先上一張圖看清 Westore 怎麼解決小程序數據難以管理和維護的問題:html
非純組件的話,能夠直接省去 triggerEvent 的過程,直接修改 store.data 而且 update,造成縮減版單向數據流。git
Github: https://github.com/dntzhang/westoregithub
這裏說的組件即是自定義組件,使用原生小程序的開發格式以下:編程
Component({ properties: { }, data: { }, methods: { } })
使用 Westore 以後:json
import create from '../../utils/create' create({ properties: { }, data: { }, methods: { } })
看着差異不大,可是區別:小程序
export default { data: { firstName: 'dnt', lastName: 'zhang', fullName:function(){ return this.firstName + this.lastName } } }
綁定到視圖:網絡
<view>{{fullName}}</view>
小程序 setData 的痛點:dom
沒使用 westore 的時候常常能夠看到這樣的代碼:ide
使用完 westore 以後:函數
上面兩種方式也能夠混合使用。
能夠看到,westore 不只支持直接賦值,並且 this.update 兼容了 this.setData 的語法,但性能大大優於 this.setData,再舉個例子:
this.store.data.motto = 'Hello Westore' this.store.data.b.arr.push({ name: 'ccc' }) this.update()
等同於
this.update({ motto:'Hello Westore', [`b.arr[${this.store.data.b.arr.length}]`]:{name:'ccc'} })
這裏須要特別強調,雖然 this.update 能夠兼容小程序的 this.setData 的方式傳參,可是更加智能,this.update 會先 Diff 而後 setData。原理:
常見純組件由不少,如 tip、alert、dialog、pager、日曆等,與業務數據無直接耦合關係。
組件的顯示狀態由傳入的 props 決定,與外界的通信經過內部 triggerEvent 暴露的回調。
triggerEvent 的回調函數能夠改變全局狀態,實現單向數據流同步全部狀態給其餘兄弟、堂兄、姑姑等組件或者其餘頁面。
Westore裏可使用 create({ pure: true })
建立純組件(固然也能夠直接使用 Component),好比 :
import create from '../../utils/create' create({ pure : true, properties: { text: { type: String, value: '', observer(newValue, oldValue) { } } }, data: { privateData: 'privateData' }, ready: function () { console.log(this.properties.text) }, methods: { onTap: function(){ this.store.data.privateData = '成功修改 privateData' this.update() this.triggerEvent('random', {rd:'成功發起單向數據流' + Math.floor( Math.random()*1000)}) } } })
須要注意的是,加上 pure : true
以後就是純組件,組件的 data 不會被合併到全局的 store.data 上。
組件區分業務組件和純組件,他們的區別以下:
大型項目必定會包含純組件、業務組件。經過純組件,能夠很好理解單向數據流。
小程序插件是對一組 JS 接口、自定義組件或頁面的封裝,用於嵌入到小程序中使用。插件不能獨立運行,必須嵌入在其餘小程序中才能被用戶使用;而第三方小程序在使用插件時,也沒法看到插件的代碼。所以,插件適合用來封裝本身的功能或服務,提供給第三方小程序進行展現和使用。
插件開發者能夠像開發小程序同樣編寫一個插件並上傳代碼,在插件發佈以後,其餘小程序方可調用。小程序平臺會託管插件代碼,其餘小程序調用時,上傳的插件代碼會隨小程序一塊兒下載運行。
Westore 提供的目錄以下:
|--components |--westore |--plugin.json |--store.js
建立插件:
import create from '../../westore/create-plugin' import store from '../../store' //最外層容器節點須要傳入 store,其餘組件不傳 store create(store, { properties:{ authKey:{ type: String, value: '' } }, data: { list: [] }, attached: function () { // 能夠獲得插件上聲明傳遞過來的屬性值 console.log(this.properties.authKey) // 監聽全部變化 this.store.onChange = (detail) => { this.triggerEvent('listChange', detail) } // 能夠在這裏發起網絡請求獲取插件的數據 this.store.data.list = [{ name: '電視', price: 1000 }, { name: '電腦', price: 4000 }, { name: '手機', price: 3000 }] this.update() //一樣也直接和兼容 setData 語法 this.update( { 'list[2].price': 100000 } ) } })
在你的小程序中使用組件:
<list auth-key="{{authKey}}" bind:listChange="onListChange" />
這裏來梳理下小程序自定義組件插件怎麼和使用它的小程序通信:
這麼方便簡潔還不趕忙試試 Westore插件開發模板 !
插件內全部組件公用的 store 和插件外小程序的 store 是相互隔離的。
名稱 | 描述 |
---|---|
onLoad | 監聽頁面加載 |
onShow | 監聽頁面顯示 |
onReady | 監聽頁面初次渲染完成 |
onHide | 監聽頁面隱藏 |
onUnload | 監聽頁面卸載 |
名稱 | 描述 |
---|---|
created | 在組件實例進入頁面節點樹時執行,注意此時不能調用 setData |
attached | 在組件實例進入頁面節點樹時執行 |
ready | 在組件佈局完成後執行,此時能夠獲取節點信息(使用 SelectorQuery ) |
moved | 在組件實例被移動到節點樹另外一個位置時執行 |
detached | 在組件實例被從頁面節點樹移除時執行 |
因爲開發插件時候的組件沒有 this.page,因此 store 是從根組件注入,並且能夠在 attached 提早注入:
export default function create(store, option) { let opt = store if (option) { opt = option originData = JSON.parse(JSON.stringify(store.data)) globalStore = store globalStore.instances = [] create.store = globalStore } const attached = opt.attached opt.attached = function () { this.store = globalStore this.store.data = Object.assign(globalStore.data, opt.data) this.setData.call(this, this.store.data) globalStore.instances.push(this) rewriteUpdate(this) attached && attached.call(this) } Component(opt) }
https://github.com/dntzhang/westore
MIT @dntzhang