首页 文章

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

提问于
浏览
6

围绕这个主题似乎有很多讨论,例如Stackoverflow answer using hubStackoverflow answer using refs,所以我真的想请专家一次提供一个清晰简洁的答案 . 如果答案也是不可能的,请说明!

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

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

要实现的目标是什么?

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

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

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

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

我自己的想法

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

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

methods: {
  generateCharts: function () {
    this.$emit('generate-charts')
    console.log('charts generated')
}

在子组件我有:

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

更新

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

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

我可以想象必须有一个原因,为什么Vue无法做到这一点,这可能是一个设计考虑因素,Vue专家解释了为什么会出现这种情况,以及什么是更好的设计方法来解决一般情况下从父母传递事件的方案对孩子,将非常感激 .

1 回答

  • 1

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

    例如,一个模态 . 您的父级单击按钮设置 showChildModal = 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
        }
      }
    })
    
    <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>
    

相关问题