vue.js - VueJS Grandchild 组件调用Great grandparent 组件中的函数

标签 vue.js

假设我有一个子组件想要给曾祖 parent 发送消息,代码将是这样的,如果我错了请纠正我:

Vue.component('child', {
  template: `<div v-on:click="clicked">Click me</div>`,
  methods: {
    clicked: function () {
        this.$emit('clicked', "hello")
    },
  },
});

Vue.component('parent', {
  template: `<child v-on:clicked="clicked"></child>`,
  methods: {
    clicked: function (msg) {
        this.$emit('clicked', msg)
    },
  },
});


Vue.component('grandparent', {
  template: `<parent v-on:clicked="clicked"></parent>`,
  methods: {
    clicked: function (msg) {
        this.$emit('clicked', msg)
    },
  },
});

Vue.component('greatgrandparent', {
  template: `<grandparent v-on:clicked="clicked"></grandparent>`,
  methods: {
    clicked: function (msg) {
        console.log('message from great grandchild: ' + msg);
    },
  },
});

有没有可能直接拦截来自子进程的消息并调用曾祖父进程中的点击函数而不需要在每个父进程中设置传递回调?

我知道我可以使用自定义数据总线,https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication , 但既然我的组件已经有父子关系,我不应该能够以更简单的方式通知祖 parent 吗?

最佳答案

如果你想保持封装就不行。 曾祖 parent 不应该知道 child 。它知道 grandparent,但不知道有子组件或有多少。原则上,您可以将 grandparent 的一个实现换成另一个没有多层的实现。或者有更多层到达 child。您可以将 child 放入顶级组件中。

您已经了解全局事件总线的概念。不过,总线不一定是全局的。您可以将它传递到 Prop 链中。 (您可以使用 曾祖 parent 本身作为公共(public)汽车,但这会使它暴露给它的 child ;更好的卫生条件才能制造一辆真正的公共(public)汽车。)

这将顶级组件与子组件区分开来:子组件将接收一个 bus prop 来执行它帮助实现的顶级组件的功能。顶级组件将发起总线。

Vue.component('child', {
  template: `<div v-on:click="clicked">Click me</div>`,
  props: ['bus'],
  methods: {
    clicked: function() {
      this.bus.$emit('clicked', 'hello');
    },
  },
});

Vue.component('parent', {
  template: `<child :bus="bus"></child>`,
  props: ['bus']
});


Vue.component('grandparent', {
  template: `<parent :bus="bus"></parent>`,
  props: ['bus']
});

Vue.component('greatgrandparent', {
  template: `<grandparent :bus="bus" v-on:clicked="clicked"></grandparent>`,
  data() {
    return {
      bus: new Vue()
    };
  },
  created() {
    this.bus.$on('clicked', this.clicked);
  },
  methods: {
    clicked: function(msg) {
      console.log('message from great grandchild: ' + msg);
    },
  },
});

new Vue({
  el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<greatgrandparent id="app"></greatgrandparent>

关于vue.js - VueJS Grandchild 组件调用Great grandparent 组件中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43254812/

相关文章:

javascript - 原型(prototype)继承的属性在 vue.js 中不是 react 性的?

javascript - Vue + Jest 无法读取未定义的属性 'default'

python - 通过 axios 将数据发送到 django rest 框架时获取错误请求 400

javascript - 如何在附加元素后触发指令事件?

javascript - 获取动态 v 模型以与数据进行比较 - VueJS 和 Vuelidate

javascript - 如何使用 Vue 迭代通过 Ajax 加载的数组?

javascript - 有没有办法将项目传递给 VueJS 中另一个组件的对话框?

javascript - 如何将创建的范围连接到文本区域元素的值?

vue.js - 如何在 vue.js 中通过点击事件发出一个值

javascript - 如何在Vue JS组件中使用全局变量?