Vuejs 2: отправка события из компонента в родительский

У меня есть этот код:

HTML

<div id="app">
  {{text}}
  <my-component></my-component>
</div>

JS

Vue.component('my-component', {
  template: '<button @click="click">Click me</button>',
  methods: {
    click() {
        this.$emit('send', 'bye')
    }
  }
})

new Vue({
  el: "#app",
  data: {
    text: "hello"
  },
  created() {
    this.$on('send', (text) => {
        this.text = text;
    })
  }
})

рабочий пример: https://jsfiddle.net/rjurado/y4yf6nve/

почему send события не работает?

Ответ 1

this.$emit относится только к компонентам Vue. Вы должны использовать root экземпляр свойства для взаимодействия с компонентами из корневого экземпляра. Итак, в основном добавьте root для событий:

this.$root.$emit('send', 'bye')

this.$root.$on('send', (text) => {
      this.text = text;
  })

Рабочий пример: jsFiddle

Центральная шина событий Vue.js

Еще лучше использовать центральную маршрутную шину: docs

var bus = new Vue();

Vue.component('my-component', {
  template: '<button @click="click">Click me</button>',
  methods: {
    click() {
        bus.$emit('send', 'bye')
    }
  }
})

new Vue({
  el: "#app",
  data: {
    text: "hello"
  },
  created() {
    bus.$on('send', (text) => {
        this.text = text;
    })
  }
})

Рабочий пример: jsFiddle

Ответ 2

Родительские компоненты могут напрямую прослушивать события, исходящие из дочерних компонентов, используя v-on.

HTML

<div id="app">
  {{text}}
  <my-component v-on:send="sendText"></my-component>
</div>

JS

Vue.component('my-component', {
  template: '<button @click="click">Click me</button>',
  methods: {
    click() {
      this.$emit('send', 'bye')
    }
  }
})

new Vue({
  el: "#app",
  data: {
    text: "hello"
  },
  methods: {
    sendText(text) {
      alert(text)
    }
  }
})

Рабочий пример: https://jsfiddle.net/y4yf6nve/2/

Ответ 3

Для будущих ссылок имя настраиваемых событий не может быть выполнено с помощью camelCased. Используйте this.$emit('send_event', 'bye') вместо this.$emit('sendEvent', 'bye') https://github.com/vuejs/vue/issues/4044