在Vue3中,我们可以使用动态组件来更改我们的组件,而无需重新加载页面。这使得我们的应用程序更加灵活和响应式。
一、主要代码
<component :is="currentComName"></component>
根据传入currentComName模块名不同而渲染不同的组件
二、实现案例
在下述案例中,我们根据点击不同的tab页而渲染出不同的组件。
以下用到了naiveui相应组件库,请先安装naiveui
npm i -D naive-ui
父组件
// ParentComponent.vue
<template>
<n-space>
<n-tag
v-for="(item, index) in tabList"
:key="item.id"
:type="currentActiveTab == item.id ? 'success' : ''"
@click="handleTabs(item)"
>
{{ item.name }}
</n-tag>
</n-space>
<component :is="currentComName"></component>
</template>
<script setup lang="ts">
import { ref, reactive, shallowRef, markRaw } from "vue";
import DynamicInput from "@/views/DynamicInput/DynamicInput.vue";
import DynamicTags from "@/views/DynamicTags/DynamicTags.vue";
import { NSpace, NTag } from "naive-ui";
const tabList = reactive([
{
id: 1,
comp: markRaw(DynamicInput),
name: "动态录入",
},
{
id: 2,
comp: markRaw(DynamicTags),
name: "动态标签",
},
]);
const currentActiveTab = ref<number>(1);
const currentComName = shallowRef(DynamicInput);
const handleTabs = (item) => {
currentActiveTab.value = item.id;
currentComName.value = item.comp;
};
</script>
<style scoped lang="scss">
.n-tag {
margin-bottom: 16px;
}
</style>
子组件
//DynamicTags.vue
<template>
<n-dynamic-tags v-model:value="tags" />
</template>
<script setup lang="ts">
import { reactive } from "vue";
import { NDynamicTags } from "naive-ui";
const tags = reactive<string[]>(["教师", "程序员"]);
</script>
<style scoped></style>
//DynamicInput.vue
<template>
<n-dynamic-input
v-model:value="value"
placeholder="请输入"
:min="3"
:max="6"
/>
<pre>{{ JSON.stringify(value, null, 2) }}</pre>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import { NDynamicInput } from "naive-ui";
const value = ref<string[]>([]);
</script>
<style scoped></style>
实现效果图如下:
三、结合keep-alive一起使用
Vue提供了keep-alive指令,可以让我们在组件切换时保留状态或避免重新渲染。
<template>
.....
<keep-alive>
<component :is="currentComName"></component>
</keep-alive>
</template>
在以下效果图中我们可以看出,加上keep-alive后组件便具有了缓存效果。
拓展:
<KeepAlive>
引入后或增加两个生命周期函数,分别为onActivated和onDeactivated。这两个钩子不仅适用于 <KeepAlive>
缓存的根组件,也适用于缓存树中的后代组件。
<script setup lang="ts">
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
// 调用时机为首次挂载
// 以及每次从缓存中被重新插入时
})
onDeactivated(() => {
// 在从 DOM 上移除、进入缓存
// 以及组件卸载时调用
})
</script>
四、总结
通过使用 Vue3 的动态组件功能,我们可以根据不同的条件渲染不同的组件,并实现复杂的业务逻辑。
五、更新
多个组件通过component标签挂载在同一个组件中,通过触发时间进行动态切换。vue3与vue2用法不一样,这里有坑!通过vue的defineAsyncComponent实现挂载组件
const DynamicInput= defineAsyncComponent(() => import("@/views/DynamicInput/DynamicInput.vue"));
const DynamicTags= defineAsyncComponent(() => import("@/views/DynamicTags/DynamicTags.vue"));