五、Vue3.x+Element Plus项目Demo引入自定义组件并实现祖孙/父子组件响应式传参
原创大约 3 分钟约 1024 字
前言
学习 Vite 和 Vue3 并搭建项目 Demo,主要目的是搭项目,对于新手直接跟着操作就可以把项目搭起来,借这个机会自己尝试写写博客,希望对大家有帮助。
参考链接
- 自定义组件:vue3.x 中的自定义组件及使用 - 清和时光 - 博客园
- 父子组件传参:vue3.0 笔记二:vue3.0 中 props 父子传值的改动_浩星-CSDN 博客
- 官方文档:Provide / Inject | Vue.js
(一)准备祖孙/父子组件
使用 Element Plus 的抽屉组件,实现父组件按钮控制子组件抽屉打开的功能。
1.祖/父组件 src/components/HelloWorld.vue
<template>
<!-- 打开抽屉 -->
<el-button @click="handleOpenChildrenDrawer" type="success" style="width: 100%; margin: 20px auto">{{ t("button.openDrawer") }}</el-button>
</template>
<script setup>
import { ref } from "vue";
/**
* 自定义组件
*/
const isDrawerOpen = ref(false);
const handleOpenChildrenDrawer = () => {
isDrawerOpen.value = true;
};
</script>
2.孙/子组件 src/components/SideDrawer.vue
<template>
<el-drawer v-model="drawer" :before-close="handleClose" title="I am the title" direction="rtl">
<span>Hi, there!</span>
</el-drawer>
</template>
<script setup>
import { ref } from "vue";
const drawer = ref(true);
const handleClose = (done) => {
ElMessage("Drawer closed.");
done();
};
</script>
(二)祖/父组件中引入孙/子组件
<script>
写法
1.普通 1)引入组件
import SideDrawer from "./SideDrawer.vue";
2)挂载组件
export default defineComponent({
components: {
SideDrawer,
"v-sidedrawer": SideDrawer,
"side-drawer": SideDrawer,
},
setup() {},
});
有三种写法:
- 直接挂载:
SideDrawer
- 使用别名:
"v-sidedrawer": SideDrawer
- 横杠连接:
"side-drawer": SideDrawer
3)展示组件
<template>
<SideDrawer></SideDrawer>
<v-sidedrawer></v-sidedrawer>
<side-drawer></side-drawer>
</template>
有三种写法,分别对应三种挂载的不同写法:
- 直接挂载:
<SideDrawer></SideDrawer>
- 使用别名:
<v-sidedrawer></v-sidedrawer>
- 横杠连接:
<side-drawer></side-drawer>
<script setup>
语法糖
2.使用 <template>
<SideDrawer></SideDrawer>
</template>
<script setup>
import SideDrawer from "./SideDrawer.vue";
</script>
直接 import
引入即可在模板中使用,无需挂载。
(三)祖孙/父子组件响应式传参
provide
传递参数
1.使用 - 通常父子组件间传参直接使用
prop
最简便,也可使用provide/inject
。 - 祖孙组件间使用
provide/inject
传参。 provide/inject
本身传递数据是不具有响应性的。- 当
provide
传递的数据是ref
或reactive
对象时,子组件inject
的数据才具有响应性。 - 即当祖/父组件修改该数据时,孙/子组件才会接收到修改后的数据。
- 当
import { onMounted, ref, provide } from "vue";
// 提供响应式的值
provide("isDrawerOpen", isDrawerOpen);
inject
接收参数
2.使用 import { inject } from "vue";
// 注入一个值,若为空则使用提供的默认值
const drawer = inject("isDrawerOpen", false);
(四)相关知识点总结
- 官方文档:依赖注入
注意
provide/inject 只能在 setup() 中使用,使用前需要从 vue 中 import 进来。
- provide 函数有两个参数:
- name ( 类型)
- value
- inject 函数有两个参数:
- 要 inject 的 property 的 name
- 默认值 (可选)
1.调用 provide 函数,将值传给自定义组件(子组件)
provide('数据名称', 要传递的数据)
provide("location", "North Pole");
provide("geolocation", {
longitude: 90,
latitude: 135,
});
2.调用 inject 函数,通过指定的数据名称获取到父组件共享的数据
const customVal = inject("customVal")
const userLocation = inject("location", "The Universe");
const userGeolocation = inject("geolocation");
return {
userLocation,
userGeolocation,
};
3.使传递的数据响应式更新
为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 或 reactive。
const location = ref("North Pole");
const geolocation = reactive({
longitude: 90,
latitude: 135,
});
provide("location", location);
provide("geolocation", geolocation);
4.同组件中,数据 A 的值挂靠在数据 B 的更新上
使用 vue 提供的计算属性 computed
,Vue 知道数据 B 依赖于数据 A,所以当数据 A 更新时,数据 B 也会更新。