我有两个Vue组件:
Vue.component('A', {});
Vue.component('B', {});
如何从组件B访问组件A?组件之间的通信如何工作?
答案 0 :(得分:31)
跨组件通信在Vue.js文档中没有得到太多关注,也没有很多教程涵盖这个主题。由于组件应该是隔离的,因此不应直接“访问”组件。这会将组件紧密地耦合在一起,这正是您想要阻止的。
Javascript有一个很好的沟通方式:事件。 Vue.js有一个内置的事件系统,主要用于父子通信。 From the docs:
虽然您可以直接访问Vue实例的子节点和父节点,但使用内置事件系统进行跨组件通信会更方便。它还使您的代码更少耦合,更易于维护。建立父子关系后,您可以使用每个组件的事件实例方法分派和触发事件。
他们的示例代码用于说明事件系统:
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撰写了一篇关于跨组件消息“斗争”的文章。如果您需要在没有父子关系的组件之间进行通信,这可能对您有所帮助。
我遇到的另一种方法(除了使用事件进行通信)是使用中央组件注册表,该注册表引用了公共API,并绑定了一个组件实例。注册表处理组件请求并返回其公共API。
在Vue.js的背景下,事件将通过我选择的武器。
答案 1 :(得分:11)
除了pesla&#39;回答一下指南State Management section under Building large scale apps:http://vuejs.org/guide/application.html#State_Management。我已根据此处jsfiddle创建了https://jsfiddle.net/WarwickGrigg/xmpLg92c/。
此技术也适用于组件:父子,兄弟 - 兄弟组件关系等。
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
}
})
答案 2 :(得分:6)
也可以通过在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.。
答案 3 :(得分:3)
使用props
和events
的最佳做法。
网上有很多例子,例如:
我建议阅读一些主题。
如果组件是兄弟姐妹并且没有父子关系,则可能值得检查应用程序的体系结构。
A
和B
是否有父子关系?C
是否可能是A
和B
的父级?如果A
和B
是C
的孩子,请考虑使用道具和活动。
另一种方法是使用props
和sync
,这对表单数据很有用:
答案 4 :(得分:0)
对于同级通信,我发现使用父级作为事件总线使逻辑相当琐碎。使用$root
作为事件总线意味着需要附加代码来检查可能不是直接兄弟姐妹的组件的范围。使用$parent
意味着可以控制所发出事件的范围。
以下示例适用于TableHeader
组件。单击后,它将对表中的数据重新排序,其他标题将不再处于活动状态,因此不应如此显示,为此将使用计算属性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)
}
}
答案 5 :(得分:0)
在两个Vuejs组件之间进行通讯有很多选项。如果您的组件是父级和子级,则应使用“ props”将数据从父级发送到子级,并使用“事件”在子级之间进行通信。如果您的组件处于同级状态,则需要使用“ store”,否则可以使用“ $ root”属性。
对孩子的父母
父组件
<ChildComponent :propsData="dataToPassToChild" />
子组件必须具有属性
props: ['propsData']
子女为父母
子组件
this.$emit('messegeToParent', arg1, arg2, ...);
父组件
<ChildComponent @messageToParent="messageReceivedFromChild" />
下面的方法应该在子组件中
messageReceivedFromChild(arg1, arg2, ...) {
}
同级组件
组件1
this.$root.$emit('message1', arg1, arg2, ...);
组件2
this.$root.$on('message1', (arg1, arg2, ...) => {
});