1. Background
The requirement is that every place where the video is played has a button to control whether to mute or not, and clicking a certain mute will mute the global sound.
Question : Since each of my small cards is a component, the essence is that each page refers to the same component several times. I used setData at the beginning, but the data in each card is independent after deep copying, so Clicking a button will only change the sound state of the video it's in.
Extended question : I also tried to use app.globalData, which is only valid on different pages, but multiple components on the same page are still invalid.
Two, the solution
In applets, often some data needs to be shared among several pages or components. Using MobX to manage the cross-page data of the applet is actually similar to the store of vuex.
Instructions:
1. Introduce MobX in the applet
Method 1: Directly import the two folders mobx-miniprogram and mobx-miniprogram-bindings into the project
Method 2: In the mini program project, you can introduce MobX through npm. If you have not used npm in the applet, execute the command in the applet directory first:
npm init -y
Introducing MobX:
npm install --save mobx-miniprogram mobx-miniprogram-bindings
You can refer to the official sample code snippet: (open in WeChat developer tools): https://developers.weixin.qq.com/s/nGvWJ2mL7et0 https://developers.weixin.qq.com/s/nGvWJ2mL7et0
2. Create MobX Store
import {observable, action} from 'mobx-miniprogram';
//是否静音
const localVoice=wx.getStorageSync('voiceMuteStatus')
export const storeVoice = observable({
//自定义属性和方法
voiceMuteStatus: localVoice,
updateVoice: action(function(voiceMuteStatus) {
this.voiceMuteStatus = voiceMuteStatus
})
})
3. Use in the Component constructor
The following code can realize global sound management.
//引入storeBindingsBehavior和自定义的store方法
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings';
import { storeVoice } from '../../store/index';
Component({
//在behaviors中
behaviors: [storeBindingsBehavior],
data: {
},
//绑定自己写的store
storeBindings: {
store: storeVoice,
fields: {
voiceMuteStatus: () => storeVoice.voiceMuteStatus,
},
actions: {
buttonTap: 'updateVoice',
},
},
methods: {
changeVoice() {
wx.setStorageSync('voiceMuteStatus', !storeVoice.voiceMuteStatus);
//可以直接这样调用updateVoice方法
this.buttonTap(!storeVoice.voiceMuteStatus);
},
}
})
3. Extended knowledge
1. The usage of MobX Store in Component and Page is different
Official example:
import { createStoreBindings } from "mobx-miniprogram-bindings";
import { store } from "./store";
Page({
data: {
someData: "...",
},
onLoad() {
this.storeBindings = createStoreBindings(this, {
store,
fields: ["numA", "numB", "sum"],
actions: ["update"],
});
},
onUnload() {
this.storeBindings.destroyStoreBindings();
},
myMethod() {
this.data.sum; // 来自于 MobX store 的字段
},
});
2. Partial update
If only a part (subfield) of the object is updated, the interface will not change! For example:
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
store,
fields: ["someObject"],
},
});
If try in store
:
this.someObject.someField = "xxx";
This will not trigger an interface update. Consider changing to:
this.someObject = Object.assign({}, this.someObject, { someField: "xxx" });