一、组件通信的概念

组件通信是指组件与组件之间数据传递和交互的方式。在 Vue 中,组件之间的通信是非常重要的概念,因为一个应用往往由多个组件构成,它们之间需要相互配合才能完成特定的功能。

二、通信方式

1. props / $emit

父组件通过 props 向子组件传递数据,子组件通过 $emit 向父组件发送事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!-- 父组件 -->
<template>
<child :msg="message" @changeMsg="handleChange"/>
</template>

<script>
export default {
data() {
return {
message: 'Hello'
}
},
methods: {
handleChange(val) {
this.message = val
}
}
}
</script>

<!-- 子组件 -->
<template>
<div>
<button @click="handleClick">修改</button>
</div>
</template>

<script>
export default {
props: ['msg'],
methods: {
handleClick() {
this.$emit('changeMsg', 'World')
}
}
}
</script>

2. $refs / $parent / $children

通过 ref 获取子组件实例,直接调用子组件的方法或访问数据

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 父组件 -->
<template>
<child ref="childComp"/>
</template>

<script>
export default {
mounted() {
// 访问子组件的数据和方法
this.$refs.childComp.someMethod()
}
}
</script>

3. EventBus

通过一个空的 Vue 实例作为中央事件总线,实现任意组件间的通信

1
2
3
4
5
6
7
8
9
10
11
// eventBus.js
import Vue from 'vue'
export const EventBus = new Vue()

// 组件 A
EventBus.$emit('custom-event', data)

// 组件 B
EventBus.$on('custom-event', data => {
console.log(data)
})

4. Vuex

状态管理模式,集中式存储管理应用的所有组件的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})

// 组件中使用
this.$store.state.count
this.$store.commit('increment')

三、各种通信方式的使用场景

  1. props / $emit

    • 适用于父子组件通信
    • 简单且清晰的数据流向
  2. $refs / $parent / $children

    • 适用于父子组件通信
    • 需要直接操作子组件时使用
  3. EventBus

    • 适用于任意组件间通信
    • 项目较小时使用
    • 数据流混乱时不易维护
  4. Vuex

    • 适用于复杂的数据管理
    • 大型项目推荐使用
    • 需要共享的状态较多时

四、注意事项

  1. 避免过度使用全局事件总线
  2. 合理使用 Vuex,不是所有状态都需要放在 Vuex 中
  3. 优先考虑 props / $emit 这种最简单的通信方式
  4. 组件通信遵循单向数据流原则

参考文献