Vue 组件之间的通信
wyx 4/9/2022 vue
# props / $emit
适用于父子组件通信
- 父组件向子组件传参:prop
- 子组件向父组件传递数据:$emit
# ref
$parent / $children(vue3废弃)
适用于父子组件通信
ref
:可以作用在子组件上、引用就指向组件实例$parent / $children
访问父组件的属性或方法 / 访问子组件的属性或方法
# EventBus ($emit / $on)适用于父子、隔代、兄弟组件通信
- 这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件
- 自己封装的EventBus类
class EventBus{
constructor() {
this.eventList = {};
};
on (name,fn) {
if(this.eventList[name]){
this.eventList[name].push(fn);
} else {
this.eventList[name] = [fn];
}
};
off(name,fn){
if (arguments.length === 1) {
if(this.eventList[name]){
delete this.eventList[name];
}
} else {
let tasks = this.eventList[name];
let index = tasks.findIndex(ele=>ele===fn);
if(index >= 0){
tasks.splice(index,1);
}
}
};
emit(name,...args){
if(this.eventList[name]){
let tasks = this.eventList[name];
tasks.forEach(fn=>{
fn(...args);
})
}
};
}
let eventBus = new EventBus();
let fn1 = (val,val2)=>{
console.log(`fn1函数${val}${val2}`);
};
let fn2 = (val)=>{
console.log(`fn2函数${val}`);
};
eventBus.on('add',fn1);
eventBus.on('add',fn2);
eventBus.off('add',fn2);
eventBus.emit('add','111','222');
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
38
39
40
41
42
43
44
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
38
39
40
41
42
43
44
# $attrs / $listeners(vue3废弃) 适用于隔代组件通信
$attrs
用于父组件隔代向孙组件传值- 用在子组件中,子组件的$attrs中包含了所有除了本组件props之外的父组件属性。
- 孙组件可以获取到未被子组件props接收的属性
// 在子组件中 <grand-child v-bind="$attr"/> // 在孙组件中 props: { name: { type: String } }
1
2
3
4
5
6
7
8$listeners
用于孙组件隔代向父组件传值- 子组件作为父组件和孙组件的传递中介,在儿子组件中给孙子组件添加v-on="$listeners",这样父组件才能接收到孙组件的数据
// 父组件中 <child @changeData="changeMyData"></child> // 子组件中 <grand-child v-on="$listeners"></grand-child> // 孙组件中 methods: { edit() { // 发送事件 this.$emit("changeData", this.data1); } }
1
2
3
4
5
6
7
8
9
10
11
# provide / inject
适用于隔代组件通信
祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系
# $root
适用于隔代组件通信
访问跟组件中的属性和方法,只对根组件有用
# Vuex
适用于隔代组件通信
- Vue的状态管理工具
- Vuex的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。
# 总结
- 父子组件:props/$emit/$parent/ref
- 兄弟组件:$parent/eventbus/vuex
- 跨层级关系:eventbus/vuex/provide+inject/$attrs + $listeners/$root