Связь между двумя компонентами (не связана с дочерним родителем)

компонент 1

 getMyProfile(){    
       this.$root.$emit('event');
           console.log("emited")
     }, 

компонент 2

mounted() {
    this.$root.$on('event', () = {
    alert("Fired");
 }
}

Я пытаюсь предупредить "выстрел" из компонента 2 из компонента 1. Но этого не происходит. что я делаю не так Должен ли я добавить что-то на основной JS?

4 ответа

Решение

Кроме маленькой опечатки в вашем $on непонятно, что вы делаете неправильно, поскольку вы не предоставили достаточно контекста, но вот рабочий пример того, что именно вы пытаетесь сделать (отправка и получение события через $root элемент, без создания отдельного экземпляра EventUue Vue). (Многие люди предпочитают передавать сообщения через отдельный экземпляр, но это функционально похоже на $root.)

Я включил объект полезной нагрузки, чтобы продемонстрировать передачу информации вместе с событием.

Vue.component('sender', {
  template: '<span><button @click="send">Sender</button></span>',
  methods: {
    send() {
      console.log("Sending...")
      this.$root.$emit('eventName', {
        message: "This is a message object sent with the event"
      })
    }
  }
})

Vue.component('receiver', {
  template: '<span>Receiver component {{message}}</span>',
  data() {return {message: ''}},
  mounted() {
    this.$root.$on('eventName', (payload) => {
      console.log("Received message", payload)
      this.message = payload.message
    })
  }
})

new Vue({
  el: '#app'
});
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<div id="app">
  <sender></sender>
  <receiver></receiver>
</div>

Лично я не склонен часто использовать этот шаблон; Я считаю, что лучше обрабатывать межкомпонентную связь от родителя к потомку как реквизит, а от потомка к родителю как прямой $emit с (не включен $root). Когда я обнаруживаю, что мне нужно общение между братьями и сестрами, это, как правило, признак того, что я сделал несколько неудачных архитектурных решений или что мое приложение стало достаточно большим, чтобы я мог переключиться на vuex. Сбор всех сообщений о событиях в одном месте, будь то $root или экземпляр Eventbus, как правило, усложняет анализ приложения и отладку.

По крайней мере, вы должны очень четко обозначать свои события, чтобы легче было понять, откуда они берутся; имена событий, такие как "handleClick" или просто "event", быстро становятся загадочными неизвестными.

Итак, что вы ищете, так это шину событий (глобальные события)

Я бы посоветовал рассмотреть возможность использования vuex в любое время, когда вам нужно реализовать шину событий.

Давайте вернемся к проблеме.

Создать файл event-bus.js это то, что будет собирать и распространять события.

import Vue from 'vue'

const EventBus = new Vue()

export default EventBus

Теперь в вашем main.js зарегистрировать свой автобус

import Vue from 'vue'
import eventBus from './event-bus'
//other imports

Vue.prototype.$eventBus = eventBus

new Vue({
   ...
}).$mount('#app')

Теперь вы можете:

  • слушать события с this.$eventBus.$on(eventName)
  • испускать события this.$eventBus.$emit(eventName)

В этом примере я перенесу событие из дочернего в родительский компонент с $emit

Дочерний компонент:

Vue.component('Child component ', {
    methods: {
        getMyProfile: function() {
            this.$emit('me-event', 'YUP!')
        }
    },
    template: `
        <button v-on:click="getMyProfile">
            Emmit Event to Parrent
        </button>
    `
})

Родительский компонент:

Vue.component('Parent component ', {
    methods: {
      getEventFromChild: function(event) {
        alert(event)
      }
    }
    template: `
        <div>
          <Child-component v-on:me-event="getEventFromChild" />
        </div>
    `
})

например, когда у вас есть поток данных в одну сторону от родителя к потомку, и вы хотите перенести данные от потомка к родителю, вы можете использовать $emit и перенести их от потомка... а в родителе вы должны перехватить его с помощью директивы v-on. (простите мой английский)

Если компонент 2 является родителем компонента 1, вы можете сделать:

getMyProfile(){    
       this.$emit('myevent');
           console.log("emited")
     }, 

для компонента 2

<componant-2 @myevent="dosomething" ...></componant-2>

и во втором компоненте

methods: {
  dosomething() {
    console.log('Event Received');
   }
}
Другие вопросы по тегам