什么是动态组件
让多个组件使用同一个挂载点,并动态切换,这就是动态组件
怎么用
第一种用法:
<template>
<div class="tab-class">
<div
v-for="(item, index) in tabsList"
@click="clickTab(item, index)"
:class="[index == comIndex ? 'active' : '']"
>
{{ item.name }}
</div>
</div>
<component :is="tabKey" class="tab-class" />
</template>
<script setup lang="ts">
import { reactive, ref, markRaw, shallowRef } from "vue"
import AVue from "./views/demo/A.vue"
import BVue from "./views/demo/B.vue"
import CVue from "./views/demo/C.vue"
const tabsList = reactive([
{ name: "A组件", comName: markRaw(AVue) },
{ name: "B组件", comName: markRaw(BVue) },
{ name: "C组件", comName: markRaw(CVue) },
])
const tabKey = ref(markRaw(AVue))
const comIndex = shallowRef(0)
const clickTab = (item: any, index: number) => {
tabKey.value = item?.comName
comIndex.value = index
}
</script>
<style scoped lang="scss">
.active {
background-color: skyblue;
}
.tab-class {
width: 100%;
display: flex;
padding: 20px;
div {
border: 1px solid;
padding: 10px;
cursor: pointer;
}
}
</style>
注意:
1.在Vue2 的时候is 是通过组件名称切换的 在Vue3 setup 是通过组件实例切换的
2.如果你把组件实例放到Reactive Vue会给你一个警告runtime-core.esm-bundler.js:38 [Vue warn]:
Vue received a Component which was made a reactive object. This can lead to
unnecessary performance
overhead, and should be avoided by marking the component with `markRaw` or
using `shallowRef` instead of `ref`.
Component that was made reactive:
这是因为reactive 会进行proxy 代理 而我们组件代理之后毫无用处 节省性能开销
推荐我们使用shallowRef 或者 markRaw 跳过proxy 代理
第二种用法:
<template>
<div class="tab-class">
<div
v-for="(item, index) in tabsList"
@click="clickTab(item, index)"
:class="[index == comIndex ? 'active' : '']"
>
{{ item.name }}
</div>
</div>
<component :is="tabKey" class="tab-class" />
</template>
<script setup lang="ts">
import { reactive, ref, shallowRef } from "vue"
const tabsList = reactive([
{ name: "A组件", comName: "AVue" },
{ name: "B组件", comName: "BVue" },
{ name: "C组件", comName: "CVue" },
])
const tabKey = ref("AVue")
const comIndex = shallowRef(0)
const clickTab = (item: any, index: number) => {
tabKey.value = item?.comName
comIndex.value = index
}
</script>
<script lang="ts">
import AVue from "./views/demo/A.vue"
import BVue from "./views/demo/B.vue"
import CVue from "./views/demo/C.vue"
export default {
components: {
AVue,
BVue,
CVue,
},
}
</script>
<style scoped lang="scss">
.active {
background-color: skyblue;
}
.tab-class {
width: 100%;
display: flex;
padding: 20px;
div {
border: 1px solid;
padding: 10px;
cursor: pointer;
}
}
</style>