Vue组件通信

Vue components communication

我有两个 Vue 组件:

Vue.component('A', {});

Vue.component('B', {});

如何从组件 B 访问组件 A?组件之间的通信如何工作?

Cross-component 通信在 Vue.js 文档中没有得到太多关注,也没有很多教程涵盖这个主题。由于组件应该是隔离的,所以你不应该直接 "access" 一个组件。这会将组件紧密地耦合在一起,而这正是您想要阻止的事情。

Javascript有一个很好的交流方式:事件。 Vue.js有一个built-in事件系统,主要用于parent-child交流。 From the docs:

Although you can directly access a Vue instance’s children and parent, it is more convenient to use the built-in event system for cross-component communication. It also makes your code less coupled and easier to maintain. Once a parent-child relationship is established, you can dispatch and trigger events using each component’s event instance methods.

他们用来说明事件系统的示例代码:

var parent = new Vue({
  template: '<div><child></child></div>',
  created: function () {
    this.$on('child-created', function (child) {
      console.log('new child created: ')
      console.log(child)
    })
  },
  components: {
    child: {
      created: function () {
        this.$dispatch('child-created', this)
      }
    }
  }
}).$mount()

Dan Holloran 最近在 two pieces 中写了一篇关于他的 "struggle" 和 cross-component 消息传递的文章。如果您需要在没有 parent-child 关系的组件之间进行通信,这可能对您有所帮助。

我有经验的另一种方法(除了使用事件进行通信)是使用中央组件注册表,该注册表引用了 public API 以及绑定到的组件实例它。注册表处理对组件的请求和 returns 它的 public API.

在 Vue.js 的背景下,事件将由我选择的武器。

除了 pesla 的回答外,请查看指南的 State Management section under Building large scale apps: http://vuejs.org/guide/application.html#State_Management . I've created a jsfiddle based on that here: https://jsfiddle.net/WarwickGrigg/xmpLg92c/

此技术也适用于组件:parent-child、sibling-sibling 组件关系等

var hub = {
  state: {
    message: 'Hello!'
  }
}

var vmA = new Vue({
    el: '#appA',
    data: {
      pState: {
        dA: "hello A" 
    },
    hubState: hub.state
  }
})

var vmB = new Vue({
    el: '#appB',
    data: {
      pState: {
        dB: "hello B"
    },
    hubState: hub.state
  }
})

还可以通过在 Vue 应用程序中创建一个全局事件中心来建立组件之间的通信。像这样:-

var bus = new Vue();

现在您可以创建自定义事件并从任何组件收听它们。

     // A.vue
    // ...
    doThis() {
        // do the job

        bus.$emit('done-this');
    }

    // B.vue
    // ...
       method:{
             foo: function()
          }
    created() {
        bus.$on('done-this', foo);
    }

有关此内容的更多信息,请参见 from official documentation.

最好使用 propsevents

网上有很多例子,比如:

我建议阅读有关该主题的一些内容。

如果组件是同级组件并且没有 parent-child 关系,则可能值得检查您的应用程序的架构。

  • AB 有 parent child 关系吗?
  • 是否有一个组件 C 可能是 AB 的 parent?

如果AB是children之C,考虑使用道具和事件。 另一种方法是使用propssync,这对表单数据有帮助:

对于兄弟姐妹之间的通信,我发现使用 parent 作为事件总线使得逻辑相当简单。使用 $root 作为事件总线意味着需要额外的代码来检查可能不是直接兄弟的组件的范围。使用 $parent 意味着可以控制发出的事件的范围。

以下示例适用于 TableHeader 组件。单击它时 re-orders table 中的数据,其他 headers 中的数据不再处于活动状态并且不应如此显示,使用计算的 属性 cssClass为此。

export default {
    name: 'TableHeader',
    props: ['sort'],
    data() {
        return {
            direction: this.sort
        }
    },
    computed: {
        cssClass() {
            if (this.direction === 'none') return '';
            return (this.direction === 'descending') ? 'headerSortUp': 'headerSortDown';
        }
    },
    methods: {
        clickHeader(event) {
            this.direction = (this.direction === 'none' || this.direction === 'descending') ? 'ascending' : 'descending';

            //We use the parent as an event bus
            this.$parent.$emit('TableHeader:sortChanged', this);
        },
        sortChanged(element) {
            //Dont reset if this is the emitter         
            if (this === element) return; 

            this.direction = 'none';
        }
    },      
    created() {
        this.$parent.$on('TableHeader:sortChanged', this.sortChanged);
    },
    beforeDestroy: function () {
        this.$parent.$off('TableHeader:sortChanged', this.sortChanged)
    }
}

两个 Vuejs 组件之间的通信有很多选项。如果您的组件是 parent 和 child 那么您应该使用 "props" 将数据从 parent 发送到 child 并使用 "events" 从 child 到 parent。如果您的组件是兄弟组件,那么您需要使用 "store" 否则您可以使用“$root” 属性.

Parent 到 child

parent分量

<ChildComponent :propsData="dataToPassToChild" />

child 组件必须有 属性

props: ['propsData']

Child 至 Parent

child分量

this.$emit('messegeToParent', arg1, arg2, ...);

parent分量

<ChildComponent @messageToParent="messageReceivedFromChild" />

下面的方法应该在child组件

messageReceivedFromChild(arg1, arg2, ...) {

}

同级组件

组件 1

this.$root.$emit('message1', arg1, arg2, ...);

组件 2

this.$root.$on('message1', (arg1, arg2, ...) => {

});