WePy框架開發小程序總結
現如今mvvm框架如此火熱,其核心思想即js邏輯層不直接操作DOM,只改變組件狀態;而視圖層則通過模板template進行渲染。
1.WePy項目的目錄結構
├── dist 小程序運行代碼目錄 ├── node_modules 依賴 ├── src 代碼編寫的目錄 | ├── components WePY組件目錄 | | ├─- com_a.wpy 可復用的WePY組件a | | └── com_b.wpy 可復用的WePY組件b| ├── pages WePY頁面目錄(屬於完整頁面) | | ├── index.wpy index頁面 | | └── other.wpy other頁面 | └── app.wpy 小程序配置項(全局數據、樣式、聲明鉤子等) └── package.json 項目的package配置
二、實例
小程序定義了三大實例類,App、Page、Component; app
2.1 App
入口文件app.wpy聲明的小程序實例繼承至wepy.app類,包含小程序的生命周期函數、config配置、全局屬性方法及自定義方法。
export default class extends wepy.app { config = { pages: [ //頁面配置 ‘pages/index/index‘, ‘pages/personals/personal‘, ], window: { backgroundTextStyle: ‘light‘, navigationBarBackgroundColor: ‘#a22b00‘, navigationBarTitleText:‘‘, navigationBarTextStyle: ‘white‘ }, tabBar: { //tab欄 list: [ { pagePath: ‘pages/index/index‘, text: ‘首頁‘, iconPath: ‘./static/images/icon-index2.png‘, selectedIconPath: ‘./static/images/icon-index1.png‘ }, { pagePath: ‘pages/personals/personal‘, text: ‘我的‘, iconPath: ‘./static/images/icon-my2.png‘, selectedIconPath: ‘./static/images/icon-my1.png‘ } ], color: ‘#000‘, borderStyle: ‘white‘, selectedColor: ‘#ff5000‘, backgroundColor: ‘#ffffff‘ } }; globalData = { //全局數據 }; onLaunch() { //生命周期函數--監聽小程序初始化(全局只觸發一次) }; onShow() { //生命周期函數--監聽小程序顯示 }; customFunction() { //自定義方法 }; }
2.2 Page
page頁面繼承至wepy.page類,該類主要屬性如下:
- config 頁面配置對象,對應於原生的
page.json
文件; - components 頁面組件列表對象;
- data 頁面渲染數據對象,存放可用於頁面模板綁定的渲染數據;
- methods wxml模板中事件處理函數;
- events WePy組件之間通信的函數,響應
$broadcast
、$emit
、$invoke;
- 生命周期函數 onLoad、onShow;
- 自定義方法
2.3 component
components中的組件實例繼承wepy.component,本質上page也是component,所以component組件實例除了不需要config
配置以及頁面特有的一些生命周期函數之外,其屬性與頁面屬性大致相同。
三、組件間的通信
wepy.component
基類提供$broadcast
、$emit
、$invoke
三個方法用於組件之間的通信和交互。
this.$emit(funName,arg1,arg2);
組件間通信的事件處理函數需要寫在組件和頁面的events對象中,但是$invoke觸發的事件在methods中響應:
import wepy from ‘wepy‘ export default class Com extends wepy.component { components = {}; data = {}; methods = { //響應$invoke funNamet: (p1, p2, $event) => { //處理邏輯 } }; // events對象中所聲明的函數為用於監聽組件之間的通信與交互事件的事件處理函數 events = { //響應$emit、$broadcast funNamet: (p1, p2, $event) => { //處理邏輯 } }; // Other properties }
$broadcast
事件是由父組件發起,所有子組件都會收到此廣播事件,除非事件被手動取消,捕獲順序。
$emit
與$broadcast
正好相反,事件發起組件的所有祖先組件會依次接收到$emit
事件,冒泡順序。
$invoke
是一個頁面或組件對另一個組件中的方法的直接調用,通過傳入組件路徑找到相應的組件,然後再調用其方法。
四、數據綁定
原生小程序的數據綁定方式
原生小程序通過Page
提供的setData
方法來綁定數據,如:
this.setData({title: ‘this is title‘});
WePY數據綁定方式
Wepy使用臟數據檢查對setData進行封裝,在函數執行周期結束時進行臟數據檢查。一來不用關心頁面多次setData是否有性能上的問題;二來可以更加簡潔去修改數據實現綁定。
this.title = ‘this is title‘;
值得註意的是,在異步綁定數據時,需要執行$apply()才會觸發臟數據檢查,
setTimeout(() => { this.title = ‘this is title‘; this.$apply(); }, 3000);
WePY臟數據檢查流程
在執行臟數據檢查時,會通過this.$$phase
標識當前檢查狀態,並且會保證在並發的流程當中,只會有一個臟數據檢查流程在運行,以下是執行臟數據檢查的流程圖:
五、小程序登錄授權獲取邏輯
原生的小程序提供許多開放接口供使用者開發,快速建立小程序內的用戶體系。
下面將小程序校驗、登錄、授權、獲取用戶信息諸多接口串聯起來,以便更直觀的認識到這些接口是如何在實際應用中使用的。
5.1 檢驗、登錄
wx.checkSession({ success: function() { //session_key 未過期,並且在本生命周期一直有效 }, fail: function() { //session_key 已經失效,需要重新執行登錄流程 wx.login({ success: (res) => { if (res.code) { //發起網絡請求 wx.request({ //開發者服務器通過code換取用戶唯一標識openid 和 會話密鑰session_key。 url: ‘https://test.com/onLogin‘, data: { // 臨時登錄憑證code,並回傳到開發者服務器 code: res.code }, success: function(result) { //返回業務數據,前後端交互身份識別 } }) } else { console.log(‘登錄失敗!‘ + res.errMsg) } } }); } })
login說明:
-
小程序調用wx.login() 獲取 臨時登錄憑證code ,並回傳到開發者服務器。
-
開發者服務器以code換取 用戶唯一標識openid 和 會話密鑰session_key。
之後開發者服務器可以根據用戶標識來生成自定義登錄態,用於後續業務邏輯中前後端交互時識別用戶身份。
會話密鑰session_key有效性:
開發者如果遇到因為session_key不正確而校驗簽名失敗或解密失敗,請關註下面幾個與session_key有關的註意事項。
-
wx.login()調用時,用戶的session_key會被更新而致使舊session_key失效。開發者應該在明確需要重新登錄時才調用wx.login(),及時通過登錄憑證校驗接口更新服務器存儲的session_key。
-
微信不會把session_key的有效期告知開發者。我們會根據用戶使用小程序的行為對session_key進行續期。用戶越頻繁使用小程序,session_key有效期越長。
-
開發者在session_key失效時,可以通過重新執行登錄流程獲取有效的session_key。使用接口wx.checkSession()可以校驗session_key是否有效,從而避免小程序反復執行登錄流程。
-
當開發者在實現自定義登錄態時,可以考慮以session_key有效期作為自身登錄態有效期,也可以實現自定義的時效性策略。
5.2 授權獲取用戶信息
// 可以通過 wx.getSetting 先查詢一下用戶是否授權了 "scope.record" 這個 scope wx.getSetting({ success(res) { if (!res.authSetting[‘scope.record‘]) { wx.authorize({ scope: ‘scope.record‘, success() { // 用戶已經同意小程序使用錄音功能,後續調用 wx.startRecord 接口不會彈窗詢問 wx.startRecord() } }) } } })
註意:wx.authorize({scope: "scope.userInfo"}),無法彈出授權窗口,請使用 <button open-type="getUserInfo"></button>
如果用戶已經授權,要獲取用戶信息,調下面接口:
wx.getSetting({ success: (res)=>{ if (res.authSetting[‘scope.userInfo‘]) { // 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱 wx.getUserInfo({ withCredentials: true, success: (res) => { console.log(res); } }) } } });
註意:
- 當用戶未授權過,調用該接口將直接報錯
- 當用戶授權過,可以使用該接口獲取用戶信息
WePy框架開發小程序總結