Vue.js 使用全局事件总线从 child 组件发射到(大)parent 组件的事件

Vue.js event emitting from child component to (grand)parent component using global eventbus

我想使用全局事件总线发出从 child 到(大)parent 的事件。

My main.js: 中,我为所有组件提供了一个全局事件总线。

import Vue from 'vue'
import App from './App'
const eventHub = new Vue()

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

Vue.mixin({
  data: function () {
    return {
      eventHub: eventHub
    }
  }
})

然后,在我的 Childcomponent.vue: 中,我在单击事件时向事件总线发出一个事件

<template>
  <button @click="save">Save</button>
</template>

<script>
  let data = {
    columnName: '',
    order: 0
  }

  export default {
    ...
    name: 'init-column',
    methods: {
      save: function () {
        this.eventHub.$emit('newColumn', data)
      }
    }
    ...
  }
</script>

然后,在 Parentcomponent.vue 中,我想捕捉这个事件并对 child 传输的数据做一些事情:

<template>
  <div id="app">
      <column v-for="column in allData"></column>
      <init-column v-if="newColumn"></init-column>
    </div>
  </div>
</template>

<script>
  import initColumn from './components/Init-column'

  let newColumn = false

  export default {
    ...
    name: 'project',
    ready: function () {
      this.eventHub.$on('newColumn', (event) => {
        console.log(event)
      })
    }
    ...
  }
</script>

我不确定将 $on 侦听器放在哪里,我看到了他们将 $on 放在 ready 挂钩中的示例。上面的代码什么也没做,但是我在控制台中没有收到任何错误。

您可以按照文档中的说明将 $on 侦听器放入创建的挂钩中:https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

您不能在 Vue 2.0 中使用 ready 钩子。 ready hook 最初在 Vue 1.x 中可用,但现在已弃用。

这样做的能力随着 Vue 3 消失了。下面的 RFC 提到了一些问题的动机和链接以获得进一步的帮助。

https://github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md


我认为 data 不是事件总线的正确位置。我也绝对不会为此使用全局混合。

我过去所做的是有一个简单的 bus.js 文件,例如:

import Vue from 'vue'
export default new Vue()

然后,在任何需要总线的组件中,我只是

import bus from './bus.js'

然后我通常这样做来发出事件。

bus.$emit('foo', whatever)

这是为了抓住他们

created () {
  bus.$on('foo', this.someMethod)
}

我更喜欢在创建时执行此操作,因为这是您可以执行此操作的生命周期中最早的一步。

另外,github 上的这个问题有一些很好的例子:https://github.com/vuejs/vuejs.org/pull/435

我通过自定义事件获得了预期的效果:@newColumn="event"

<init-column @newColumn="event" v-if="newColumn"></init-column>
...
methods: { event: function(e) { console.log(e) }

因此,每当我从 child $emit 时,它都会调用事件方法。

这很管用,但出于某种奇怪的原因,监听器 $on 却不行。也许我在 $on 方法中遗漏了一些东西。