目录
一.作用
1.跨层级通信
2.避免重复声明
3.封装通用服务
二.性质
1.非响应式
2.不可选项
3.高级用法
三.使用
1.爷组件
2.父组件
3.子组件
四.代码
1.爷组件代码
2.父组件代码
3.子组件代码
五.效果
Vue3中的provide-inject机制是用于在组件树中进行依赖注入的一种方法,它允许父组件向其所有子孙组件提供数据或方法。
一.作用
1.跨层级通信
provide-inject机制使得父组件可以向其所有子孙组件提供数据或方法,无需通过props逐层传递。这简化了组件间的数据流,尤其是在处理深层嵌套的组件结构时。
2.避免重复声明
传统的父子组件传值需要用到props属性,如果组件层级比较复杂,就需要传递多次props属性。而provide-inject机制只需一次声明,就可以在所有子孙组件中使用。
3.封装通用服务
可以将一些通用的逻辑或数据封装在父组件中,并通过provide提供给需要的子孙组件。
二.性质
1.非响应式
provide和inject本身不是响应式的。如果父组件提供的值发生变化,子组件不会自动更新。如果需要响应式的数据传递,可以考虑使用Vuex或其他状态管理库。
2.不可选项
无论父组件是否真的提供了数据,子组件都会尝试注入。如果没有提供对应的provide,则inject的属性将会有一个默认值(如果指定了的话)。
3.高级用法
可以通过provide提供一个函数,而不是直接提供值。子孙组件在获取数据时,可以根据需要动态计算。还可以同时提供多个不同类型的数据。
三.使用
1.爷组件
1.首先,导入了Father组件和Vue 3的一些功能:ref、reactive和provide。
2.定义了一个名为money的响应式引用,初始值为100。
3.定义了一个名为car的响应式对象,包含brand和price属性,初始值分别为'宝马'和30。
4.定义了一个名为updateCar的方法,用于更新car对象的brand和price属性。
5.定义了一个名为updateMoney的方法,用于更新money的值。
6.使用provide函数将money和updateMoney方法提供给子组件,键名为'money'。
7.使用provide函数将car和updateCar方法提供给子组件,键名为'car'。
2.父组件
1.在模板部分,有一个div元素,类名为"father",包含一个标题(h4)显示"父组件",另一个标题显示爷爷的钱(money),以及一个按钮用于修改money的值。
2.导入了Son组件,并在模板中使用了标签来引入该组件。
3.使用inject函数从祖先组件中获取money和updateMoney属性。这里使用了默认值,如果祖先组件没有提供这些属性,那么money的默认值为0,updateMoney的默认值为一个空函数。
3.子组件
1.在模板部分,有一个div元素,类名为"son",包含一个标题(h4)显示"子组件",两个标题分别显示爷爷的存款和车的信息,以及一个按钮用于修改车的信息。
2.导入了inject函数,用于从祖先组件中获取数据和方法。这里使用了默认值,如果祖先组件没有提供这些属性,那么money的默认值为0,car的默认值为0,updateCar的默认值为一个空函数。
3.使用inject函数从祖先组件中获取money和car属性,以及updateCar方法。这样,我们就可以在组件中使用这些变量和方法了。
四.代码
1.爷组件代码
<template><div class="grandfather"><h4>爷组件</h4><h4>存款:{{ money }}</h4><h4>汽车:{{ car }}</h4><Father/></div></template><script setup lang="ts" name="Father">import Father from "./Father.vue";import { ref,reactive,provide } from "vue";// 数据let money = ref(100)let car = reactive({brand:'宝马',price:30})// 更新车辆品牌function updateCar(value:any){car.brand = valuecar.price = 20}function updateMoney(value:number){money.value += value}// 提供数据provide('money',{money,updateMoney})provide('car',{car,updateCar})</script><style scoped>
.grandfather{background-color: green;
}
h4{margin-left: 20px;font-size: 20px;
}
</style>
2.父组件代码
<template><div class="father"><h4>父组件</h4><h4>爷爷的钱:{{ money }}</h4><button @click="updateMoney(5)">修改父亲的钱</button><son/></div>
</template><script setup lang="ts" name="father">import son from "./Son.vue";import { inject } from "vue";let {money,updateMoney} = inject('money',{money:0,updateMoney:(x:number)=>{}})</script><style scoped>
.father{background-color: orange;
}
h4{margin-left: 20px;font-size: 20px;
}
button{margin-left: 20xp;width: 200px;height: 40px;
}</style>
3.子组件代码
<template><div class="son"><h4>子组件</h4><h4>爷爷的存款:{{ money }}</h4><h4>爷爷的车:{{ car }}</h4><button @click="updateCar('奥迪')">修改爷的车</button></div>
</template><script setup lang="ts" name="father">import { inject } from "vue";let {money} = inject('money',{money:0})let {car,updateCar} = inject('car',{car:0,updateCar:(param:any)=>{}})</script><style scoped>
.son{background-color: skyblue;
}
h4{margin-left: 20px;font-size: 20px;
}
button{margin-left: 20xp;width: 200px;height: 40px;
}
</style>