【问题标题】:$emit event is not being heard in Vue componentsVue 组件中没有听到 $emit 事件
【发布时间】:2020-03-18 00:02:54
【问题描述】:

我有一个 Vue 应用程序,其中父组件需要发出一个事件,它在一个按钮中执行此操作:

<button @click.prevent="saveTradeClick" class="btn btn-primary">Save</button>

它触发一个方法:

  saveTradeClick: function (event) {
    console.log("click");
    this.$emit('SAVE');
    console.log("after emit");
  },

子组件应该监听这个事件来触发一个方法。

    mounted() {
   this.$parent.$on('SAVE', this.submitTrade);
}

这不起作用。我得到了console.log('click'); 但是,我从子组件中一无所获。

当我查看 Vue 开发工具时,我收到了一个 $emit 事件,但仅此而已。有什么想法我可以用这个吗?

【问题讨论】:

  • 您是否确保在父级发出事件时子级已挂载?
  • 这样干净多了。 Vue.prototype.$eventHub = new Vue()

标签: vue.js


【解决方案1】:

如果您希望子组件侦听来自父组件的事件,另一个想法是创建一个Event Bus

现在这个特性并不是开箱即用的,所以你必须实际创建一个新的 Vue 实例,然后像这样导出 EventBus 特性。

eventbus.js

import Vue from 'vue';
export const EventBus = new Vue();

然后您可以将EventBus 导入到您想要与之交互的组件中。

父组件

<template>
  <div class="pleeease-click-me" @click="emitGlobalClickEvent()"></div>
</template>

<script>
// Import the EventBus we just created.
import { EventBus } from './event-bus.js';

export default {
  name: 'Parent',
  data() {
    return {
      clickCount: 0
    }
  },

  methods: {
    emitGlobalClickEvent() {
      this.clickCount++;
      // Send the event on a channel (i-got-clicked) with a payload (the click count.)
      EventBus.$emit('i-got-clicked', this.clickCount);
    }
  }
}
</script>

因此,您现在可以在您的子组件中监听事件i-got-clicked

子组件

<script>
// Import the EventBus we just created.
import { EventBus } from './event-bus.js';

export default {
  name: 'Child',

  mounted() {
    EventBus.$on('i-got-clicked', clickCount => {
     console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`)
  });
}
</script>

clickCount 是从父级传递的,因此您可以通过监听事件长时间共享数据。

根据您的应用程序大小的另一种解决方案是查看vuex

【讨论】:

    【解决方案2】:

    我建议控制来自父组件的状态以获得更多控制权,而不是让您的子组件依赖您可能不可用的父组件。

    示例:

    家长

    <template>
      <div>
        <button @click.prevent="saveTradeClick" class="btn btn-primary">Save</button>
        <child :traded="traded"></child>
      <div>
    </template>
    <script>
    export default {
      data: () => ({ traded: false }),
      methods: {
        saveTradeClick() {
          this.traded = true;
        },
      },
    };
    </script>
    

    儿童

    <template>
      <div><div>
    </template>
    <script>
    export default {
      props: ['traded'],
      watch:{
        traded(val) {
          if (val) this.submitTrade();
        },
      },
    };
    </script>
    

    Vue unwritten rules

    • 允许父母引用孩子,例如通过 props 或 refs
    • 孩子没有对父母的任何参考
    • 儿童不会更改通过 props 传递的数据。

    【讨论】:

      猜你喜欢
      • 2017-01-12
      • 2017-01-22
      • 2017-07-07
      • 2020-03-16
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 2021-12-27
      • 2020-06-25
      相关资源
      最近更新 更多