目录
一.作用
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 = value
    car.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>
    五.效果




















