组件间通信方式有哪些
Youky ... 2021-8-30 About 2 min
# 组件间通信方式有哪些
# 1. 最常用方式,props:父子组件
- 父组件用
props
向子组件传值 - 子组件用
$emit
触发自定义事件,向父组件传值
# 2. 通过 ref、$parent
、$children
:父子组件
ref
用来便捷的访问某个节点或是自定义组件。
ref 只会在组件渲染完成后生效,并且不是响应式的
- 用在 DOM 节点上时和 ID 类似
- 用在组件上时获取的是这个 Vue 实例
- ref 与 v-for 一起使用时,得到的是包含了所有子组件的数组
<myCom ref="myInput" />
1
// 获取这个组件,类似于获得了它的this指针
this.$refs.myInput;
1
2
2
$parent
用于获得组件的父组件,可以获取其数据或调用其方法。
$children
用于获得组件的子组件。在 vue3 中已移除,需要时用 ref 作为代替
# 3. 依赖注入:隔代组件
使用方法:
- 在父组件使用
provide
属性,向所有子组件(不只是直接子组件,包括深层嵌套的子组件)提供值 - 在子组件中用 inject 属性进行接收
缺点:
- 是非响应式的。
- 使组件和组织方式耦合起来,不利于重构
// 父组件
{
// ...
provide(){
return{
name: this.name
}
}
}
// 所有子组件或子组件的子组件中都可以接收:
{
inject:['name']
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
如何解决非响应式的问题?
- 传递一个函数或是直接传递
this
provide() { return { parent: this } }
1
provide() {
return {
parentName: () => this.name
}
}
1
2
3
4
5
2
3
4
5
- Vue3 中使用 computed 包裹传递内容
import { computed } from "vue";
export default {
data() {
return {
message: "hello!",
};
},
provide() {
return {
// 显式提供一个计算属性
message: computed(() => this.message),
};
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4. $attrs/$listeners:隔代组件
$attrs
:包含了父组件传递了但没有在 props 中进行接收的 props(class 和 style 除外)
<children v-bind="$attrs"></children>
1
$listeners
:包含了父级作用域中的 v-on 监听器
<children v-on="$listeners"></children>
1
# 5. 总线模式/发布订阅模式:全局可用,低配版 Vuex
- 用一个空的 Vue 实例作为中心事件总线,用它来监听和触发事件,从而实现组件间通信。
// $bus为事件总线的名称,自己随意定义
Vue.prototype.$bus = new Vue();
new Vue({}).$mount("#app");
1
2
3
4
2
3
4
- 在需要传递信息的地方触发自定义事件
this.$bus.$emit("事件名", "事件参数");
1
- 在需要接收的地方监听事件
this.$bus.$on("事件名", (arg) => {});
1
总线模式的缺点:
- vue 是 SPA,在某个页面刷新后,与之相关的 eventbus 会被移除
- 不利于组件化开发