在搭建带 TS 的微信小程序模板时,使用 mobx-miniprogram 会遇到一些奇奇怪怪的问题(应该是微信官方懒得解决 BUG)
定义 observable
和 vuex 类似,mobx 也有 action 用于修改状态的方法,但是 mobx-miniprogram 基于 mobx4 修改而来,多少带点类型推导的 bug,正确的 action 定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import { observable, runInAction, action } from 'mobx-miniprogram' import { delay } from '../utils/index'
export const store = observable({ numA: 1, numB: 2,
get sum() { return this.numA + this.numB },
update: async function () { await delay(1000) runInAction(() => { const sum = this.sum this.numA = this.numB this.numB = sum }) },
update1: action(() => { const sum = store.sum store.numA = store.numB store.numB = sum }),
update2: action(async () => { await delay(1000) const sum = store.sum store.numA = store.numB store.numB = sum }), })
|
binding
定义完 store 之后就需要绑定到组件或者页面,这里不能使用手动绑定,不然就会报错:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { createStoreBindings } from 'mobx-miniprogram-bindings'
Page({ onLoad() { this.storeBindings = createStoreBindings(this, { }) }, onUnload() { this.storeBindings.destroyStoreBindings() }, })
|
正确的绑定方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { ComponentWithStore } from 'mobx-miniprogram-bindings' import { store } from '../../models' ComponentWithStore({ storeBindings: { namespace: 'user_store', store: user, fields: { numA: 'numA', numB: (store: typeof user) => { return store.numB }, sum: 'sum', }, actions: { buttonTap: 'update_user', }, }, })
|
或者使用 behavior 的方式绑定:
behavior.ts1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { BehaviorWithStore } from 'mobx-miniprogram-bindings' import { store1, store2 } from '../../models/index'
export const mobxBehavior = BehaviorWithStore({ storeBindings: [ { namespace: 'store2', store: store2, fields: ['numA', 'numB', 'sum'], actions: ['update'], }, { store: store1, fields: ['numA', 'numB', 'sum'], actions: ['update_user'], }, ], })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { mobxBehavior } from './behavior' import { behavior as computedBehavior } from 'miniprogram-computed' import { testApi } from '../../api/index' import { store } from '../../models/index' Page({ behaviors: [mobxBehavior, computedBehavior], computed: { allSum(data: { numA: number numB: number global: { numA: number; numB: number } }) { return data.numA + data.numB + data.global.numA + data.global.numB }, }, readStore() { console.log(store) }, })
|
Action
如果需要响应式修改 store 的值,可以使用 runInAction:
1 2 3 4 5 6 7 8 9 10
| import { runInAction } from 'mobx-miniprogram' import { store } from '../../models/index' Page({ setStore(arg) { runInAction(() => { store.xxx = arg }) }, })
|
注意:如果 store 里有对象数组,则需要特殊操作
1 2 3 4 5 6 7 8 9 10 11 12
| setStore(arg) { runInAction(() => { store.myList = store.myList.map((item)=>{ })
store.myList[xx].xx = arg store.myList = store.myList }) }
|