原生微信小程序的状态管理机
- 再独立出一个设置初值的方法,增加校验模式,防止没有被申明的状态被组件或页面注册,达到统一管理维护的效果
- 增加非响应的全局状态与全局方法(用于统一管理数据,脱离globalData和getApp实例)
- 应用至线上十万级流量小程序,使其经过生产环境打磨变得完善
-
如果是简单的父子组件关系,不建议将数据放到数据流中,因为
props
传值的方式比setData
性能要高。(本项目的内部实现你原理都是使用setData
完成的) -
setData
的数据是有长度限制的,微信官方限制了1MB
左右
mp-store
默认导出的是一个Store
实例,因为具有命名空间
的机制,所以可以只用一个实例管理全局的数据。
// view
<view>
<view>{{bar}}</view>
<view>{{ns_foo}}</view>
<button bindtap="eve">click here</button>
</view>
// app-service
import store from 'mp-store.js'
Page({
onLoad(opts) {
store.register('bar', this);
// 可以带有命名空间
store.register({
key: 'foo',
instance: this,
beforeUpdate(prev, next) {
console.log(prev, next);
},
nameSpace: 'ns',
});
},
eve() {
// 可以使用赋值表达式赋值
store['bar'] = 'bar here';
store['ns_foo'] = 'data2';
setTimeout(() => {
// 也可以用set方法赋值
store.set('ns_foo', 'data2');
}, 1000);
store.set('bar', 'bar value');
console.log(store.get('ns_foo'));
}
});
组件中使用方式相同
在项目的/cover
目录下有一个Page.js
和一个Component.js
使用他们代替Page和Component来申明页面和组件,可以优化对数据的访问体验。
import CoverPage from './cover/Page';
import store from './store';
CoverPage({
store: ['foo', 'bar'],
onLoad() {
console.log(this.store.foo);
},
}, store);
CoverPage({
store: {
ns: ['bar', {
key: 'foo',
beforeUpdate: () => {},
}],
},
onLoad() {
console.log(this.store['ns_foo']);
},
}, store);
组件中使用方式相同
给需要被通知的页面或者组件注册数据
第一种传参方式
/** 要创建或者监听的数据 */
key: string
/** 当数据改变后要通知的组件或者页面实例 */
instance: Page|Component)
第二种传参方式
options: {
/** 要创建或者监听的数据 */
key: string
/** 命名空间 */
nameSpace: string
/** 当数据改变后要通知的组件或者页面实例 */
instance: Page|Component
/** 第一次设置值时候的默认值 */
defaultValue: any
/** 值被更新前要做的事情 */
beforeUpdate
/** 值被更新后要做的事情 */
afterUpdate
}
第一种传参方式
注销所有该页面监听的数据
/** 需要被注销的页面或者组件 */
instance: Page|Component
第二种传参方式
注销所有命名空间下监听的`key`
/** 需要被注销的页面或者组件 */
instance: Page|Component
/** 需要被注销的数据名称 */
key: string
第三种传参方式
会注销某个命名空间下的某个数据的监听
/** 需要被注销的页面或者组件 */
instance: Page|Component
/** 需要被注销的数据名称 */
key: string
/** 命名空间 */
nameSpace: string
返回某一个数据
第一种传参方式
/** 需要获取的数据的名字 */
key: string
第二种传参方式
/** 需要获取的数据的名字 */
key: string
/** 命名空间 */
nameSpace: string
设置值
第一种传参方式
options: {
/** 数据名 */
key: string
/** 命名空间 */
nameSpace: string
/** 值 */
value: any
}
第二种传参方式
/** 数据名 */
key: string
/** 值 */
value: any