通过前面的学习,对于Vue中组件的数据交流有了一定的了解。实际上在Vue中不同场景之下组件之间的数据通讯是不一样的,在业务中常见的组件通讯的场景主要有父子组件之间的通讯、兄弟组件间的通讯和全局组件的通讯等三种。只不过全局组件的通讯不是我们这章要阐述的范围,他涉及到Vuex。接下来分别看看父子组件和兄弟组件之间的通讯方式和实现方法。
父子组件间的数据通讯
父子组件间的数据通讯可以分为:父组件传递数据给子组件和子组件传递数据给父组件两种。
在《组件数据传递》一文中我们知道了,在Vue中,父组件传递数据给子组件时,可以通过props
来完成。
上图简单的描述了,在Vue中父组件的数据通过props
传递给子组件。具体示例如下:
子组件传递数据给父组件有两种方式:回调参数和自定义事件。先来看回调函数的方式,如图:
简单的看一个小示例:
<div id="app">
<h3>{{ parentComponentName }}</h3>
<child :change-parent-component-name = "changeParentComponentName"></child>
</div>
<template id="child">
<div>
<button @click = "() => changeParentComponentName(newComponentName)">点击我</button>
</div>
</template>
let parent = new Vue({
el: '#app',
data () {
return {
parentComponentName: 'w3cplus'
}
},
methods: {
changeParentComponentName: function (newComponentName) {
this.parentComponentName = newComponentName
}
},
components: {
'child': {
template: '#child',
data () {
return {
newComponentName: '大漠'
}
},
props: {
changeParentComponentName: {
type: Function,
default: () => { }
}
}
}
}
})
上面的示例父组件通过props
给子组件传递了一个changeParentComponentName
函数,然后在子组件调用这个函数的时候,以参数的形式传递一个子组件内部的newComponentName
数据给这个函数。这样在父组件中定义的函数changeParentComponentName
就可以取得子组件传来的newComponentName
参数。
当你点击蓝色按钮(子组件)时,父组件的名称就会由“w3cplus”换成“大漠”:
除了回调函数的方式之外,还有类似于在《实现组件数据的双向绑定》一文中介绍的方式,即自定义事件。
把上面回调函数的示例修改成自定义事件的方法:
<div id="app">
<h3>{{ parentComponentName }}</h3>
<child v-on:change-parent-component-name = "changeParentComponentName"></child>
</div>
<template id="child">
<div>
<button @click="clickCallback">点击我</button>
</div>
</template>
let parent = new Vue({
el: '#app',
data () {
return {
parentComponentName: 'W3cplus'
}
},
methods: {
changeParentComponentName: function (componentName) {
this.parentComponentName = componentName
}
},
components: {
'child': {
template: '#child',
data () {
return {
parentComponentName: '大漠'
}
},
methods: {
clickCallback: function () {
this.$emit('change-parent-component-name', this.parentComponentName)
}
}
}
}
})
上面的代码在子组件中通过$emit(event,[...options])
自定义了一个change-parent-component-name
事件,所有的参数据将被传递给监听器回调,也就是在父组件中通过methods
定义的changeParentComponentName
方法,从而实现从子组件中给父组件传参。
最终得到的效果和回调函数的方式是一样的。
兄弟组件间的数据通讯
上面我们展示的是父子组件间的数据通讯。但在具体的业务,总是难免会碰到兄弟组件间的数据通讯。比如firstChild
和secondChild
两个组件都是parent
组件的子组件,而且firstChild
和secondChild
两个组件间存在数据通讯。打个比方来说,点击secondChild
组件的按钮来改变firstChild
组件的名称。这样的一个效果如何实现,看代码吧。
<template id="child1">
<div>
<h3>{{ firstChildComponentName }}</h3>
</div>
</template>
<template id="child2">
<div>
<button @click="changeFirstChildComponentName">点击我</button>
</div>
</template>
<div id="app">
<h2>{{ parentComponentName }}</h2>
<first-child :first-child-component-name="firstChildComponentName"></first-child>
<second-child :change-first-child-component-name="changeFirstChildComponentName"></second-child>
</div>
let app = new Vue({
el: '#app',
data () {
return {
parentComponentName: 'W3cplus',
firstChildComponentName: '大漠'
}
},
methods: {
changeFirstChildComponentName: function () {
this.firstChildComponentName = 'Airen'
}
},
components: {
'firstChild': {
template: '#child1',
props: {
firstChildComponentName: {
type: String,
default: ''
}
}
},
'secondChild': {
template: '#child2',
props: {
changeFirstChildComponentName: {
type: Function,
default: () => {}
}
}
}
}
})
效果如下:
这个时候点击secondChild
的按钮时,firstChild
组件的名称会从“大漠”变成“Airen”。
secondChild
通过调用函数来修改firstChild
的数据。其原理是:寻找其共同的父组件,使用数据和相关方法“提升”到父组件内部,并向下传给两个子组件。其中一个子组件取得数据,另一个子组件取得了改变数据的方法。
总结
通过《组件数据传递》、《实现组件数据的双向绑定》和今天这篇文章的学习。简单的了解了Vue中的组件数据通讯方式:
- 通过
props
从父组件向子组件传递数据,实现父组件传递数据给子组件 - 通过回调函数和自定义事件从子组件向父组件传递数据,实现子组件传递数据给父组件
再次验证:父子组件的关系总结为:prop
向下传递,事件向上传递。
对于兄弟组件间的数据通讯,它们将会寻找其共同的父组件,使用数据和相关方法“提升”到父组件内部,并向下传给两个子组件。其中一个子组件取得数据,另一个子组件取得了改变数据的方法。
如需转载,烦请注明出处:https://www.w3cplus.com/vue/component-data-and-props-part3.html