微信小程序的開發體驗相似vue和react,可是卻沒有提供全局狀態管理的機制,因此狀態的共享只能經過屬性傳遞的方式來實現。這種作法在小規模的應用中尚能夠知足開發效率,可是在複雜的應用中組件的嵌套層次很深,屬性傳遞的路徑過長。html
因而我就想利用小程序Page中的data對象來構建一個全局store,這個store知足一下幾點需求:vue
先附上源碼 github地址react
咱們先跳過原理來看使用方法。git
將Store.js放入微信小程序項目的文件夾中,例如/lib/Store.js。github
這裏咱們經過wxappStore.createPage
來建立。對比一下Store.js和原來的建立方法的區別小程序
// 原來的建立方法 Page({ data: { message: '' }, onLoad: function () { this.setData({ message: 'hello world' }) } })
// 增長全局狀態管理以後 import wxappStore from "../../lib/Store.js"; Page(wxappStore.createPage({ // 第一個參數和原來傳入Page方法的option沒有區別。其中的data會做爲全局共享對象來使用。 data: { message: '' }, onLoad: function () { // 經過dispatch方法,進行一個異步操做。 this.store.dispatch({ name: 'testAction', payload: 'hello world' }); // 經過commit方法,修改全局狀態。 this.store.commit({ name: 'testMutation', payload: 'hello world' }); } }, // 第二個參數是一個對象,其中包含mutations和actions { mutations: { testMutation: function({ setData, payload, data }) { setData({ message: payload }); } }, actions: { testAction: function ({ commit, payload, data }) { setTimeout(() => { commit({ name: 'testMutation', payload: payload }); }); } } }))
wxappStore.createPage
方法有兩個參數。微信小程序
第一個參數和原來傳入Page方法的option沒有區別。其中的data會做爲全局共享對象來使用。微信
第二個參數是一個對象,其中包含mutations
和actions
app
mutation和Vuex中的mutation相似,它經過同步的方式修改狀態。能夠經過commit調用。框架
mutations在wxappStore.createPage
的第二個參數中定義,它用於修改全局狀態。mutation一般同步的。mutation方法的參數是一個對象,包含三個屬性:
function
: 用來修改全局狀態,在微信小程序中直接修改狀態不會觸發頁面重匯。object
:修改的狀態,能夠是一個對象,也能夠是String等基礎數據類型object
:當前狀態mutations: { testMutation: function({ setData, payload, data }) { setData({ message: payload }); } },
經過commit方法調用mutation,它的參數是一個對象,包含兩個屬性:
String
:mutation的名稱Object
:須要修改的狀態,和Vuex的payload相似。this.store.commit({ name: 'testMutation', payload: 'hello world' });
action和Vuex中action概念相似,一般包含異步操做,在異步操做完成後進行commit操做。
action方法的參數是一個參數,包含3個屬性:
function
:執行commit操做Object
:數據對象,和Vuex類型Object
:當前狀態actions: { testAction: function ({ commit, payload, data }) { setTimeout(() => { commit({ name: 'testMutation', payload: payload }); }); } }
經過dispatch方法調用action,它的參數是一個對象,包含兩個屬性:
String
:action的名稱Object
:須要修改的狀態,和Vuex的payload相似。this.store.dispatch({ name: 'testAction', payload: 'hello world' });
在Component中咱們須要完成兩項工做
第一將全局狀態綁定到當前組件的data屬性上,並將組件的data屬性綁定到頁面元素上。
第二組件須要使用commit或者dispatch完成全局狀態的修改。
這裏Store.j經過wxappStore.createComp
來建立Component,它會經過代理的方式爲Component實現全局狀態管理的功能。
import wxappStore from "../lib/Store.js"; Component(wxappStore.createComp({ data: { localtimeData: '' }, ready: function () { // 綁定全局狀態 this.getGlobalData({ globalDataKey: 'localtime', localDataKey: 'localtimeData' }); // 改變全局狀態 this.store.commit({ name: 'testMutation', payload: (new Date()).toLocaleTimeString() }) } }))
<view>讀取全局狀態:{{localtimeData}}</view>
全局狀態綁定經過getGlobalData
這個實例方法實現,這個方法並不在小程序的運行環境中,它是Store.js執行的過程當中插入到Component實例中的。
getGlobalData
不能再created
回調中調用,應爲component的實例方法setData
不能再created
中調用。
getGlobalData
的參數是一個對象,包含兩個屬性:
String
:這個屬性表示須要全局狀態的屬性名,這個全局狀態將於component的本地狀態綁定。String
:這個屬性表示本地狀態的屬性名,這個本地狀態將於全局狀態綁定。// 綁定全局狀態 this.getGlobalData({ globalDataKey: 'localtime', localDataKey: 'localtimeData' });
可使用store.commit
或者store.dispatch
,store
並非小程序的運行環境中內置的,一樣是經過Store.js插入到每個component實例中。它的使用方法和Page中的相似。
store.commit
或者store.dispatch
觸發發全局狀態的改變。