先上一張圖看清 Westore 怎么解決小程序數(shù)據(jù)難以管理和維護(hù)的問題:
非純組件的話,可以直接省去 triggerEvent 的過程,直接修改 store.data 并且 update,形成縮減版單向數(shù)據(jù)流。
這里說的組件便是自定義組件,使用原生小程序的開發(fā)格式如下:
Component({ properties: { }, data: { }, methods: { } }) 使用 Westore 之后: import create from '../../utils/create' create({ properties: { }, data: { }, methods: { } }) |
看著差別不大,但是區(qū)別:
Component 的方式使用 setData 更新視圖 create 的方式直接更改 store.data 然后調(diào)用 update create 的方式可以使用函數(shù)屬性,Component 不可以,如: export default { data: { firstName: 'dnt', lastName: 'zhang', fullName:function(){ return this.firstName + this.lastName } } } |
綁定到視圖:
<view>{{fullName}}</view>
小程序 setData 的痛點(diǎn):
沒使用 westore 的時候經(jīng)??梢钥吹竭@樣的代碼:
使用完 westore 之后:
上面兩種方式也可以混合使用。
可以看到,westore 不僅支持直接賦值,而且 this.update 兼容了 this.setData 的語法,但性能大大優(yōu)于 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'} }) |
這里需要特別強(qiáng)調(diào),雖然 this.update 可以兼容小程序的 this.setData 的方式傳參,但是更加智能,this.update 會先 Diff 然后 setData。原理:
常見純組件由很多,如 tip、alert、dialog、pager、日歷等,與業(yè)務(wù)數(shù)據(jù)無直接耦合關(guān)系。
組件的顯示狀態(tài)由傳入的 props 決定,與外界的通訊通過內(nèi)部 triggerEvent 暴露的回調(diào)。
triggerEvent 的回調(diào)函數(shù)可以改變?nèi)譅顟B(tài),實(shí)現(xiàn)單向數(shù)據(jù)流同步所有狀態(tài)給其他兄弟、堂兄、姑姑等組件或者其他頁面。
Westore里可以使用 create({ pure: true }) 創(chuàng)建純組件(當(dāng)然也可以直接使用 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:'成功發(fā)起單向數(shù)據(jù)流' + Math.floor( Math.random()*1000)}) } } }) |
需要注意的是,加上 pure : true 之后就是純組件,組件的 data 不會被合并到全局的 store.data 上。
組件區(qū)分業(yè)務(wù)組件和純組件,他們的區(qū)別如下:
大型項(xiàng)目一定會包含純組件、業(yè)務(wù)組件。通過純組件,可以很好理解單向數(shù)據(jù)流。
小程序插件是對一組 JS 接口、自定義組件或頁面的封裝,用于嵌入到小程序中使用。插件不能獨(dú)立運(yùn)行,必須嵌入在其他小程序中才能被用戶使用;而第三方小程序在使用插件時,也無法看到插件的代碼。因此,插件適合用來封裝自己的功能或服務(wù),提供給第三方小程序進(jìn)行展示和使用。
插件開發(fā)者可以像開發(fā)小程序一樣編寫一個插件并上傳代碼,在插件發(fā)布之后,其他小程序方可調(diào)用。小程序平臺會托管插件代碼,其他小程序調(diào)用時,上傳的插件代碼會隨小程序一起下載運(yùn)行。
Westore 提供的目錄如下:
|--components |--westore |--plugin.json |--store.js 創(chuàng)建插件: import create from '../../westore/create-plugin' import store from '../../store' //最外層容器節(jié)點(diǎn)需要傳入 store,其他組件不傳 store create(store, { properties:{ authKey:{ type: String, value: '' } }, data: { list: [] }, attached: function () { // 可以得到插件上聲明傳遞過來的屬性值 console.log(this.properties.authKey) // 監(jiān)聽所有變化 this.store.onChange = (detail) => { this.triggerEvent('listChange', detail) } // 可以在這里發(fā)起網(wǎng)絡(luò)請求獲取插件的數(shù)據(jù) this.store.data.list = [{ name: '電視', price: 1000 }, { name: '電腦', price: 4000 }, { name: '手機(jī)', price: 3000 }] this.update() //同樣也直接和兼容 setData 語法 this.update( { 'list[2].price': 100000 } ) } }) |
在你的小程序中使用組件:
<list auth-key="{{authKey}}" bind:listChange="onListChange" />
這里來梳理下小程序自定義組件插件怎么和使用它的小程序通訊:
這么方便簡潔還不趕緊試試 Westore插件開發(fā)模板 !
插件內(nèi)所有組件公用的 store 和插件外小程序的 store 是相互隔離的。
由于開發(fā)插件時候的組件沒有 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) } |
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)