Vue3 的 inject 和 provide (附源码)

一:前言

        在前端项目中牵扯的最多的莫过于组件之间的传值了,除了最最常用的 props 和 emit,其实在 Vue 中还额外提供了另外几种方法。今天分享一种组件之间通信的方法:provide 和 inject。

二:使用

1、目录结构

        以下是项目的目录结构,其中 index.vue 是进入的首页。在这个页面中引入了 son1.vue 组件,在 son1.vue 中引入了 son2.vue 组件。

2、效果

        右侧是我们项目的页面效果,当我们选中不同的颜色时,下面的三个正方形都会同步进行颜色的更改

3、index.vue

        这里的单选框没有使用 element plus ,是我直接自己写的。在下方 CSS 中使用了 vue3 新支持的 v-bind 方式进行动态绑定背景色。而后使用了 provide 提供了一个 color 属性。

<template>
    <div class="home">
        <div class="box" @click.stop="onCheck(1)">
            <input type="checkbox" v-model="check1" /> 粉色
        </div>
        <div class="box" @click="onCheck(2)">
            <input type="checkbox" v-model="check2" /> 红色
        </div>
        <div class="box" @click="onCheck(3)">
            <input type="checkbox" v-model="check3" /> 黄色
        </div>
    </div>
    <div class="col"></div>
    <hr />
    <son1></son1>
</template>

<script lang="ts" setup>
import son1 from './components/son1.vue'
let color = ref('red')
provide('color', color)

let check1 = ref(false)
let check2 = ref(true)
let check3 = ref(false)

const onCheck = (index: number) => {
    if (index == 1) {
        if (check1.value && !check2.value && !check3.value) {
            return
        }
        check1.value = !check1.value
        check2.value = false
        check3.value = false
        color.value = 'pink'
    } else if (index == 2) {
        if (!check1.value && check2.value && !check3.value) {
            return
        }
        check1.value = false
        check2.value = !check2.value
        check3.value = false
        color.value = 'red'
    } else if (index == 3) {
        if (!check1.value && !check2.value && check3.value) {
            return
        }
        check1.value = false
        check2.value = false
        check3.value = !check3.value
        color.value = 'yellow'
    }
}
</script>

<style lang="scss" scoped>
.home {
    display: flex;
}

.box {
    margin-right: 10px;
    cursor: pointer;
}

.col {
    margin: 10px 0;
    width: 100px;
    height: 100px;
    background: v-bind(color);
}
</style>

4、son1.vue

        在这个页面中,我们引入了 son2.vue 组件,并且创建了一个背景色,动态绑定为注入的 color 属性。

<template>
    <h1>son1 组件</h1>
    <div class="col"></div>
    <hr />
    <son2></son2>
</template>

<script setup>
import son2 from './son2.vue'
let color = inject('color')
</script>

<style lang="scss" scoped>
.col {
    margin: 10px 0;
    width: 100px;
    height: 100px;
    background: v-bind(color);
}
</style>

5、son2.vue

        这个组件和 son1.vue 的逻辑是相同的。不同之处在于我们在这个组件中写了一个小问题。

        在使用 inject 的时候,我们在子组件中修改值,别的组件中会同步修改,在某些情况下这显然是不合理的。因此我们写了一个 button 按钮进行测试,发现确实是有影响。解决办法也很简单,在使用 inject 的时候使用 readonly 标记一下就好了,再次点击 button 按钮是不生效的。

<template>
    <h1>son2 组件</h1>
    <button @click="color='blue'">to blue</button> PS.readonly不允许修改
    <div class="col"></div>
</template>

<script setup>
import { readonly } from 'vue';

let color =readonly(inject('color'))
</script>

<style lang="scss" scoped>
.col {
    margin: 10px 0;
    width: 100px;
    height: 100px;
    background: v-bind(color);
}
</style>

三:总结

        provide 和 inject 是适用于多层传值比较方便的一种方式之一。熟练地使用这个知识,可以让我们在日常开发中提高代码效率和可读性。不过也有很多需要注意的地方,这些各位小伙伴在写的时候会逐步发现。这里我只写了基本使用。

        好啦以上就是本文的全部内容啦,最后附上我学习这些知识点时写的练习项目,里面包含各种知识点,有需要的小伙伴可以自己拉取哦。

乾辰/vue3全家桶练习icon-default.png?t=N7T8https://gitee.com/qianchen12138/vue3-family-bucket-practice

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴怒的代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值