【Vuejs】1720- 详细聊一聊 Vue3 动态组件

news/2024/11/9 2:02:31/

5f5ed25fabba673f1cae689efa077e79.jpeg

👉 「相关文章」

  1. 深入浅出 Vue3 自定义指令

  2. 6 个你必须明白 Vue3 的 ref 和 reactive 问题

  3. 初中级前端必须掌握的 10 个 Vue 优化技巧

  4. 分享 15 个 Vue3 全家桶开发的避坑经验

动态组件[1]是 Vue3 中非常重要的一个组件类型,它可以让我们在不同的场景下灵活地渲染不同的组件。

✨ 快速上手

使用动态组件非常简单,我们只需要在模板中使用 <component> 标签,并通过设置组件的is 属性来指定要渲染的组件。例如:

<component :is="currentComponent"></component>

其中,currentComponent 是一个变量,它的值可以是以下 2 种:

  • 已注册的组件名,或 HTML 标签名称

  • 导入的组件对象

下面这张图会更清晰:cbe1a44ffcb5512f79943e70516dbb7c.png

🚀 使用场景

灵活运用 Vue3 的动态组件功能,能够帮助我们满足动态性和灵活性的需求,这里列举几个常见的使用场景:

  1. 「条件渲染」

根据不同条件加载组件,如根据用户权限加载权限组件或根据用户选择加载不同的组件。

  1. 「动态表单」

根据表单类型或步骤动态渲染相关组件,避免加载整个表单,只加载与当前状态相关的部分。

  1. 「模态框和弹出窗口」

通过动态组件实现模态框和弹出窗口内容,根据触发条件或用户操作动态加载相应内容。

  1. 「复用和扩展组件」

使用动态组件轻松复用和扩展现有组件,通过替换动态组件实现不同展现和行为。

  1. 「路由视图切换」

在路由器中使用动态组件实现动态路由视图切换,根据路由路径加载相应组件,实现无缝页面切换。

  1. 「可配置的组件选择」

低代码平台提供可视化界面配置应用程序组件,动态组件用于根据用户配置选择和加载特定组件,快速生成定制化应用程序。

🎬 使用示例

接下来通过 5 个使用示例,帮助大家更好的理解 Vue3 动态组件的使用:

1. 动态组件切换

当我们需要根据不同的条件来渲染不同的组件。这时,我们可以使用 v-ifv-else指令来实现条件渲染。例如:

<component v-if="showComponentA" :is="'ComponentA'"></component>
<component v-else :is="'ComponentB'"></component><!-- 代码简化 -->
<component :is="showComponentA ? 'ComponentA' : 'ComponentB'"></component>

在这个示例中,根据 showComponentA 的值来决定渲染 <ComponentA> 还是 <ComponentB>

2. 动态组件的过渡效果

为了让动态组件的切换更加平滑,我们可以为添加过渡效果(包括入场和离场的过渡动画)。我们可以使用 Vue 内置的 [<transition>](https://vuejs.org/guide/built-ins/transition.html "<transition>") 组件和过渡类名,来实现过渡效果。

<template><div><transition name="fade"><component :is="currentComponent"></component></transition></div>
</template><style>.fade-enter-active,.fade-leave-active {transition: opacity 0.5s;}.fade-enter,.fade-leave-to {opacity: 0;}
</style>

在这个示例中,通过为 <transition> 组件指定name 属性名称为"fade"的过渡类名,我们可以在 CSS 中定义该名称对应的过渡效果,为动态组件添加淡入淡出的过渡效果和持续时间。<transition> 组件动画的触发条件可以是下面任意一种:

  • v-if 所触发的切换

  • v-show 所触发的切换

  • 由特殊元素 <component> 切换的动态组件

  • 改变特殊的 key 属性

3. 动态组件的传递数据

在父组件和动态组件之间传递数据也非常简单,父组件可以通过 v-bind 指令将数据传递给动态组件,例如:

<component :is="currentComponent" :prop1="value1" :prop2="value2"></component>

在这个示例中,通过 :prop1="value1" :prop2="value2"向组件 currentComponent传递了 value1value2的数据。在动态组件中,我们可以使用 defineProps 来接收这些数据,以 <script setup>为例:

<script setup lang="ts">const props = defineProps<{prop1: string;prop2: string;}>();
</script>

4. 使用组件对象作为 is 属性的参数

在实际业务中,我们可能需要根据用户选择的不同选项来展示不同的表单组件。例如,用户可以选择注册类型(个人或企业),然后我们需要显示相应的表单组件。我们需要通过定义 pages 对象,将不同页面类型和组件进行绑定。

<script setup lang="ts">
import { ref, type Component } from "vue";
import Company from "./Company.vue";
import Personal from "./Personal.vue";const pages: Record<string, Component> = {company: Company,personal: Personal,
};
const currentPage = ref<Component>(pages.company);
const changePage = (page: string) => {currentPage.value = pages[page];
};
</script><template><h3><a @click.stop="changePage('company')">Company</a></h3><h3><a @click.stop="changePage('personal')">Personal</a></h3><div style="border: 1px solid #000"><h2>From Content:</h2><component :is="currentPage"></component></div>
</template>

在这个示例代码中,<component :is="currentPage"></component>渲染组件,在切换页面时修改 currentPage,从而实现组件切换,用户通过点击底下 CompanyPersonal切换不同的表单进行显示。

5. 使用组件名作为 is 属性的参数

我们需要将需要使用的组件进行全局注册,然后在 <component :is="currentPage"></component>中使用组件名即可。首先在 main.ts 中使用 app.component(组件名, 组件对象)全局注册组件,全局注册的组件可以在任何组件模版中直接使用:

// main.ts
import { createApp } from "vue";
import Company from "./components/Company.vue";
import Personal from "./components/Personal.vue";import App from "./App.vue";const app = createApp(App);
app.component("demo-company", Company);
app.component("demo-personal", Personal);app.mount("#app");

然后在需要使用动态的组件页面中使用组件即可:

<script setup lang="ts">
import { ref } from "vue";const currentPage = ref<string>("demo-company");
const changePage = (page: string) => {currentPage.value = page;
};
</script><template><h3><a @click.stop="changePage('demo-company')">Company</a></h3><h3><a @click.stop="changePage('demo-personal')">Personal</a></h3><div style="border: 1px solid #000"><h2>Content:</h2><component :is="currentPage"></component></div>
</template>

❓ 常见问题

当使用 Vue3 的动态组件时,下面介绍 5 个常见问题的示例代码和解决方案,并使用 <script setup> 和 TypeScript 语法演示:

1. 组件名的动态更新

<script setup lang="ts">
import { ref } from "vue";const currentPage = ref<string>("demo-company");
const changePage = (page: string) => {currentPage.value = page;
};
</script><template><h3><a @click.stop="changePage('demo-company')">Company</a></h3><h3><a @click.stop="changePage('demo-personal')">Personal</a></h3><div style="border: 1px solid #000"><h2>Content:</h2><component :is="currentPage"></component></div>
</template>

在这个示例中,使用了 ref 来创建响应式数据 currentPage,并且默认值为 "demo-company",当调用 changePage() 方法时,将组件名更新为对应的组件名称,Vue 会自动销毁旧的组件实例并创建新的组件实例。

2. 组件销毁与缓存

<template><keep-alive><component :is="componentName"></component></keep-alive>
</template><script setup lang="ts">
import { ref } from "vue";
const componentName = ref("ComponentA");
</script>

由于组件切换时,被切换的组件会被销毁,因此可以使用 Vue 内置的 [<keep-alive>](https://vuejs.org/guide/built-ins/keep-alive.html "<keep-alive>") 组件包裹动态组件,以实现组件的缓存,避免重复创建和销毁。

3. 组件之间的通信

<template><div><component:is="componentName":data="componentData"@event="handleEvent"></component></div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";const componentName = ref("ComponentA");
const componentData = reactive({});const handleEvent = (data: any) => {// 处理从动态组件触发的事件
};
</script>

通过传递 data 属性和监听 event 事件,实现动态组件与父组件之间的通信。使用 reactive 包裹对象 componentData,使其成为响应式数据。

4. 异步组件加载

当我们不使用全局注册的组件或者提前导入组件时,可以使用异步加载组件的方式实现动态组件的功能。

<template><div><component :is="componentName" v-if="componentLoaded"></component><div v-else>Loading...</div></div>
</template><script setup lang="ts">
import { ref, onMounted } from "vue";const componentName = ref(null);
const componentLoaded = ref(false);onMounted(async () => {// 异步加载组件const module = await import("./ComponentA.vue");componentName.value = module.default;componentLoaded.value = true;
});
</script>

通过 import 异步加载组件,在组件加载完成后再进行渲染。使用 ref 来创建响应式数据componentNamecomponentLoaded

5. 确保相关全局组件已经注册

在使用动态组件之前,如果是需要使用全局组件,则要确保相关的组件已经在全局注册。

// main.ts
// 省略其他代码
// 需要先注册
app.component("demo-company", Company);
app.component("demo-personal", Personal);app.mount("#app");

通过在 mian.ts入口文件,全局注册了 'demo-company''demo-personal'组件。

🔍 总结

动态组件是 Vue 中非常重要的一个组件类型,它可以让我们在不同的场景下灵活地渲染不同的组件。通过本文的介绍,相信大家已经掌握了动态组件的基本概念、使用方法、条件渲染、过渡效果和数据传递等方面的知识。

📚 学习资源

如果您想深入学习 Vue3,可以参考以下学习资源:

  • Vue 官方文档[2]

  • Vue Mastery 课程[3]

  • 基于 CSS 的过渡效果[4]

参考资料

[1]

动态组件: https://vuejs.org/guide/essentials/component-basics.html#dynamic-components

[2]

Vue 官方文档: https://vuejs.org/guide/essentials/component-basics.html#dynamic-components

[3]

Vue Mastery 课程: https://www.vuemastery.com/courses/advanced-components/dynamic-components

[4]

基于 CSS 的过渡效果: https://vuejs.org/guide/built-ins/transition.html#css-based-transitions

往期回顾

#

如何使用 TypeScript 开发 React 函数式组件?

#

11 个需要避免的 React 错误用法

#

6 个 Vue3 开发必备的 VSCode 插件

#

3 款非常实用的 Node.js 版本管理工具

#

6 个你必须明白 Vue3 的 ref 和 reactive 问题

#

6 个意想不到的 JavaScript 问题

#

试着换个角度理解低代码平台设计的本质

a66d1b59396d28c94577fe041faf56c5.gif

回复“加群”,一起学习进步


http://www.ppmy.cn/news/514765.html

相关文章

各种品牌的Andr​​oid智能手机在Aliexpress.comstore833807

各种品牌的Andr​​oid智能手机在Aliexpress.comstore833807   三星Galaxy S3的   的Andr​​oid 4.3更新发布   如果你拥有三星Galaxy S3的国际版&#xff0c;你就是幸运的。而Android 4.3更新终于开始推出的前旗舰产品。   具体而言&#xff0c;银河S3手机有型号GT-I…

android备份卡刷包,Android 4.3 卡刷版的Root包

Android 4.3恐怕要成为历史上最悲剧的操作系统了&#xff0c;因为它还没有正式发布的时候就被Root了。 日前&#xff0c;网上泄露出原生版Galaxy S4所使用的Android 4.3 ROM&#xff0c;经网友实测之后发现搭载骁龙600处理器的美版Galaxy S4(GT-I9505)可以完美运行这一ROM&…

linux 编译指cpu内核,Linux 有问必答:如何知道进程运行在哪个 CPU 内核上?

问题&#xff1a;我有个 Linux 进程运行在多核处理器系统上。怎样才能找出哪个 CPU 内核正在运行该进程&#xff1f; 当你在 多核 NUMA 处理器上运 行需要较高性能的 HPC(高性能计算)程序或非常消耗网络资源的程序时&#xff0c;CPU/memory 的亲和力是限度其发挥最大性能的重要…

抢班夺权成新跳水王 三星S5周爆跌近2k

三星今年的首款旗舰手机GALAXY S5如期而至&#xff0c;相比上一代的GALAXY S4&#xff0c;正面外观变化不大&#xff0c;后盖采用类皮革质地的塑料材质&#xff0c;配置上搭载高通骁龙800处理器&#xff0c;最高主频2.5GHz&#xff0c;运行内存2GB&#xff0c;机身存储空间为16…

i9500android操作系统跑流量,三星I9500刷机包 百度云ROM54公测版 因为专注 所以精进...

三星Galaxy S4是三星电子在2013年推出的一款手机&#xff0c;搭载的是Exynos 5410双四核处理器&#xff0c;支持ARM的big.LITTLE Processing省电技术&#xff0c;是A7A15的组合(基于Cortex-A15架构&#xff0c;主频1.6GHz、基于Cortex-A7架构&#xff0c;主频1.2GHz。 GPU为Ima…

webpakc原理之开发一个清除console.log(xxx)的loader

一、webpack中清除console的方法 当然想要清除console我们可以使用babel-loader结合babel-plugin-transform-remove-console插件来实现。 安装babel-loader和babel-plugin-transform-remove-console插件 npm install babel-loader babel-plugin-transform-remove-console -D…

QQ自定义登录模拟器

QQ模拟登陆 - 安卓版 软件介绍&#xff1a;一款QQ号码模拟登录效果图生成软件&#xff0c;通过使用这款软件&#xff0c;您可以模拟任何QQ账号&#xff0c;得到您想要的QQ账号登录效果图&#xff0c;用法简单&#xff0c;安全可靠&#xff0c;欢迎下载使用。 ----- 下载地址&am…

QQ飞车回归入团

47541 1.活动时间&#xff1a;2022.12.08 00:00:00-2023.1.31 23:59:59。 2.活动规则&#xff1a; ①任何人皆可为团长&#xff0c;但参团人员必须为回归玩家&#xff0c;具体判断标准以游戏内荣耀回归身份为准 ②加入任意团队均需获得队长同意。 ③每人活动期间限定参团3次&…