【Vue.js 3.0】Day-17 Composition API 依赖注入provide & inject

Provide / Inject

  • 当我们需要从父组件向子组件传递数据时,我们使用 props可以实现! 
  • 想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 props 沿着组件链逐级传递下去,可能会很麻烦。
  • provide 可以在祖先组件中指定我们想要提供给后代组件的数据或方法,而在任何后代组件中,我们都可以使用 inject 来接收 provide 提供的数据或方法。 
  • Provide / Inject 在vue 中主要是依靠原型链去实现的! (通过原型链逐级向上查找变量)
  • 使用场景:当父组件有很多数据需要分发给其子代组件的时候, 就可以使用provide和inject。

TIPS 你如果传递普通的值是不具有响应式的、需要通过ref reactive 添加响应式

eg: 点击单选按钮,共享颜色背景 

App.vue

<template>
  <h1>App.vue(爷爷组件)</h1>
  <label>
    <input v-model="colorVal" type="radio" value="red" name="color" />红色
  </label>
  <label>
    <input v-model="colorVal" type="radio" value="pink" name="color" />粉色
  </label>
  <label>
    <input v-model="colorVal" type="radio" value="yellow" name="color" />黄色
  </label>
  <!-- 盒子容器 -->
  <div class="box"></div>
  <hr />
  <provide-a />
</template>

<script setup>
import { ref, provide, readonly } from "vue";
import ProvideA from "./components/ProvideA.vue";
const colorVal = ref("red");
// 提供一个数据: 颜色值
provide("color",readonly(colorVal));
</script>

<style>
.box {
  height: 50px;
  width: 50px;
  border: 1px solid #ccc;
  /* 绑定 setup 中的变量 */
  background: v-bind(colorVal);
}
</style>

src/components/ProvideA.vue

<template>
  <h1>ProvideA.vue(父级组件)</h1>
  <div class="box"></div>
  <hr />
  <provide-b />
</template>

<script setup>
import { inject } from "vue";
import ProvideB from './ProvideB.vue'
// 通过 inject 注入读取共享数据
let color = inject("color");
</script>

<style scoped>
.box {
  width: 50px;
  height: 50px;
  border: 1px solid #ccc;
  /* 绑定 setup 中的变量 */
  background: v-bind(color);
}
</style>

src/components/ProvideB.vue

<template>
  <h1>ProvideB.vue(子孙组件)</h1>
  <div class="box"></div>
  <hr />
  <!-- 修改 provide 共享的数据 -->
  <div>
    <button @click="setColorHandle">修改 provide的值 green</button>
  </div>
</template>

<script setup>
import { inject, ref } from "vue";
// 通过 inject 注入读取共享数据
let color = inject("color");

// provide共享的数据、是可以修改的;(注意: 但不想让子组件修改数据, 可以在源数据中设置readonly! ) 
const setColorHandle = () =>{
    color.value = 'yellow'
}

</script>

<style scoped>
.box {
  width: 50px;
  height: 50px;
  border: 1px solid #ccc;
  /* 定义 setup中的变量 */
  background: v-bind(color);
}
</style>

 实现效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值