一:前言
在前端项目中牵扯的最多的莫过于组件之间的传值了,除了最最常用的 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全家桶练习https://gitee.com/qianchen12138/vue3-family-bucket-practice