- Published on
译: 动态组件
文章翻译至: Dynamic Components
目录
动态组件通过将 is
属性绑定到保留的 <component>
元素来达到在组件之间动态更改(即切换)的目的。
我们将通过一个示例来更好地理解动态组件的工作原理。假设我们有标题为 Home 、 Feed 和 History 的单独组件,它们仅显示指示其是什么组件的文本。
<!-- 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>
我们的目标是构建一个界面,显示可单击的选项卡列表。根据单击的选项卡,动态渲染某个组件。
当在选项卡之间单击时,我们希望动态的unmounted和mounted组件,而不使用路由。
虽然类似这样的事情可以通过在 v-if
和 v-else
等指令的帮助下有条件地渲染子模板来实现,但这也是示范 Vue 动态组件的完美用例。
在应用程序的父 App 组件中,我们可以首先导入三个单独的组件,以使它们在模板中可用。我们还将创建一个 currentTab
响应式属性,其初始值为 Home
。
<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 组件模板中,我们将渲染三个单独的tab按钮 - 每个组件对应我们要显示的每个组件。我们将使用 v-for
指令来帮助实现这一目标。我们将循环遍历 tabs
列表并渲染 <button />
元素列表。
对于每个呈现的 <button />
,我们将tab值绑定到元素的 key
属性,如果tab被选中,则动态渲染 .active
类,,并且有一个点击处理程序在选择tab时更新组件 currentTab
值。
<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
数据属性来指示在特定时间选择哪个子组件。
<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";
const currentTab = ref("Home");
const tabs = {
Home,
Feed,
History,
};
</script>
将动态 <component />
元素放置在模板中后,我们会注意到子组件现在根据选择的tab动态unmounted和mounted。
保存状态
使用动态组件时,保留状态可能是需要牢记的一个重要考虑因素。默认情况下,当组件被卸载时,其状态就会丢失。然而,Vue 提供了一种使用 <KeepAlive>
组件来保存动态组件状态的方法。
为了保留动态组件的状态,我们可以用 <KeepAlive >
组件包装 <component>
元素。
<template>
<div class="demo">
<KeepAlive>
<component :is="tabs[currentTab]" class="tab"></component>
</KeepAlive>
</div>
</template>
<script setup>
// ...
</script>
通过 <KeepAlive>
组件包装 <component>
元素,动态组件的状态在卸载时将被保留。这意味着任何数据或组件状态都将被保留,并且组件在再次安装时将保留其先前的状态。
要查看这样的示例,我们可以更新每个子组件以包含一个简单的递增计数器。
<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);
const incrementCounter = () => {
counter.value++;
};
</script>
通过这些更改,我们会注意到即使我们在组件之间动态切换,每个子组件的计数器状态也被保留。
通过使用 <KeepAlive>
组件,我们可以通过保留动态组件的状态来增强动态组件的行为,并在tab之间切换时提供更流畅的用户体验。
End.