小程序自定义组件通信与全局状态方案
【摘要】 小程序原生开发的组件通信,官方给了triggerEvent和relations,但复杂一点的页面就不够用。这篇梳理从基础到全局状态的四层通信方案,以及我们最后的选型。第一层:父子通信,triggerEvent。//子组件Component({properties:{value:String},//父到子methods:{onInput(e){this.triggerEvent('c...
小程序原生开发的组件通信,官方给了 triggerEvent 和 relations,但复杂一点的页面就不够用。这篇梳理从基础到全局状态的四层通信方案,以及我们最后的选型。
第一层:父子通信,triggerEvent。
// 子组件
Component({
properties: { value: String }, // 父到子
methods: {
onInput(e) {
this.triggerEvent('change', e.detail.value) // 子到父
},
},
})
<!-- 父页面 -->
<search-box value="{{kw}}" bind:change="onKwChange" />
标准但啰嗦:每加一个对外事件,两边都要改。跨层级(孙组件到爷爷页面)要层层转发,三层以上就该考虑别的方案了。
第二层:兄弟与跨层级,用 relations 还是事件总线上帝视角组件。relations 适合「父子有结构关联」的组件(如 collapse 与 collapse-item),互相拿到对方实例直接调方法。而通用场景我们用了一个极简总线:
// bus.js
const listeners = new Map()
module.exports = {
on(event, fn) {
if (!listeners.has(event)) listeners.set(event, new Set())
listeners.get(event).add(fn)
return () => listeners.get(event)?.delete(fn) // 返回解绑函数
},
emit(event, payload) {
listeners.get(event)?.forEach((fn) => fn(payload))
},
}
// 组件 attached 时订阅,detached 时解绑(必须成对,否则泄漏)
Component({
lifetimes: {
attached() {
this._off = bus.on('cart-updated', (n) => this.setData({ count: n }))
},
detached() {
this._off()
},
},
})
第三层:全局状态。购物车数量、登录态这类多处共享的数据,裸总线会让调用点满天飞。选型对比:
- mobx-miniprogram + mobx-miniprogram-bindings:响应式,绑定后自动更新,学习成本低(写过 mobx 的零成本上手)
- westore:腾讯出品,基于 diff 的 setData 优化,顺带解决通信
- 自研简易 store:一个 observable 包装加页面 mixin
我们选了 mobx 系,共享 store 定义:
// stores/cart.js
import { observable, action } from 'mobx-miniprogram'
export const cartStore = observable({
count: 0,
addToCart: action(function () {
this.count += 1
}),
})
// 组件里绑定:store 变化自动 setData
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { cartStore } from '../../stores/cart'
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
store: cartStore,
fields: { count: 'count' },
actions: { addToCart: 'addToCart' },
},
})
fields/actions 一配,模板直接用 count 和点击直接调 addToCart,组件内部不再写一行 setData。
四层方案的使用边界:props/events 管父子、bus 管偶发跨层通知、store 管全局共享数据、relations 管结构化组件簇。全部混用 store 的过度集中和全部用事件的满天飞,都是反面教材。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)