需求场景:
小程序中有AB两个页面,A属于商品列表页,B属于商品编辑页,A页面点击编辑商品需要将商品数据传输到B页面。
解决方案:
- 利用app.js globalData,设置公共变量 缺点:页面间数据不是同步的,数据来源不清晰
- 利用storage, 缺点:大小限制,分同步异步,数据命名冲突
- 利用事件总线EventBus 缺点:功能单一
- 自己实现一套类似redux或者vuex的状态管理工具
参考vuex API为小程序增加轻量级状态管理并提供页面间通信接口,解决跨页面数据共享问题,支持watch和computed功能
安装:
npm i -S swan-store
命名约定:所有的共享状态都以$开头,包括
$state
和$getter
。**
使用
// /store/swan-store
import Store from 'swan-store';
export default new Store({
state: {
counter: 0,
num: 110,
arr: [1, 2, 3, 4, 5, 6, 7],
test: []
},
mutations: { // 同步
count(state, payload) {
return state.counter += payload;
},
count1(state, payload) {
return state.num += payload;
},
addarr(state, payload) {
state.test = payload;
},
},
actions: { // 异步
countAsync(store, payload) {
return new Promise(resolve => {
setTimeout(() => {
store.commit('count1', payload);
resolve();
}, 1000);
});
},
},
getters: {
arrLength(state) {
return state.arr.length;
}
}
});
import Store from '../../store/swan-store';
Page({
data: {
number: 0,
name: 'SWAN',
items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
test: {
a: 100,
b: 200
}
},
computed: { // 计算属性
test2() {
return this.data.test.a + 'Test2'
},
test3() {
return this.data.test.b + 'Test3'
}
},
watch: { // 监听数据变化
test(newVal) {
console.log('test发生变化', newVal);
}
},
onLoad() {
Store.install(this); // 小程序注册
Store.commit('addarr', 1); // 同步修改数据
Store.dispatch('countAsync', 5); // 异步修改数据
Store.replaceState({ // 替换数据
counter: 955
});
const a = Store.subscribe((type, state) => { // 订阅
i++;
console.log(type, state);
if (i > 3) a(); // 取消订阅
});
}
})
<view>{{$state.counter}}</view> // 获取store里的值
<view>{{$state.num}}</view>
<view>{{$state.arr}}</view>
<view>{{$getter.arrLength}}</view> // store里的getter
<view>{{tag}}</view>
<view>{{test2}}</view> // 计算属性
<view>{{test3}}</view>