本文正在参加「金石计划 . 瓜分6万现金大奖」
全局数据共享 又被叫做 状态管理 目的是为了解决 层级较远的组件之间进行数据共享的问题
常见的全局数据共享方案有vuex,pinia,redux,mobx等
在小程序中 可以使用mobx-miniprogram 和 mobx-miniprogram-bindings来实现全局数据共享
- mobx-miniprogram 用于创建 store实例对象
- mobx-miniprogram-bingings 用于 把store中共享的数据和方法 绑定到对应的组件和页面中
mobx-miniprogram并不要求在整个小程序中有且只有一个根,可以存在多个对应的store
npm add mobx-miniprogram
npm add mobx-miniprogram-bindings
基本使用
store的定义
store/index.js
import { observable, action } from 'mobx-miniprogram'
export default observable({
// 被共享的数据
name: 'Klaus',
age: 23,
// 计算属性
// 一般情况下 计算属性不需要被设置
// 只需要根据对应的依赖项进行计算即可
// 所以在mobx-miniprogram中使用getter定义计算属性
get doubleAge() {
return this.age * 2
},
// 定义action方法 来修改共享的数据
// 在mobx-miniprogram中修改共享状态的唯一方法只有通过action方法
// 直接修改共享状态 会 静默失效
// 为了避免和组件或页面中的方法命名冲突
// 对应的action方法一般使用Action作为后缀名结尾
// action中传入的方法 必须使用普通函数形式进行定义
// 不可以使用箭头函数形式进行定义
// 当使用普通函数形式定义的时候,aciton的回调函数再被调用的时候,会将当前store实例作为this值传入
// 而使用箭头函数的时候,因为箭头函数内部不绑定this值,所以对应的回调函数中的this值将是undefined
updateNameAction: action(function(name) {
this.name = name
}),
updateAgeAction: action(function(age) {
this.age = age
})
})
在页面中使用
<view>
<view>{{ name }} - {{ age }} - {{ doubleAge }}</view>
<button size="mini" type="primary" bindtap="updateName" data-name="Alex">updateName</button>
<button size="mini" type="primary" bindtap="updateAge" data-age="{{ 32 }}">updateAge</button>
</view>
// 在页面和组件中 引入模块的时候 可以引入第三方模块 也可以引入自定义模块
// 但是在引入自定义模块饿时候,需要注意以下亮点:
// 1. 只能使用相对路径, 不可以使用绝对路径
// 2. 只能省略后缀名, 不能省略文件名,也就是说小程序并不会自动去查找对应的index文件并导入
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import store from '../../store/index'
Page({
data: {
// 虽然storeBindings并不需要在页面中使用
// 所以不设置初始值,也是可以的,但是推荐设置上对应的初始值
storeBindings: null
},
// 在onLoad生命周期中进行数据的绑定
onLoad() {
// 使用createStoreBindings方法将数据和方法绑定到第一个参数对象上
// 所以一般第一个参数传入的值就是this
// 即意味着将对应的数据绑定到当前页面或当前组件上
// createStoreBindings方法会返回一个对象
//通过该对象可以在组件或页面被移除的时候执行对应的清理工作
this.storeBindings = createStoreBindings(this, {
store, // 参数一 --- 数据源
// 参数二 --- 那些状态需要绑定到当前组件或页面上
// 绑定后就可以通过 this.xxxx 去进行使用
fields: ['name', 'age', 'doubleAge'],
// 参数三 --- 那些操作需要被绑定到当前组件或页面上
// 绑定后就可以通过this.xxxx() 去进行调用
actions: ['updateNameAction', 'updateAgeAction']
})
},
// 在onUnload生命周期中进行数据的清理工作
onUnload() {
// 通过调用destoryStoreBindings在组件或页面被销毁的时候,清除绑定的共享状态和action函数
this.storeBindings.destoryStoreBindings()
},
updateName(e) {
// 在组件或页面内不能主动修改store中的数据,只能通过actions来进行修改
this.updateNameAction(e.currentTarget.dataset.name)
},
updateAge(e) {
this.updateAgeAction(e.currentTarget.dataset.age)
}
})
在组件中使用
<view>
<view>{{ name }} - {{ age }} - {{ doubleAge }}</view>
<button size="mini" type="primary" bindtap="updateName" data-name="Alex">updateName</button>
<button size="mini" type="primary" bindtap="updateAge" data-age="{{ 32 }}">updateAge</button>
</view>
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import store from '../../../../store/index'
Component({
// 在组件中使用 store的方式是通过behaviors进行混入操作
behaviors: [storeBindingsBehavior],
// 将要使用的数据和方法进行绑定
storeBindings: {
store, // 数据源
// 需要映射的字段
fields: {
// key --- 在组件中需要使用到的状态名
// value --- 有三种使用方式
// 1. 直接是一个字符串,对应的值是在store中对应的状态名
name: 'name',
// 2. 一个函数 --- 参数是store对象,可以通过该对象拿取对应的共享状态
age: store => store.age,
// 3. 一个函数 --- 可以是无参的函数,但是在函数体内部依旧可以通过store对象拿到对应的共享状态
doubleAge: () => store.doubleAge
},
// 需要映射的actions
actions: {
// key --- 在组件中需要使用的方法名
// value --- 在store中对应的action方法名 --- ps: 类型是字符串
updateNameAction: 'updateNameAction',
updateAgeAction: 'updateAgeAction'
}
},
methods: {
updateName(e) {
this.updateNameAction(e.currentTarget.dataset.name)
},
updateAge(e) {
this.updateAgeAction(e.currentTarget.dataset.age)
}
}
})
本文正在参加「金石计划 . 瓜分6万现金大奖」