在实际业务中使用了uni.$on()和uni.$emit()自定义事件来传递参数,但是发现在两个父子页面中都使用当前自定义事件,在子页面中调用后会触发父页面的事件(而且我是在组件中onUnload中$off了的)
实际业务是 这样
有一个公共的组件 esLoadEmployeeInfo 我们定义了一个 名称为onEsLoadEmployeeInfoBack 的事件这个组件用于选择人员
当每次选择了人员后 会调用
uni.$emit('onEsLoadEmployeeInfoBack', {params:option,personInfoList:this.rollArray});
将相关的数据传递出去 并在 onUnload 中
uni.$off('onEsLoadEmployeeInfoBack');手动删除了
现在有两个页面 A 和B
在A和B中都有一个按钮来选择人员
在A 页面中
onShow 中我们通过$on来监听
uni.$on('onEsLoadEmployeeInfoBack', res => {
if (res) {
console.log(res);
this.personInfoList = res.personInfoList;
this.person.id = res.params.guid;
this.person.name = res.params.name;
}
});
获取到了名称和数据
然后再A 页面还有个跳转页面 我们通过
uni.navigateTo({
url:"childer"
})
跳转到B界面
而且我也在A 界面的onUnload 中 uni.$off('onEsLoadEmployeeInfoBack');手动删除了
跳转到子页面
在子页面 同样也有一个按钮 用来取人员也是
在onShow中
uni.$on('onEsLoadEmployeeInfoBack', res => {
if (res) {
console.log(res);
this.personInfoList = res.personInfoList;
this.person.id = res.params.guid;
this.person.name = res.params.name;
}
});
调用
但是 当在子界面调用取人员的组件的时候,当选取后 触发
uni.$emit('onEsLoadEmployeeInfoBack', {params:option,personInfoList:this.rollArray});
的时候 会触发父页面的监听 这样 就触发了两次监听 子页面一次 父页面一次 这样导致了父页面的数据被修改了。
按理说我都手动删除了 事件不应该会触发两次的。
2 个回复
易软 (作者)
DCloud_uniCloud_JSON
首先你需要确认uni.$off('onEsLoadEmployeeInfoBack');触发的时机,确保是否触发了。
优化建议 在组件esLoadEmployeeInfo组件新增一个属性k,值推荐为使用该组件的页面名称或者路径。在$emit时携带k的值$on内做校验。可以避免同个组件,渲染到多个页面。用全局事件触发显示,会同时触发的情况。
如果只是app端的,公共悬浮框建议用subnvue实现。
易软 (作者)
好的
2020-11-18 15:38