在平时的开发过程中,父子 / 兄弟组件间的通信是肯定会遇到的啦,所以这里总结了 6 种 Vue 组件的通信方式:
1. props / $emit
2. $emit / $on
3. Vuex
4. $attrs / $listeners
5. $parent / $children 与 ref
6. provide / inject
前言
如上图所示,A/B,B/C,B/D组件是父子关系,C/D是兄弟关系。那如何根据不同的使用场景,选择不同的通信方式呢?所以前提就是我们要了解不同的通信方式的作用和区别。
一. props / $emit
这个是我们平时用得比较多的方式之一,父组件 A 通过 props 参数向子组件 B 传递数据,B 组件通过 e m i t 向 A 组 件 发 送 一 个 事 件 ( 携 带 参 数 数 据 ) , A 组 件 中 监 听 emit向A组件发送一个事件(携带参数数据),A组件中监听 emit向A组件发送一个事件(携带参数数据),A组件中监听emit 触发的事件得到 B 向 A 发送的数据。
我们来具体解释下它的实现步骤:
1:父组件向子组件传值
// App.vue 父组件
<template>
<a-compontent :data-a="dataA"></a-compontent>
</template>
<script>
import aCompontent from './components/A.vue';
export default {
name: 'app',
data () {
return {
dataA: 'dataA数据'
}
}
}
// aCompontent 子组件
<template>
<p>{
{
dataA}}</p> // 在子组件中把父组件传递过来的值显示出来
</template>
<script>
export default {
name: 'aCompontent',
props: {
dataA: {
//这个就是父组件中子标签自定义名字
type: String,
required: true // 或者false
}
}
}
</script>
2:子组件向父组件传值(通过事件方式)
// 子组件
<template>
<p @click="sendDataToParent">点击向父组件传递数据</p>
</template>
<script>
export default {
name: 'child',
methods:{
changeTitle() {
this.$emit('sendDataToParent','这是子组件向父组件传递的数据'); // 自定义事件,会触发父组件的监听事件,并将数据以参数的形式传递
}
}
}
// 父组件
<template>
<child @sendDataToParent="getChildData"></child>
</template>
<script>
import child from './components/child.vue';
export default {
name: 'child',
methods:{
getChildData(data) {
console.log(data); // 这里的得到了子组件的值
}
}
}
</script>
二. $emit / $on
这种方式是通过一个类似 App.vue 的实例作为一个模块的事件中心,用它来触发和监听事件,如果把它放在 App.vue 中,就可以很好的实现任何组件中的通信,但是这种方法在项目比较大的时候不太好维护。
举个 ?:
假设现在有 4 个组件,Home.vue 和 A/B/C 组件,AB 这三个组件是兄弟组件,Home.vue 相当于父组件
// 我们可以在router-view中监听change事件,也可以在mounted方法中监听
// home.vue
<template>
<div>
<child-a />
<child-b />
<child