likes
comments
collection
share

Vue3 动态组件?!原来是这样啊!

作者站长头像
站长
· 阅读数 7

本篇文章主要以理解Vue3动态组件,及其相关应用与问题解析。

什么是 Vue3 动态组件?

简单来说,这里的动态,即:能够根据组件的呈现条件,来调整好自己需要呈现的组件,以此来满足对需求的实现。

注:和动态样式一样,通过用户的操作来确定是什么类型的组件。

基本使用

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

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

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

  • 已注册的组件名,或 HTML 标签名称
  • 导入的组件对象

以下是示例:

<script>
import { Transition, TransitionGroup } from 'vue'

export default {
  components: {
    Transition,
    TransitionGroup
  }
}
</script>

<template>
  <component :is="isGroup ? 'TransitionGroup' : 'Transition'">
    ...
  </component>
</template>

在这个例子中,我们可以看到,component 所呈现的组件,是由isGroup来决定的。

注意:

如果将组件本身传递给 is 而不是其名称,则不需要注册,例如在 <script setup> 中。

如果在 <component> 标签上使用 v-model,模板编译器会将其扩展为 modelValue propupdate:modelValue 事件监听器,就像对任何其他组件一样。但是,这与原生 HTML 元素不兼容,例如 <input> <select>。因此,在动态创建的原生元素上使用 v-model 将不起作用:

<script setup>
import { ref } from 'vue'

const tag = ref('input')
const username = ref('')
</script>

<template>
  <!-- 由于 'input' 是原生 HTML 元素,因此这个 v-model 不起作用 -->
  <component :is="tag" v-model="username" />
</template>

应用场景

灵活运用 Vue3 的动态组件功能,能够帮助我们满足动态性和灵活性的需求:

  1. 条件渲染

这也是上面所说的,根据组件呈现的条件来呈现不同的组件。如:根据用户权限加载权限组件或根据用户选择加载不同的组件(可移动看上面的示例!!)

  1. 动态表单

根据表单类型及步骤,动态地渲染表单,以免加载整个表单,比如在我们进行登录的时候,会遇到诸如验证码的东西,有时候产品的需求可能需要我们在不同情况下换验证码的方式:可能有滑块、填数字等。

  1. 复用和扩展组件

利用动态化的呈现,能够在一定程度下,减少对组件的重复利用,这样也便于争取内存和空间。

  1. 配置组件的选择

在一些低代码平台中,通过对组件进行动态化处理,我们能够根据用户配置选择和加载特定组件,快速生成定制化应用程序

  1. 路由视图切换

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

示例

  1. 通过组件名来动态更新组件 - (动态更新)

我们可以看以下的示例,我们通过两个按钮来改变currentPage的值,以此来改变component中的:is的值,来改变该组件。

<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>

当然,我们也是能够将组件名对象存入一个模块中,进而我们去接收其参数,来实现组件的动态渲染,如以下例子:

<template>
      <component :is="item.component" v-for="item in globalComponents" :key="item.key" :ref="(vnode:any)=>item.vnode = vnode" v-bind="item.props"></component>
</template>

<script setup lang="ts">
//获取该元素状态
import { useGlobalStore } from '@/store';
const { globalComponents } = toRefs(useGlobalStore());
</script>
  1. 动态组件间的通信

动态组件的传值,除了支持v-bind传值以外,还支持ref引用传值。使用引用传值的时候,需要注意的是:需要确定组件之后,再使用ref属性进行传值,否则将会无法获取应用组件的属性。

<template>
  <keep-alive>
    <component :is="componentName"></component>
  </keep-alive>
</template>

<script setup lang="ts">
import { ref } from "vue";
const componentName = ref("ComponentA");
</script>
  1. 组件销毁与缓存

当我们在切换组件的时候,在组件切换之后,会导致原组件销毁,导致之前的数据丢失。这个时候,如果我们能够在组件切换的过程中能够保持组件的状态的话,避免一些重复渲染而导致的性能问题,则我们能够在动态组件上使用keep-alive来缓存组件中的数据。

template>
  <keep-alive>
    <component :is="componentName"></component>
  </keep-alive>
</template>

<script setup lang="ts">
import { ref } from "vue";
const componentName = ref("ComponentA");
</script>

总结

动态组件是 Vue 中非常重要的一个组件类型,我们能够通过去使用它,来实现更为复杂的切换组件逻辑。当然,使用该组件类型,笔者认为还是需要学会去搭配不同的类型及方法,已达到更好的性能优化、简洁代码的目的。

Vue3 动态组件?!原来是这样啊!

笔者能力精力有限,如有错误,还望大家及时指出改进