微信小程序demo-碼乎


博客班級 https://edu.cnblogs.com/campus/zjcsxy/SE2020
作業要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334
作業目標 一個小程序,一次github,一篇博客
作業源代碼 https://github.com/Psyduck619/MyZhihu
學號 31801142
姓名 勞帥權

前言

項目描述:
本項目的靈感來源於知乎APP和朵朵校友圈微信小程序,ZUCC的同學們在朵朵上分享校園日常等,那么可不可以按照知乎的模式,設計一個 屬於ZUCC的專業知識相關的問答平台,但全校范圍過廣,於是我設計為我們基於我們計算學院的平台,也就是計算機相關專業知識的交流問答平台,這就是 碼乎。今天,你碼了嗎?
本項目只是一個簡單的微信小程序demo,使用微信小程序雲開發,數據存儲在數據庫中。
設計思路:
1.完成全局配置,如頂部欄,底部tabBar,將計划中的5個基本頁面形成大致框架,並引入所需素材。
2.首先在數據庫存入所需數據,相應頁面js文件引入data,然后逐個完成頁面的排版布局,使頁面完整。
3.完成基本交互,包括頁面間的跳轉,點擊事件等。
4.整理代碼,修改、彌補不足。
開發工具及環境:
微信開發者工具、VSCode

項目基本頁面演示

(本博文所有圖片均來自於真機調試)

全局配置

全局JOSN文件 app.jons

全局配置主要用於控制小程序頁面以外的內容,如頭部和底部導航欄的樣式結構等,也決定了整個小程序的內容頁數,我們在開始做一個小程序之前,應該先設計好大概的需要做的頁面內容,制定好框架再進行,不然在做的過程中容易混亂,想加想改可能都會遇到麻煩。
pages:共5個基本頁面,index(首頁),answer(回答頁),question(問題頁),notify(消息頁),my(個人頁)
"pages":[
    "pages/index/index",
    "pages/answer/answer",
    "pages/notify/notify",
    "pages/question/question",
    "pages/my/my",
    "pages/logs/logs"
  ]

window:定義小程序所有頁面的頂部背景顏色,文字顏色定義等

"window":{
    "backgroundTextStyle":"dark",
    "navigationBarBackgroundColor": "#0068C4",
    "navigationBarTitleText": "碼乎",
    "navigationBarTextStyle":"white",
    "enablePullDownRefresh": true
  }

tabBar:底部導航欄組件,控制小程序底部導航欄的所有樣式

"tabBar": {
    "color": "#aaa",
    "selectedColor": "#0068C4",
    "backgroundColor": "#ffffff",
    "position": "bottom",
    "borderStyle": "white",
    "list": [
      {
        "text": "首頁",
        "pagePath": "pages/index/index",
        "iconPath": "images/tabBar/index.png",
        "selectedIconPath": "images/tabBar/index_focus.png"
      },
      {
        "text": "消息",
        "pagePath": "pages/notify/notify",
        "iconPath": "images/tabBar/ring.png",
        "selectedIconPath": "images/tabBar/ring_focus.png"
      },
      {
        "text": "我的",
        "pagePath": "pages/my/my",
        "iconPath": "images/tabBar/my.png",
        "selectedIconPath": "images/tabBar/my_focus.png"
      }
    ]
  }

全局js文件 app.js

下面的js代碼為微信開發者工具原生自帶,主要用於授權后獲得微信用戶信息,這點直接決定了后台數據的調用,數據庫的一般分配給每個用戶一個單獨的id來調取數據,所以這個功能非常重要。在本小程序中,該功能從微信端簡單調用登錄用戶的頭像和名字等信息。
  wx.login({
    success: res => {
      // 發送 res.code 到后台換取 openId, sessionKey, unionId
    }
  })
  // 獲取用戶信息
  wx.getSetting({
    success: res => {
      if (res.authSetting['scope.userInfo']) {
        // 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱,不會彈框
        wx.getUserInfo({
          success: res => {
            // 可以將 res 發送給后台解碼出 unionId
            this.globalData.userInfo = res.userInfo

            // 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
            // 所以此處加入 callback 以防止這種情況
            if (this.userInfoReadyCallback) {
              this.userInfoReadyCallback(res)
            }
          }
        })
      }
    }
  })

各頁面基本介紹

首頁


基本局部 index.wxml
  <!-- 頭部搜索框 -->
  <view class="search flex-wrp">
    <view class="search-left flex-item">
      <image src="../../images/search.png"></image>
      <input placeholder="搜索ZUCC碼乎內容" placeholder-class="search-placeholder" />
    </view>
    <view class="search-right flex-item">
      <image src="../../images/lighting.png"></image>
    </view>
  </view>
  <!-- 用於解決頭部被遮擋問題 -->
  <view class="vis-wrap">
    <view class="vis"></view>
  </view>
  <!-- 首頁列表 -->
  <view class="show-list" wx:for="{{feed}}" wx:key="index">
      <!-- block01 -->
      <view class="list-head" bindtap="toQuestion">
        <text class="question">{{item.question}}</text>
      </view>
      <!-- block02 -->
      <view class="user-left">
        <image src="{{item.feed_source_img}}"></image>
        <text class="name">{{item.feed_source_name}}</text>
      </view>
      <!-- block03 -->
      <view class="answer" bindtap="toAnswer">
        <text>{{item.answer_ctnt}}</text>
      </view>
      <!-- block04 -->
      <view class="list-bottom">
        <text>{{item.good_num + "贊同 • " + item.comment_num + "評論"}}</text>
        <image src="../../images/more.png"></image>
      </view>
  </view>
</view>

index.js 存放本地數據和跳轉功能。wx.navigateTo是非常重要的一個方法,用於頁面間的跳轉,在頁面內多設置跳轉,可以提高小程序的交互性。

  // 跳轉至回答頁面
  toAnswer: function () {
    wx.navigateTo({
      url: "../answer/answer"
    });
  },
  //跳轉至問題頁面
  toQuestion: function () {
    wx.navigateTo({
      url: "../question/question"
    });
  }

回答頁

本頁除了基本的樣式排版外,實現了關注與取消關注,贊同與取消贊同,收藏與取消收藏功能,下面為演示gif(25s)

以關注和取消關注為例,只需要在data數據中設置一個用於判斷當前關注狀態的值isFocus,再給收藏標簽設置一個bindtap,使之獲得一個點擊響應方法,該方法通過對當前的isFocus進行判斷,從而改變關注標簽的樣式等。將isFocus保存在數據庫,每次加載時即可調取上次保存的關注狀態。
下面的收藏功能的部分js代碼
focus: function (options) {
    console.log(options)
    let that = this;
    let isFocus = this.data.feed[0].isFocus;
    if (!isFocus) { //關注
      DB.doc("d6b130aa5fa2c865000c045b41a8468c").update({
        data: {
          isFocus: true,
          focus_text: "已關注",
        },
        success(res) {
          console.log("更新成功", res)
        },
        fail(res) {
          console.log("更新失敗", res)
        }
      })
      wx.showToast({
        title: '關注成功',
        icon: 'none'
      })
    }
    else{ //取消關注
      DB.doc("d6b130aa5fa2c865000c045b41a8468c").update({
        data: {
          isFocus: false,
          focus_text: "關注"
        },
        success(res) {
          console.log("更新成功", res)
        },
        fail(res) {
          console.log("更新失敗", res)
        }
      })
      wx.showToast({
        title: '已取消關注',
        icon: 'none'
      })
    }

問題頁

一個朴實無華的問題頁。這一頁我完全模仿知乎APP的布局排版來設置,非常有意思,最終做出的效果還不錯。做這種頁面布局很有意義,從最外層一層一層往里挖掘,既需要細心,更需要大局觀。

消息頁

本頁采用頂部欄切換形式,分為動態和消息兩欄。實現方法為在js中設置一個判斷值currentNavTab,通過點擊事件SwitchTab得到當前用戶選擇的頁面,然后修改判斷值,通過判斷值將另外的頁面設置為hidden即可,同時,為了改變頂部欄的樣式,也需要通過判斷值修改頂部欄的class。
這個在同一頁面內的擴展方式也非常常用,很好地將兩個息息相關的頁面放在同一個大頁中,讓用戶獲得良好的體驗。

基本布局:
<!-- 頂部導航條 -->
<view class="top-tab">
  <view class="toptab {{currentNavtab==idx ? 'active' : ''}}" wx:for="{{navTab}}" 
    wx:for-index="idx" wx:for-item="itemName" data-idx="{{idx}}" bindtap="switchTab">
    {{itemName}}
  </view>
</view>
<view class="container">
  <!-- 動態欄 -->
  <view class="cnt0" hidden="{{currentNavtab==0 ? '' : true}}" wx:for="{{feed}}"
    wx:key="{{index}}">
    <view class="head">
      <view class="img">
        <image src="{{item.feed_source_img}}"></image>
      </view>
      <view class="text">
        <text class="name">{{item.feed_source_name}}</text>
        <text class="time" decode>收藏了回答&nbsp;·&nbsp;10/15</text>
      </view>
    </view>
    <view class="content">
      <view class="text">
        <view class="title">
          <text>{{item.question}}</text>
        </view>
        <view class="info">
          <text decode>{{item.feed_source_name + "的文章 · " + item.good_num 
              + " 贊同 · " + item.comment_num + " 評論"}}</text>
        </view>
      </view>
      <view class="img">
        <image src="{{item.feed_source_img2}}"></image>
      </view>
    </view>
  </view>
  <!-- 消息欄 -->
  <view class="cnt1" hidden="{{currentNavtab==1 ? '' : true}}">
    <view class="allread">
      <view class="list">
        <text>消息列表</text>
      </view>
      <view class="txt">
        <text>全部已讀</text>
      </view>
    </view>
    <view class="notifylist" wx:for="{{notifyList}}" wx:key="{{index}}">
      <view class="img">
        <image src="{{item.img}}"></image>
      </view>
      <view class="info">
        <view class="name">
          <text>{{item.name}}</text>
        </view>
        <view class="text">
          <text>{{item.text}}</text>
        </view>
      </view>
      <view class="time">
        <view>
          <text>{{item.time}}</text>
        </view>
      </view>
    </view>
  </view>
</view>

js方法:

  switchTab: function(e){
    this.setData({ //修改判斷值,從而改變樣式
      currentNavtab: e.currentTarget.dataset.idx
    });
  }

我的頁

本頁便采用了微信小程序自帶的微信授權功能,實現用戶信息的交互功能,可在頁面中直接展示用戶的微信頭像及用戶昵稱,js代碼已在前面展示

my.wxml
<view class="container">
  <view class="userinfo">
    <button class="btn" wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" 
      bindgetuserinfo="getUserInfo"> 微信授權登錄 </button>
    <view wx:else class="content">
      <view class="img">
        <image bindtap="bindViewTap" class="userinfo-avatar" 
          src="{{userInfo.avatarUrl}}" mode="cover"></image>
      </view>
      <view class="text">
        <text class="userinfo-nickname">{{userInfo.nickName}}</text>
        <text class="setting" decode>個人主頁&nbsp;></text>
      </view>
    </view>
  </view>
  <view class="mylist" wx:for="{{myList}}" wx:key="{{index}}">
    <view class="idx">
      <view class="img">
        <image src="{{item.img}}"></image>
      </view>
      <view class="text">
        <text>{{item.text}}</text>
      </view>
    </view>
  </view>
</view>

問題與發現

1.最大的問題是功能還不完善,本demo只能做展示使用,而沒有用戶進行提問和回答等功能,有待開發.
2.我在首頁做一個頂部固定的(用position:fix實現)的搜索框,然后我還想獲得下拉刷新,那么搜索框下面的內容就會被覆蓋起來,如果給下面的內容加一個margin-top,那么下拉刷新的白條就會變長,很難看,體驗不佳,查了很多資料也沒有得到解決方法,只好取消下拉刷新,而頂部固定的內容也有類似情況。
3.做項目時CSS代碼非常重要,首先在布局上,總體一般使用flex布局會比較方便,很多時候調整位置會用到相對定位。由於flex布局的通用性和復用性,最好可以將css代碼統一寫到app.wxss中,那么就可以進行復用,不用再多次地敲重復的代碼,很多其他的css樣式也是同樣的道理。我做這樣一個簡單的小程序就覺得重復率很高,更何況接下來體量大得多的大作業?很重要的一點,就是提前准備好全局的css代碼,在項目前期完善這方面的功能和內容,將會為后面節省下大量的時間和精力,整個項目和代碼的結構框架也更清晰,何樂而不為呢?
4.與第二點類似的,微信小程序為我們提供了一個很方便的component,可以用來自定義一些復用組件,也是很好地提高我們寫小程序的效率,如果我們能充分利用,會非常有益。
5.軟件工程項目需要面向客戶,所以交互是非常重要的,而決定交互的一是界面的樣式,這是由html和css決定的,而更重要的是小程序對用戶操作的反應,這就是由js決定的了,可以說用好js才能做出出色的,功能可靠完全的小程序,因此對於js的學習應該加緊,特別是es6語法,能很大地提高寫代碼的水准。

總結

這是我第一個獨立完成的微信小程序,雖然有很多不完善的地方,也有很多代碼混亂、不知所措的地方,但通過這幾天的摸索和努力,也找到了一點開發微信小程序的思路。接下去,我會學習更多軟件工程方法和微信小程序的知識,來完善自己的不足,擴充小程序的內容和功能。軟件工程是一門非常考驗實踐的課程,多學、多想、多寫才能讓人更上一層樓。

參考資料

https://github.com/RebeccaHanjw/weapp-wechat-zhihu 知乎小程序demo

https://juejin.im/post/6844903873497268231 微信小程序實戰教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM