Vue3:provide-inject实现组件通信

目录

一.作用

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>




    

五.效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值