博客班級 | 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>收藏了回答 · 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>個人主頁 ></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 微信小程序實戰教程