全局数据共享是为了解决组件之间数据共享的问题。
全局数据共享方案
开发中常用的全局共享方案有:Vuex、Redux、MobX等。在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。其中:
- mobx-miniprogram用来
创建Store实例对象【创建全局数据共享池】 - mobx-miniprogram-bindings用来
把Store中的共享数据或方法,绑定到组件或页面中使用
安装MobX相关包
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
构建npm
创建store
新增store目录,在store目录中新怎store.js文件,用来专门创建Store的实例对象
// store.js
// observable 用来创建检测对象,对象中的属性会被转换成响应式数据
// action 用来显示定义action方法
import {action, observable} from "mobx-miniprogram"
export const store=observable({
// 数据字段
numA:1,
numB:2,
// 计算属性
get sum(){
return this.numA+this.numB
},
// actions 方法,用来修改 store 中的数据
updateNum1:action(function(step){
this.numA+=step;
}),
updateNum2:action(function(step){
this.numB+=step;
}),
})
将store中成员绑定到页面中
方式一
// behavior -> userBehaviors.js
import {BehaviorWithStore} from "mobx-miniprogram-bindings"
import {store} from "../store/store"
export const userBehavior = BehaviorWithStore({
storeBindings:{
store,
fields:['userInfo'],
actions:["setUserInfo"]
}
})
import {userBehavior} from "../../behavior/userBehaviors"
// pages/list/list.js
Page({
behaviors:[userBehavior],
方式二
将store中的数据绑定到页面,在onLoad生命周期中绑定,页面卸载时卸载实例,在onUnload中清理
import {createStoreBindings} from "mobx-miniprogram-bindings"
import {store} from "../../store/store"
Page({
// 监听页面加载
onLoad(){
this.storeBindings=createStoreBindings(this,{
store,
fields:["numA","numB","sum"],
actions:['updateNum1'],
})
},
stepHandler(e){
this.updateNum1(e.target.dataset.step)
},
// 监听页面卸载
onUnload(){
this.storeBindings.destroyStoreBindings();
},
<view>numA:{{numA}} numB:{{numB}} sum:{{sum}}</view>
<van-button type="primary" bind:tap="stepHandler" data-step="{{1}}">store</van-button>
将store中成员绑定到组件中
方式一
// 导入ComponentWithStore
import {ComponentWithStore} from "mobx-miniprogram-bindings"
// 导入store对象
import {store} from "../../store/store"
// pages/mobx/mobx.js
// 导入ComponentWithStore 替换 Component方法构造页面
ComponentWithStore({
// 让页面和store建立关联
storeBindings:{
store:store, // 需要绑定的store对象
fields:['token'], // 需要从store对象中映射哪些数据
actions:['setToken'], //从store对象中映射actions方法
},
方式二
import {storeBindingsBehavior} from "mobx-miniprogram-bindings"
import {store} from "../../store/store"
Component({
// 通过storeBindingsBehavior实现自动绑定
behaviors:[storeBindingsBehavior],
storeBindings:{
store,
fields:{
numA:()=>store.numA, // 绑定字段的第1种方式
numB:(store)=>store.numB,// 绑定字段的第2种方式
sum:"sum" // 绑定字段的第3种方式
},
actions:{
updateNum2:"updateNum2"
}
},
methods: {
stepHandler(e){
this.updateNum2(e.target.dataset.step)
},
...
}
...
<view>numA:{{numA}} numB:{{numB}} sum:{{sum}}</view>
<van-button type="primary" bind:tap="stepHandler" data-step="{{1}}">store</van-button>
绑定多个store以及命名空间
需要将storeBindings改为数组的形式
import {BehaviorWithStore} from "mobx-miniprogram-bindings"
import {storeA} from "../store/storeA"
import {storeB} from "../store/storeB"
export const userBehavior = BehaviorWithStore({
storeBindings:[
{
storeA,
fields:['userInfo'],
actions:["setUserInfo"]
},
{
storeB,
fields:['userInfo'],
actions:["setUserInfo"]
}
]
})
两个store都有setUserInfo方法,有两种方式:
- 可使用对象的方式,修改别名
- 添加命名空间
// 修改别名
storeBindings:[
{
storeA,
fields:['userInfo'],
actions:["setUserInfo"]
},
{
storeB,
fields:{
userInfoA:"userInfo",
},
actions:{
setUserInfoB:"setUserInfo",
}
}
]
// 添加命名空间
storeBindings:[
{
storeA,
fields:['userInfo'],
actions:["setUserInfo"]
},
{
storeB,
namespace:"cloneStore",
// 数据冲突,添加命名空间可以解决
// 添加命名空间后想访问数据,需要加上命名空间名字才可以
// 如:cloneStore.userInfo
fields:['userInfo'],
// 方法冲突,依然需要使用对象方式
// actions:["setUserInfo"],
actions:{
setUserInfoB:"setUserInfo",
}
}
]