从子组件中的父组件中侦听事件,并在没有集线器的情况下在vue中执行子组件的方法

Pay*_*ari 6 events event-handling vue.js vue-component vuejs2

似乎有很多围绕这一话题的讨论,如使用集线器答案#1,利用裁判答案#1,所以我真的想问问专家提供一次清晰简洁的回答了这个问题.如果答案也是不可能的,请说明!

这是一个场景:有两个组件,父母和孩子

<Parent> // There is a button here that can be clicked to emit an event using 'this.$emit()'
   <Child></Child> // The child listens and once hears the event, it does something
</Parent>
Run Code Online (Sandbox Code Playgroud)

该怎么办?

单击Parent中的按钮发出特定事件,孩子将不断地监听,一​​旦听到事件,它就会执行一个动作,例如调用自己的方法.

到目前为止,有什么关于这个的?

  1. 使用集线器,在Vue Hub中明确指出这是针对非父母 - 儿童沟通的,那么使用它进行亲子沟通有什么意义呢?

  2. 使用Refs,当无法使用道具和事件时,它作为最终解决方案提供.那么为什么不能在第一时间举办活动呢?

我自己的想法

在我看来,一个事件的发射和听取它只能从孩子到父母,基本上是单向沟通.父节点能够发出事件,但子组件无法捕获事件.为什么?我尝试过这个并没有奏效:

在我的父组件中(通过单击父组件中的按钮触发):

methods: {
  generateCharts: function () {
    this.$emit('generate-charts')
    console.log('charts generated')
}
Run Code Online (Sandbox Code Playgroud)

在子组件我有:

mounted () {
 this.parent.$on('generate-charts', function () {
   console.log('event captured') // Here nothing gets logged to the console
 })
}
Run Code Online (Sandbox Code Playgroud)

更新

刚刚遇到这个答案Vue $ emit.显然这对于​​Vue来说根本不可能.

在第一种情况下,它似乎是一种缺陷,因为我曾经在几种情况下需要从父母那里开一个事件并在孩子身上听它.

我可以想像,必须有一个原因,这是不可能的Vue公司,它可能是一个设计考虑,Vue公司的专家们解释为什么是这样的情况下,什么是更好的设计方法,一般情况下,解决通过从父事件对孩子,将非常感激.

Jus*_*tin 4

答案是使用道具并对这些道具的变化做出反应。一开始有点令人困惑,因为看起来需要很多代码来做一些简单的事情,但随着应用程序变得越来越复杂,通过使用 props 强制执行数据流的一种方式确实有助于调试和推理代码试图完成的任务。

例如,模态。您的父母showChildModal = true通过单击按钮进行设置,该值作为道具传递给孩子。孩子正在观察道具的变化,当它看到它设置为 true 时,它​​会打开模式。最后,当模式关闭时,$emit('close')父级正在监视的子级,以及当它看到它设置时showChildModal = false

Vue.component('child', {
  template: '#child',
  props: ['showModal'],
  name: 'child',
  watch: {
    showModal: function(show) {
      if (show) {
        window.setTimeout(() => {
          if (window.confirm("Hi, I'm the child modal")) {
            this.$emit('close');
          } else {
            this.$emit('close');
          }
        }, 100)
      }
    }
  }
})

var vm = new Vue({
  el: '#el',
  data() {
    return {
      showChildModal: false
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="el">
  Parent
  <p>
    <button @click="showChildModal = true">Click to show child modal</button>
  </p>
  <hr>
  <p>
    <child :show-modal="showChildModal" v-on:close="showChildModal = false"> </child>
  </p>
</div>

<script type="x-template" id="child">
  <div>
    Child
    <p>
      modal open? {{ showModal }}
    </p>
  </div>
</script>
Run Code Online (Sandbox Code Playgroud)