Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间

2020-06-13 10:28:28易采站长站整理

}
}

父组件定义 colored 状态


<template>
<div>
<div @click="handleClick" :style="{color}">
{{msg.id}} - {{msg.data}} ⭕
</div>
</div>
</template>

子组件渲染 msg 并监听 click 事件


export default {
// ...
props: ['msg', 'colored'],
methods: {
handleClick (e) {
this.$parent.$data.colored = !this.$parent.$data.colored
}
}
}

通过 $parent 访问父组件,并修改 $data 状态

非父子组件通信

中央事件总线

我们可以使用使用中央事件总线来处理非父子组件间的通信

具体步骤是创建一个 Vue 实例,然后 $on 监听事件,$emit 来派发事件


// src/eventBus.js

import Vue from 'vue'
export default new Vue()

首先创建并导出一个 Vue 实例


import bus from '@/eventbus'

export default {
// ...
methods: {
handleClick (e) {
bus.$emit('change-color')
}
}
}

后代元素 $emit 触发 eventBus 的事件


import bus from '@/eventbus'

export default {
// ...
mounted () {
bus.$on('change-color', () => {
this.colored = !this.colored
})
}
}

祖先元素 $on 方法监听 eventBus 的事件

provide/inject

适用于祖先和后代关系的组件间的通信,祖先元素通过 provide 提供一个值,后代元素则通过 inject 获取到这个值。这个值默认是非响应的,如果是对象那么则是响应式的:


export default {
name: 'home',
provide () {
return {
colored: this.colored // 依赖于 data
}
},
components: {
MyComp
},
data () {
return {
colored: { // 必须为对象
value: false
},
msgs: [{
// ...

首先通过 provide 对外提供一个 colored,这个属性依赖于 data 中的 colored,该变量必须为一个对象,才是响应式的。

⚠️ 必须为一个对象


methods: {
handleChangeColor () {
this.colored.value = !this.colored.value
}
}

祖先组件监听事件或其他途径去修改 data 改变状态。


export default {
name: 'MyComp',
inject: ['colored'], // inject colored
computed: {
color () {
return this.colored.value ? 'red' : 'black' // do more...
}
},
// ...

后代组件通过 inject 获取到祖先组件提供的对象,根据对象做进一步动作。