组件通信是组件之间交换数据和信息的过程,以实现功能上的协同和数据的共享。
1. props/$emit
父传子:在父组件中定义属性,并将属性值传入子组件,子组件通过props获取父组件传递的数据。
子传父:子组件中通过 $emit 触发父组件的自定义事件,并传入数据。在父组件中调用子组件的位置设置自定义事件,并定义事件处理函数以接收子组件传递的数据。
2. ref/$refs
ref 和 $refs 并不是专门用于组件通信的机制,但它们确实提供了一种访问子组件实例或 DOM 元素的方式。
将ref绑定在组件调用的地方,可以通过实例来访问组件的数据和方法(this.$ref.xxx.fn())
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="sayHello">Hello from Child</button>
</div>
</template>
<script>
export default {
methods: {
sayHello() {
console.log('Hello from Child Component!');
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">Call Child Method</button>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
callChildMethod() {
this.$refs.childRef.sayHello(); // 直接调用子组件的方法
}
}
}
</script>
在上面的例子中,我们通过 ref 属性在父组件中注册了子组件的引用,并在父组件的方法中通过 this.$refs.childRef 访问了子组件的实例,并调用了其方法。
3. provide/inject
provide/inject允许一个祖先组件向其所有子孙后代提供一个依赖,在层数很深的情况下也可以使用这种方式,只要在其上下文作用链中就可以注入这个依赖,provide和inject与data和methods是同级的。
provide钩子用来发送数据或方法
inject钩子用来接受数据或方法
依赖注入所提供的属性是非响应式的
//父组件
provide() {
return { num: this.num };
}
//子组件
inject: ['num']
//这种写法可以访问父组件中的所有属性
provide() {
return { app: this };
}
data() {
return { num: 1 };
}
inject: ['app']
console.log(this.app.num)
4. $parent& children
使用$parent可以让组件访问父组件的实例(对象)(只可访问上一级组件的属性和方法)
可以使用$root来访问根组件的实例
在根组件上使用$parent拿到的是new Vue()的实例,在此实例上再拿$parent得到undefined,而在最底层的子组件上拿$children是个空数组
使用$children可以让组件访问子组件的实例,但是不保证顺序(数组)切数据不是响应式的
5. $attrs& listeners
$attrs 和 $listeners 是两个特殊的实例属性,它们主要用于组件之间的属性(attribute)和事件(event)的传递。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部子组件——在创建更高层次的组件时非常有用。
$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
这两个属性在创建可复用的组件时特别有用,特别是当你想要创建一个“包装器”或“高阶”组件时,它可以接受任何属性或事件,并将其传递给其子组件,而不需要明确知道这些属性或事件是什么。这增加了组件的灵活性和可重用性。
<template>
<div>
<child-component v-on="$listeners"></child-component>
</div>
</template>
<script>
export default {
// ...
}
</script>
在这个例子中,任何在父组件上定义的事件监听器(如 @click 或 @my-event),都会通过 $listeners 传递给 child-component。
6. 跨组件通信库(如Vuex)
- Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。