关于Vue eventBus总线传值时的生命周期问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Vue eventBus总线传值时的生命周期问题相关的知识,希望对你有一定的参考价值。

参考技术A 在Vue的非父子组件传递数据时,我们会用到Vue的bus总线机制,也就是在Vue的原型上声明一个vue实例,通过Vue的属性来链接各个页面。

Vue.prototype.$eventBus = new Vue()

有的时候我们需要从B页面返回A页面时带回数据来赋值给A页面,比如:在B页面点击返回方法中触发$emit(),然后在A页面的mounted()中监听$on并赋值给A页面的某个变量,但是我们发现并没有效果,无法正确赋值。

如下图所示:当你在A页面中点击跳转到B页面以后,再点击B页面回到A页面时,想通过$emit和$on方法赋值,但是发现并不能达到预期效果。

Vue的bus总线机制总的来说主要有几个关键点:

1.需要先监听$on、后触发$emit

2.注意$on触发的生命周期问题:

    a.如果是两个组件都已经加载完了比如父与子组件,$on可以放在mounted()生命周期中

    b.如果两个组件是有顺序的加载,比如页面A到页面B,$on需要放在created()生命周期中

这里我们主要讨论b情况,如果我们按以下写法

我们无法成功将msg赋值,打印的生命周期如下图:

在监听成功时A页面压根就还没开始加载,连beforeCreate()都没开始,所以这个时候监听事件触发以后并不能成功赋值

要保证监听事件在触发事件之前,还要保证触发的时候生命周期无误,由上面失败的案例中打印的生命周期可知,B页面的触发事件只能写在 beforeDestroy() 或者 destroyed() 之中,而A页面的监听事件只能放在 beforeCreate()、created()、beforeMount() 之中。

打印的生命周期如下图:

监听事件正确的出现在了相应的生命周期之后这样是可以成功触发传值的。

Vue开发中的中央事件总线

  在Vue开发中会遇到大量的组件之间共享数据的情形,针对不同的情形,Vue有相对应的解决方案。比如,父组件向子组件传值可以使用props,复杂项目中不同模块之间传值可以使用Vuex。但是,对于一些简单的项目里的非父子组件来说,它们一方面不适用props,另一方面又没有必要使用Vuex,针对这种情形可以使用中央事件总线(Event Bus)来解决问题。

1、创建中央事件总线

可以使用多种形式创建Event Bus。

Example 1:

// main.js
import Vue from ‘vue‘;
window.eventBus = new Vue();   // 注册全局事件对象
// 也可以修改Vue的原型链
Vue.prototype.$event = new Vue();

Example 2:

// ./event/moduleEvent.vue
<tempalte>
</template>
<script>
    import Vue from ‘vue‘;
    export default new Vue({
        data () {

        }
    })
</script>
// main.js
import moduleEvent from ‘./event/moduleEvent‘;
Vue.prototype.$event = moduleEvent;

Example 3:

// Example 2 中的创建eventBus的vue文件改为js文件,main.js不变
// ./event/moduleEvent.js
inport Vue from ‘vue‘;
export const moduleEvent = new Vue();
// main.js
import moduleEvent from ‘../event/moduleEvent‘;
Vue.prototype.$event = moduleEvent;

2、使用中央事件总线传值

先在组件A中发射事件:

// moduleA.vue
methods: {
    sendData () {
        // 通过修改Vue原型链的方式注册
        this.$event.$emit(‘dataFromA‘, this.dataA);
        // 直接注册在window上
        // moduleEvent.$emit(‘dataFromA‘, this.dataA);      
    }
}

然后就可以在组件B中接收了。组件B可以与组件A是父子、兄弟等等任意关系。

// moduleB.vue
methods: {
    getData () {
        // 通过修改Vue原型链的方式注册
        this.$event.$on(‘dataFromA‘,  function (data) {
            // handle data code
            // 回调函数的参数data即为组件A传递的值
        });
        // 直接注册在window上
        // moduleEvent.$emit(‘dataFromA‘,  function (data) {
            // handle data code
            // 回调函数的参数data即为组件A传递的值
        // });      
    }
}

3、单次接收事件或者移除事件Listeners

如果你只想监听一次该事件。可以使用 this.$event.$once(channel: string, callback(payload1, payload2, ...)),事件触发一次后将移除事件。

如果你想移除自定义事件监听器,你可以使用  this.$event.$off([event, callback]); 来实现。该方法如果没有提供参数,则移除所有的事件监听器;如果只提供事件,则移除该事件所有的监听器;如果同时提供了事件与回调,则只移除这个回调的监听器。


以上是关于关于Vue eventBus总线传值时的生命周期问题的主要内容,如果未能解决你的问题,请参考以下文章

27 Vue组件传值时的校验操作

Vue:基础语法、创建组件、组件间传值、实例生命周期

Vue开发中的中央事件总线

C#总结EventBus事件总线的使用-自己实现事件总线

vue3.0的生命周期和父子传值,一学就会#yyds干货盘点#

快速入门vue3.0系列之生命周期及父传值,建议“收藏细品”,会持续更新!❤