vue中如何更好地处理深度组件抛出的事件?

如果有一个组件,内部的子组件抛出事件,这个组件也应该抛出相同的事件。
一种的做法是一层一层抛出,这样的话代码比较冗余
一种做法是在子组件中通过 $parent.$emit 来抛出,这种做法会有一个问题,就是单看父组件是看不到父组件抛出的这些事件的,需要配合文档来使用。
还有一种做法是通过 inject 把 $emit 注入到子组件,但是问题和第二种是一样的
有没有更好的做法来处理这类问题?

阅读 6.1k
4 个回答

推荐使用 事件总线(Event Bus)

实现步骤示例:

1.创建事件总线: 创建一个全局的事件总线文件,例如 eventBus.js。

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();

2.在子组件中使用事件总线: 在子组件中,通过事件总线来抛出事件。

// ChildComponent.vue
import { EventBus } from './eventBus';

export default {
  methods: {
    triggerEvent(data) {
      EventBus.$emit('childEvent', data);
    }
  }
}

3.在父组件中监听事件: 在父组件中,监听事件总线上的事件,并在接收到事件时再抛出父组件的事件。

// ParentComponent.vue
import { EventBus } from './eventBus';

export default {
  created() {
    EventBus.$on('childEvent', this.handleChildEvent);
  },
  methods: {
    handleChildEvent(data) {
      this.$emit('parentEvent', data);
    }
  },
  beforeDestroy() {
    EventBus.$off('childEvent', this.handleChildEvent);
  }
}

不管你用哪种方法,文档都是必须的。写程序不能惧怕文档,把文档也看作程序的一部分就好了。

inject/provide 和事件总线两种方法都适合。层层抛太累,人累框架也累,不推荐。

分享下我的项目经验,其实组件深度透传也好,还是事件监听也好,并不是使用方式导致的冗余。而是页面代码模块化没有标准,如果你是组长可以强制使团队按照你的页面构建标准来走,如果是个人可以按照自己自己觉的舒服的标准来走。最最最简单的例子, 一个客户管理模块,文件夹是partner, 内部是index.vue, 你打算在index.vue里放什么?当然是客户管理模块全局管理的事件或者是变量啦,不管你是使用最新的 inject 还是provide, 还是使用传统的eventbus都不是关键。而是写代码的你😄

不论用什么方法,肯定是怎么方便,怎么好维护就怎么来;如果某种方法在你自己看来都很难维护那说明该方法不适用;
相比于依赖注入、多层传递等方法,跨层级的深度组件的事件处理还是建议EventBus,简易、解耦、更易维护

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏