前言(feihua): 最近闲来没事写了一个小的demo,在小的数据传输上没有必要去使用vuex,对于非父子组件的传值方法总结了一点心得体会供你们参考(若有太low,还请大神别喷俺)javascript
先上官方文档:vue
思路:java
1.定义一个空的Vue实例,做为中央事件总线。vuex
2.A组件定义方法去触发自定义事件dom
3.B组件在钩子里面去监听函数
OK!看似很简单,实践起来却贼鸡儿坑,一共遇到3个问题:this
1.A组件触发的事件在B组件中能够console显示,可是不能更新视图。spa
2.A经过路由跳转至B,第一次是没法console出传递过来的数值的(第二次之后就能够)。3d
3.第二次传过来的数据依次是递增的。code
咱们来一个一个分析解决:
问题一:最初判断是生命周期函数出了问题,通过分析发现是能够console出来应该是this指向的问题,最初写法:
mounted () { Bus.$on('msg', function (data) { this.message = data // this指向错误,该this指向Vue实例 }) }
因而分析,该this应该指当前事件,改成:
mounted () { Bus.$on('msg', (data) => { //箭头函数没有本身的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window this.message = data }) }
改成箭头函数以后就解决了传递过去的数据不更新视图的问题了!
问题二:为何第一次在A中触发事件,B中却没有打印呢?
请看图:
上图分别为B A组件生命周期,咱们能够明确的看到跳转至B组件的时候,A中的事件并无触发,如今明白了吧,经过分析有两种解决方案:
1.使用this.$nextTick(在下次 DOM 更新循环结束以后执行延迟回调),也就是说,等B组件dom准备完成后在触发这个方法,亲测没问题!
2.在beforeDestroy钩子中去触发事件,亲测有效!
问题三:传递的数据为何会递增呢?
是由于B中的事件一直存在,因此会致使每次都会监听上次触发的事件,解决办法:在B中beforeDestroy中使用Bus.$off('事件')去解绑这个事件,亲测有效!
各位大佬有更好的办法请留言!虚心指教