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