Unsplash本次的系列博文的知識(shí)點(diǎn)講解和代碼,主要是來自于七月老師的書籍《微信小程序開發(fā):入門與實(shí)踐》,由個(gè)人總結(jié)并編寫,關(guān)于更多微信小程序開發(fā)中的各項(xiàng)技能,以及常見問題的解決方案,還請(qǐng)大家購(gòu)買書籍進(jìn)行學(xué) ...
![]()
Unsplash
本次的系列博文的知識(shí)點(diǎn)講解和代碼,主要是來自于 七月老師 的書籍《微信小程序開發(fā):入門與實(shí)踐》,由個(gè)人總結(jié)并編寫,關(guān)于更多微信小程序開發(fā)中的各項(xiàng)技能,以及常見問題的解決方案,還請(qǐng)大家購(gòu)買書籍進(jìn)行學(xué)習(xí)實(shí)踐,該系列博文的發(fā)布已得到七月老師的授權(quán)許可
授權(quán)許可
我們?cè)?nbsp;WeChat 文章列表頁(yè)面(一) 中,已經(jīng)完成了文章列表頁(yè)面了,效果圖如下所示 ![]()
文章列表頁(yè)面
post.js 文件默認(rèn)包含的代碼如下所示 Page({ /** * 頁(yè)面的初始數(shù)據(jù) */ data: { }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面加載 */ onLoad: function (options) { }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面初次渲染完成 */ onReady: function () { }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面顯示 */ onShow: function () { }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面隱藏 */ onHide: function () { }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面卸載 */ onUnload: function () { }, /** * 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作 */ onPullDownRefresh: function () { }, /** * 頁(yè)面上拉觸底事件的處理函數(shù) */ onReachBottom: function () { }, /** * 用戶點(diǎn)擊右上角分享 */ onShareAppMessage: function () { } }) 可以看到,整個(gè)頁(yè)面執(zhí)行了一個(gè) Page({...}) 方法,參數(shù)是一個(gè) Object 對(duì)象,用來指定頁(yè)面的初始數(shù)據(jù) (data)、生命周期函數(shù) (on 開頭的函數(shù))、事件處理函數(shù)等 一個(gè)頁(yè)面從創(chuàng)建到卸載,會(huì)經(jīng)歷以下 5 個(gè)周期:加載、顯示、渲染、隱藏、卸載,MINA 框架分別提供了 5 個(gè)生命周期函數(shù)來監(jiān)聽這 5 個(gè)特定的生命周期,以方便開發(fā)者可以在這些特定的時(shí)刻執(zhí)行一些自己的代碼邏輯,它們分別是:
除了以上 5 個(gè)生命周期函數(shù)之外,還包括以下 3 個(gè)小程序特定事件的處理函數(shù):
我們接下來通過控制臺(tái)打印的方式,來看下生命周期函數(shù)及事件處理函數(shù)的觸發(fā)時(shí)機(jī),也可以通過打斷點(diǎn)的方式,進(jìn)行調(diào)試,具體代碼如下所示: Page({ data: { }, onLoad: function (options) { console.log("onLoad:頁(yè)面被加載"); }, onReady: function () { console.log("onReady:頁(yè)面被渲染"); }, onShow: function () { console.log("onShow:頁(yè)面被顯示"); }, onHide: function () { console.log("onHide:頁(yè)面被隱藏"); }, onUnload: function () { console.log("onUnload:頁(yè)面被卸載"); }, onPullDownRefresh: function () { console.log("onPullDownRefres:監(jiān)聽用戶下拉動(dòng)作"); }, onReachBottom: function () { console.log("onReachBottom:頁(yè)面上拉觸底事件"); }, onShareAppMessage: function () { console.log("onShareAppMessage:用戶點(diǎn)擊右上角分享"); } }) ![]()
運(yùn)行結(jié)果
可以看到,一個(gè)頁(yè)面要正常顯示,必須經(jīng)過以上 3 個(gè)生命周期:加載、顯示、渲染,至于 onHide 和 onUnload 函數(shù),以及 3 個(gè)特定事件的處理函數(shù),它們的觸發(fā)都需要執(zhí)行一些 API 操作,這些我們到之后的部分再做介紹 官方文檔中,也是給出 Page 實(shí)例生命周期的圖解,同時(shí)也告訴我們,以下內(nèi)容你不需要立馬完全弄明白,不過以后它會(huì)有幫助,所以在這里建議大家的是,在遇到問題或者業(yè)務(wù)需要時(shí),再回過頭來研究這張完整的生命周期圖更有意義 ![]()
頁(yè)面生命周期
在真實(shí)項(xiàng)目中,業(yè)務(wù)數(shù)據(jù)通常都放置在自己的服務(wù)器中,然后通過 HTTP 請(qǐng)求來訪問服務(wù)器提供的 RESTFUI API,從而實(shí)現(xiàn)數(shù)據(jù)的獲取 接下來,我們嘗試將編碼在 post.wxml 文件里的數(shù)據(jù)移植到 post.js 中,在 post.js 中加入一個(gè)臨時(shí)變量 postData 來模擬文章數(shù)據(jù),并將上一小節(jié)中測(cè)試生命周期的代碼移除,編寫完成后的代碼如下: Page({ data: { date: "Jan 28 2017", title: "小時(shí)候的冰棍兒與雪糕", postImg: "/images/post/post-4.jpg", avatar: "/images/avatar/avatar-5.png", content: "冰棍與雪糕絕對(duì)不是同一個(gè)東西。3到5毛錢的雪糕猶如現(xiàn)在的哈根達(dá)斯,而5分1毛的冰棍兒就像現(xiàn)在的老冰棒。時(shí)過境遷,...", readingNum: 92, collectionNum: 108, commentNum: 7 }, }) 如果是傳統(tǒng)的網(wǎng)頁(yè)開發(fā),我們會(huì)想到,先獲取 HTML 文檔的 DOM,然后對(duì) DOM 標(biāo)簽進(jìn)行復(fù)制,從而實(shí)現(xiàn)數(shù)據(jù)的顯示,但在小程序中,是沒有 DOM 結(jié)構(gòu)的,無法通過這樣的方式,將數(shù)據(jù)“填充”到頁(yè)面當(dāng)中 在現(xiàn)在流行的 MVC 或者 MVVM 框架中,如 AngularJS、Vue.js 中,都有數(shù)據(jù)綁定的概念,小程序也是借鑒了這些流行框架的思想,采用數(shù)據(jù)綁定的機(jī)制來做數(shù)據(jù)的初始化和更新 不同于 AngularJS 的雙向數(shù)據(jù)綁定,小程序僅實(shí)現(xiàn)了單向數(shù)據(jù)綁定,即只支持從邏輯層傳遞到渲染層的數(shù)據(jù)綁定,反之則不可以 小程序使用 Page 方法參數(shù)里的 data 變量作為數(shù)據(jù)綁定的橋梁,data 里已經(jīng)被我們放置了一些數(shù)據(jù),這些直接寫在 data 里的數(shù)據(jù),被稱為數(shù)據(jù)綁定的初始化數(shù)據(jù) 需要注意的是,數(shù)據(jù)綁定有以下兩種:
接下來,我們對(duì) post.wxml 文件做一些改動(dòng),使用 Mustache 語(yǔ)法的雙大括號(hào) {{}} 在 wxml 組件里進(jìn)行數(shù)據(jù)的綁定,凡是對(duì)標(biāo)簽屬性做綁定的,一定要記得加上雙引號(hào),代碼如下: <view class="post-container"> <view class="post-author-date"> <image src="{{avatar}}" /> <text>{{date}}text> view> <text class="post-title">{{title}}text> <image class="post-image" src="{{postImg}}" mode="aspectFill" /> <text class="post-content">{{content}}text> <view class="post-like"> <image src="/images/icon/wx_app_collect.png" /> <text>{{collectionNum}}text> <image src="/images/icon/wx_app_view.png" /> <text>{{readingNum}}text> <image src="/images/icon/wx_app_message.png" /> <text>{{commentNum}}text> view> view> ![]()
運(yùn)行結(jié)果
我們通過頁(yè)面生命周期圖解,來解釋一下初始化數(shù)據(jù)綁定的過程,當(dāng)頁(yè)面執(zhí)行了 onShow 函數(shù)后,邏輯層會(huì)收到一個(gè)通知 (Notify);隨后邏輯層會(huì)將 data 對(duì)象以 json 的形式發(fā)送到 View 視圖層 (Send Initial Data),視圖層接受初始化數(shù)據(jù)后,開始渲染并顯示初始化數(shù)據(jù) (First Render),最終將數(shù)據(jù)呈現(xiàn)在開發(fā)者的面前 我們打開“編輯”選項(xiàng)卡,點(diǎn)擊 AppData 就能夠看到數(shù)據(jù)綁定變量,如下圖所示 ![]()
post 頁(yè)面在 AppData 面板中的數(shù)據(jù)綁定情況
點(diǎn)擊 Tree 選項(xiàng),切換成 Code,數(shù)據(jù)將以 json 的形式呈現(xiàn),如下圖所示 ![]()
以 json 的格式呈現(xiàn)數(shù)據(jù)
如果 data 對(duì)象的屬性較為復(fù)雜,包括對(duì)象和數(shù)組,那需要相應(yīng)的調(diào)整 wxml 文件,可以看下面兩張圖進(jìn)行理解 ![]()
較為復(fù)雜的 data 對(duì)象
![]()
根據(jù) data 對(duì)象結(jié)構(gòu)調(diào)整的 wxml
通過 setData 函數(shù)來進(jìn)行數(shù)據(jù)綁定,這種方式可以理解為“數(shù)據(jù)更新”,setData 方法位于 Page 對(duì)象的原型鏈上:Page.prototype.setData,在大多數(shù)的情況下,我們使用 this.setData 的方式來調(diào)用這個(gè)方法 setData 的參數(shù)接受一個(gè)對(duì)象,以 key 和 value 的形式將 this.data 中的 key 對(duì)應(yīng)的值設(shè)置成 value,這句話需要注意兩點(diǎn):① setData 會(huì)改變 this.data 變量里相同 key 的值;② setData 執(zhí)行后會(huì)通知邏輯層執(zhí)行 Rerender,并立刻重新渲染視圖 Page({ data: { object: { date: "Jan 28 2017" }, title: "小時(shí)候的冰棍兒與雪糕", postImg: "/images/post/post-4.jpg", avatar: "/images/avatar/avatar-5.png", content: "冰棍與雪糕絕對(duì)不是同一個(gè)東西。3到5毛錢的雪糕猶如現(xiàn)在的哈根達(dá)斯,而5分1毛的冰棍兒就像現(xiàn)在的老冰棒。時(shí)過境遷,...", readingNum: 92, collectionNum: { array: [108] }, commentNum: 7 }, onLoad:function(){ this.setData({ title: "一根雪糕的經(jīng)濟(jì)學(xué)原理" }) } }) ![]()
運(yùn)行結(jié)果
可以看到,第一篇文章的標(biāo)題由 data 里所設(shè)置的 title:"小時(shí)候的冰棍兒與雪糕",被更改成了“一根雪糕的經(jīng)濟(jì)學(xué)原理”,key 可以使用字符串來表示,可以看下面 3 個(gè)例子 |