一:前言
在前端项目中牵扯的最多的莫过于组件之间的传值了,除了最最常用的 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.valuecheck2.value = falsecheck3.value = falsecolor.value = 'pink'} else if (index == 2) {if (!check1.value && check2.value && !check3.value) {return}check1.value = falsecheck2.value = !check2.valuecheck3.value = falsecolor.value = 'red'} else if (index == 3) {if (!check1.value && !check2.value && check3.value) {return}check1.value = falsecheck2.value = falsecheck3.value = !check3.valuecolor.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