Vue事件总线及非父子组件传值的坑

如何使用事件总线进行非父子组件之间传值

  • 新建一个js文件命名为Bus.js
import Vue from 'vue'
const Bus = new Vue();
export default Bus
  • 组件B
// 组件B ,监听事件send
<template>
  <div>
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: ''
      }
    },
    created() {
      let _this = this
      // 用$on监听事件并接受数据
      Bus.$on('send', (data) => {
        _this.name = data
        console.log(data)
      })
    },
    methods: {}
  }
</script>
  • 组件A
// 组件A, 触发事件send
<template>
  <div>
    <input type="button" value="点击触发" @click="onClick">
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elValue: '我是B组件数据'
      }
    },
    methods: {
        // 发送数据
      onClick() {
        Bus.$emit('send', this.elValue)
      }
    }
  }
</script>

这样就可以简单的实现一个非父子组件之间的传值了

在使用事件总线时遇到的问题

  • 第一次触发的时候$on事件没有被触发
    • 当我们还在页面A的时候,页面B还没生成,也就是页面B中的 created中所监听的来自于A中的事件还没有被触发。这个时候当你A中emit事件的时候,B其实是没有监听到的。
    • 我们可以把A页面组件中的emit事件写在beforeDestory中去。因为这个时候,B页面组件已经被created了,也就是我们写的on事件已经触发了。
    • 如果是像我们上面的代码通过事件触发的时候可以使用$nextTick()方法。将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
    onClick() :  {
       let _this = this
      // DOM 还没有更新
      _this.$nextTick(function () {
      // DOM 现在更新了
      Bus.$emit('send', this.elValue)
      })
    }
    
  • 后面再一次依次去触发的时候会出现,每一次都会发现好像之前的$on事件分发都没有被撤销一样,导致每一次的事件触发执行越来越多。
    • 这个$on事件是不会自动清除销毁的,需要我们手动来销毁。
    • 在B组件页面中添加Bus.$off来关闭
    beforeDestroy(){
        bus.$off('send')
      }
    

如有错误之处,欢迎指正。感谢~~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容