VueJs 2.0 将事件从孙子发送到他的祖父组件

新手上路,请多包涵

Vue.js 2.0 似乎不会将事件从孙子发送到他的祖父组件。

 Vue.component('parent', {
  template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
  data(){
    return {
      action: 'No action'
    }
  },
  methods: {
    performAction() { this.action = 'actionDone' }
  }
})

Vue.component('child', {
  template: '<div>I am the child <grand-child></grand-child></div>'
})

Vue.component('grand-child', {
  template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
  methods: {
    doEvent() { this.$emit('eventtriggered') }
  }
})

new Vue({
  el: '#app'
})

这个 JsFiddle 解决了问题 https://jsfiddle.net/y5dvkqbd/4/ ,但是通过 emtting 两个事件:

  • 一个从孙子到中间组件
  • 然后再次从中间组件发射到祖父母

添加这个中间事件似乎是重复的和不必要的。有没有办法直接发射给我不知道的祖父母?

原文由 BassMHL 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 483
2 个回答

新答案(2018 年 11 月更新)

我发现我们实际上可以通过利用大子组件中的 $parent 属性来做到这一点:

 this.$parent.$emit("submit", {somekey: somevalue})

更干净,更简单。

原文由 BassMHL 发布,翻译遵循 CC BY-SA 4.0 许可协议

Vue 2.4 引入了一种使用 vm.$listeners 轻松将事件向上传递的方法

来自 https://v2.vuejs.org/v2/api/#vm-listeners

包含父范围 v-on 事件侦听器(没有 .native 修饰符)。这可以通过 v-on="$listeners" 传递给内部组件 - 在创建透明包装组件时很有用。

child 模板中的 grand-child 组件中使用 v-on="$listeners" 参见下面的片段:

 Vue.component('parent', {
  template:
    '<div>' +
      '<p>I am the parent. The value is {{displayValue}}.</p>' +
      '<child @toggle-value="toggleValue"></child>' +
    '</div>',
  data() {
    return {
      value: false
    }
  },
  methods: {
    toggleValue() { this.value = !this.value }
  },
  computed: {
    displayValue() {
      return (this.value ? "ON" : "OFF")
    }
  }
})

Vue.component('child', {
  template:
    '<div class="child">' +
      '<p>I am the child. I\'m just a wrapper providing some UI.</p>' +
      '<grand-child v-on="$listeners"></grand-child>' +
    '</div>'
})

Vue.component('grand-child', {
  template:
    '<div class="child">' +
      '<p>I am the grand-child: ' +
        '<button @click="emitToggleEvent">Toggle the value</button>' +
      '</p>' +
    '</div>',
  methods: {
    emitToggleEvent() { this.$emit('toggle-value') }
  }
})

new Vue({
  el: '#app'
})
 .child {
  padding: 10px;
  border: 1px solid #ddd;
  background: #f0f0f0
}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <parent></parent>
</div>

原文由 Michael Rush 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题