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

news2024/9/20 12:40:22

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.coloradmin.cn/o/674513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git远程仓库使用

说明&#xff1a;使用Git&#xff0c;可以实现版本控制和协作开发。需要协作开发&#xff0c;当然需要建立一个Git代码托管的平台。目前可以使用GitHub、码云、GitLab等&#xff0c;码云相当于国内的GitHub&#xff0c;在国内访问速度高于GitHub&#xff1b;而GitLab是搭建私服…

阿里云服务器的可靠性和稳定性如何?是否有SLA保障?

阿里云服务器的可靠性和稳定性如何&#xff1f;是否有SLA保障&#xff1f;   一、阿里云服务器的可靠性   阿里云服务器作为全球领先的云计算服务平台&#xff0c;以其高性能、高可靠性和高安全性获得了广泛好评。为满足企业客户对稳定、可靠云服务的需求&#xff0c;阿里云…

「译文」用ChatGPT助力SEO工作

大家好&#xff0c;我是可夫小子&#xff0c;《小白玩转ChatGPT》专栏作者&#xff0c;关注AIGC、读书和自媒体。 那些使用ChatGPT的先进人士&#xff0c;也没还能完全掌握它内容生成的能力&#xff0c;特别是像博客那样的长文写作能力。 现在&#xff0c;跟大家介绍 一下SEO优…

GeoServer中使用Qgis发布的SLD样式进行图层美化

目录 知识地图 一、前言 二、Qgis符号化转变成SLD 1、Qis中符号化生成 2、SLD样式导出 三、GeoServer数据发布 1、矢量图层发布 2、在GeoServer中发布样式 总结 知识地图 序号博文链接1使用LeafLet叠加Geoserver wms图层到已有底图的方法2关于GeoServer发布服务时数据源…

windows -- 自动安装python包,并启动服务

文章目录 定制python的包编写批处理文件遇到的问题 自动安装python的包&#xff0c;并启动后台服务进程。 定制python的包 基于python的Flask框架&#xff0c;简单开发一个服务器&#xff1b;编写发布python包的setup.py 在my_ff包的同级目录下创建一个setup.py&#xff0c…

【跟小嘉学 Rust 编程】三、Rust 的基本程序概念

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 文章目录 系列文章目录前言一、变量以及可变性1.1、变量声明语法1.2、不可变变量1.3、未使用变量警告1.4、使用 let mu…

【雕爷学编程】Arduino动手做(119)---JQ6500语音模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

计算机网络——网络层

序言 计算机网络中的网络层在当今的社会起到了什么作用&#xff1f; 现在的互联网通信&#xff0c;远程办公和远程教育&#xff0c;电子商务和在线服务&#xff0c;信息共享和社交媒体&#xff0c;物联网和智能家居都是通过网络层才能使用的。它连接了人们、设备和信息&#xf…

学习笔记:CMOS、MOS、NMOS、PMOS、MOSFET等的区别

复习时 发现连基础概念都不知道&#xff0c;连忙来找补 FET 把P型半导体放入电场中&#xff0c;根据同电荷排斥、异电荷吸引&#xff0c;电荷情况如下&#xff1a; 这种效应称为电场效应&#xff08;Field Effect&#xff09;&#xff0c;依据这种现场所发明的半导体器件称为…

回归、多项式回归、多重回归

1.回归、多项式回归、多重回归 1.1 回归&#xff08;单变量&#xff09; 预测一个变量 x x x与一个变量 y y y的关系 例如&#xff1a;广告费 x x x与点击量 y y y 用直线拟合数据 1.2 多项式回归&#xff08;单变量&#xff09; 预测一个变量 x x x与一个变量 y y y的关系…

mtk preloader简介

前言 preloader按照mtk的说法是MTK in-house developed loader&#xff0c;也就说是mtk内部开发的一个loader&#xff0c;那么单独编译preloader也是可以的&#xff0c;使用命令./mk project_name n pl。 文章目录 前言计算机系统中常用的存储器类型1、启动流程2、下载流程3、代…

React学习[三]

React学习[三] 组件的propsprops的基本使用props的特点 组件通讯的三种方式父组件传递数据给子组件子组件传递数据给父组件兄弟组件传递 Contextprops进阶children属性props校验约束规则 props的默认值 组件的生命周期生命周期三个阶段创建时&#xff08;挂载阶段&#xff09;更…

代理Windows台式机支持Remote Desktop外网远程桌面连接, 随时玩转Stable Diffusion WebUI

title: 《树莓派4B家庭服务器搭建指南》第十八期&#xff1a;代理Windows台式机支持Remote Desktop外网远程桌面连接, 随时玩转Stable Diffusion WebUI zhaoolee在家中Windows台式机折腾Stable Diffusion WebUI , 为了出门在外也能访问Windows台式机的Stable Diffusion WebUI&…

dom4j解析 mybatis config XML文件

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

软件工程——第4章形式化说明技术(非重点)

本专栏是博主个人笔记&#xff0c;主要目的是利用碎片化的时间来记忆软工知识点&#xff0c;特此声明&#xff01; 文章目录 1.软件工程方法划分成哪三类&#xff1f;并各自举例 2.形式化方法的定义&#xff1f; 3.非形式化的方法的缺点&#xff1f; 4.形式化方法的优点&am…

elasticsearch snapshot快照指定多个索引并行备份——筑梦之路

Curl 命令方式对elasticsearch备份和恢复—— 筑梦之路_筑梦之路的博客-CSDN博客 之前也写过使用API请求的方式对ES数据进行快照方式备份&#xff0c;这里主要对之前的内容进行完善和补充。 版本兼容性 快照包含构成索引的磁盘上数据结构的副本。这意味着快照只能还原为可以读…

Kubernetes API Server源码学习(二):OpenAPI、API Resource的装载、HTTP Server具体是怎么跑起来的?

本文基于Kubernetes v1.22.4版本进行源码学习 6、OpenAPI 1&#xff09;、OpenAPI的作用 OpenAPI是由Swagger发展而来的一个规范&#xff0c;一种形式化描述Restful Service的语言&#xff0c;便于使用者理解和使用一个Service。通过OpenAPI规范可以描述一个服务&#xff1a;…

28离散Hopfield神经网络的联想记忆数字识别(附matlab)

1.简述 学习目标&#xff1a;利用离散Hopfield神经网络进行联想记忆数字识别 1982年&#xff0c;美国加州理工学院的J.Hopfield教授提出了一种单层反馈神经网络&#xff0c;称为Hopfield网络[1]。Hopfield网络是一种循环的神经网络&#xff0c;从输出到输入有反馈连接。Hopfiel…

Leetcode---350周赛

题目列表 6901. 总行驶距离 6890. 找出分区值 6893. 特别的排列 6447. 给墙壁刷油漆 一、总行驶距离 很显然&#xff0c;这题单纯就是一道数学应用题&#xff0c;我们要明白最关键的一点 &#xff1a;只有当mainTank>5并且additionalTank>0时&#xff0c;才能发生副油…

操作系统 - 操作系统结构

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…