05.动态组件

动态组件通过将 is 属性作用于 <component> 元素来构成在组件之间动态更改(即切换)的能力。

我们将通过一个示例来更好地理解动态组件的工作原理。假设我们有标题为 Home 、 Feed 和 History 的组件,它们仅显示指示它是什么组件的文本。

html 复制代码
<!-- Home -->
<template><div class="tab">Home component</div></template>

<!-- Feed -->
<template><div class="tab">Feed component</div></template>

<!-- History -->
<template><div class="tab">History component</div></template>

我们的目标是构建一个界面,可单击的选项卡列表。根据单击的选项卡,我们希望动态渲染某个组件。

当在选项卡之间单击时,我们希望动态卸载和安装组件而不使用路由。虽然类似这样的事情可以通过借助 v-if 和 v-else 等指令通过条件渲染子模板来实现,但这是 Vue 动态组件更完美的用例。

在应用程序的 App 组件中,我们可以首先导入三个单独的组件,以使它们在模板中可用。我们还将创建一个 currentTab 响应式属性,其初始值为 "Home" 。

js 复制代码
<script setup>
  import { ref } from "vue";
  import Home from "./components/Home.vue";
  import Feed from "./components/Feed.vue";
  import History from "./components/History.vue";

  const currentTab = ref("Home");
  const tabs = {
    Home,
    Feed,
    History,
  };
</script>

请注意,我们的 tabs 对象引用实际的组件定义,而不仅仅是组件的名称。

在 App 组件模板中,我们将渲染三个单独的选项卡按钮------每个组件对应我们要显示的那个组件。我们将使用 v-for 指令来帮助实现这一目标。我们将循环遍历 tabs 列表并渲染 <button /> 元素列表。对于每个呈现的 <button /> ,我们将选项卡值绑定到元素的 key 属性,如果选项卡被选中/激活,则动态呈现 .active 类,并且有一个点击处理程序来在选择选项卡时更新组件 currentTab 值。

html 复制代码
<template>
  <div class="demo">
    <button
      v-for="(_, tab) in tabs"
      :key="tab"
      :class="['tab-button', { active: currentTab === tab }]"
      @click="currentTab = tab"
    >
      {{ tab }}
    </button>
  </div>
</template>

<script setup>
  import { ref } from "vue";
  import Home from "./components/Home.vue";
  import Feed from "./components/Feed.vue";
  import History from "./components/History.vue";

  const currentTab = ref("Home");
  const tabs = {
    Home,
    Feed,
    History,
  };
</script>

通过这些更改,我们现在将显示三个选项卡按钮。

为了动态渲染某个子组件,我们将 is 属性绑定到保留的 <component> 元素。附加到 is 属性的值应与我们要动态渲染的子组件相对应。在我们的例子中,我们将使用 currentTab 数据属性来指示在特定时间选择哪个子组件。

html 复制代码
<template>
  <div class="demo">
    <button
      v-for="(_, tab) in tabs"
      :key="tab"
      :class="['tab-button', { active: currentTab === tab }]"
      @click="currentTab = tab"
    >
      {{ tab }}
    </button>
    <component :is="tabs[currentTab]" class="tab"></component>
  </div>
</template>

<script setup>
  import { ref } from "vue";
  import Home from "./components/Home.vue";
  import Feed from "./components/Feed.vue";
  import History from "./components/History.vue";

  // eslint-disable-next-line no-unused-vars
  const currentTab = ref("Home");

  // eslint-disable-next-line no-unused-vars
  const tabs = {
    Home,
    Feed,
    History,
  };
</script>

将动态 <component /> 元素放置在模板中后,我们会注意到子组件现在根据选择的选项卡动态卸载和加载。

打开沙箱运行代码

保存状态

使用动态组件时,保留状态可能是需要牢记的一个重要考虑因素。默认情况下,当组件被卸载时,其状态就会丢失。然而,Vue 提供了一种使用 <KeepAlive> 组件来保存动态组件状态的方法。

为了保留动态组件的状态,我们可以用 <KeepAlive > 组件包裹 <component> 元素。

html 复制代码
<template>
  <div class="demo">
    <!--  -->
    <KeepAlive>
      <component :is="tabs[currentTab]" class="tab"></component>
    </KeepAlive>
  </div>
</template>

<script setup>
  // ...
</script>

通过 <KeepAlive> 组件包裹 <component> 元素,动态组件的状态在卸载时将被保留。这意味着任何数据或组件状态都将被保留,并且组件在再次加载时将保留其先前的状态。

要查看这样的示例,我们可以更新每个子组件以包含一个简单的递增计数器。

html 复制代码
<!-- Repeat this counter example for Home, Feed, and History -->
<template>
  <div class="tab">
    Home component
    <p>Counter: {{ counter }}</p>
    <button @click="incrementCounter">Increment</button>
  </div>
</template>

<script setup>
  import { ref } from "vue";

  const counter = ref(0);

  // eslint-disable-next-line no-unused-vars
  const incrementCounter = () => {
    counter.value++;
  };
</script>

通过这些更改,我们会注意到即使我们在组件之间动态切换,每个子组件的计数器状态也被保留。

通过使用 <KeepAlive> 组件,我们可以保留动态组件的状态来增强动态组件的行为,并在选项卡之间切换时提供更流畅的用户体验。

打开沙箱运行代码

相关资源

相关推荐
福兮说3 分钟前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理42 分钟前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
专业程序开发源1 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
专业程序开发源1 小时前
springboot社区养老系统44071-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
小呆呆6661 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)2 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan2 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_3 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒3 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技3 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端