Answer a question

I want to use a global eventbus to emit events from a child up to a (grand)parent.

In My main.js: I make a global eventbus available to all components.

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
    }
  }
})

Then, in my Childcomponent.vue: I emit an event to the eventbus on a click event

<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>

Then, in a Parentcomponent.vue I want to catch this event and do something with the data that the child had transmitted:

<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>

I'm not sure where to put the $on listener, I saw examples where they put $on in the ready hook. The code above does nothing, however I get no error in the console.

Answers

The ability to do this goes away with Vue 3. The RFC below mentions the motivation and links to some issues for further help.

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


I don't think data is the right place for the event bus. I definitely wouldn't use a global mixin for it either.

What I've done in the past is have a simple bus.js file like:

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

Then, in any component that needs the bus I just

import bus from './bus.js'

Then I normally do this to emit events.

bus.$emit('foo', whatever)

and this to catch them

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

I prefer to do it in created since that's the earliest step in the lifecycle you can do this.

Also, this issue on github has some very nice examples: https://github.com/vuejs/vuejs.org/pull/435

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐