1. 场景
tab 切换,组件动态加载
2. 基本用法
<template>
<div style="display: flex;">
<div v-for="(item, index) in data" :key="index" @click="clickTab(item, index)" :class = "[index === comIndex ? 'active' : '']" class="tab">
{{ item.name }}
</div>
</div>
<!-- 动态组件占位符 -->
<component :is='comId'></component>
</template>
<script setup lang="ts">
import { reactive,ref } from 'vue';
import A from './components/A.vue';
import B from './components/B.vue';
import C from './components/C.vue';
// 点击 tab
const clickTab = (item: any, index: number) => {
comIndex.value = index // 切换 tab 索引
comId.value = item.com // 切换动态组件
}
// 响应式索引,用于标记当前 tab
let comIndex = ref(0)
// 响应式组件,用于标记当前组件
let comId = ref(A)
const data = reactive([
{
name: '组件A',
com: A
},
{
name: '组件B',
com: B
},
{
name: '组件C',
com: C
}
])
</script>
<style scoped>
.tab {
width: 150px;
height: 100px;
border: 1px solid #ccc;
cursor: pointer;
}
.active {
background-color: skyblue;
}
</style>
3. 性能调优
可以看到控制台上报出提示:建议不要对组件进行深层次的监视,会造成不必要的性能开销
根据提示,我们可以修改两个地方
// 1. 把组件用 markRaw 包裹
const data = reactive([
{
name: '组件A',
com: markRaw(A)
},
{
name: '组件B',
com: markRaw(B)
},
{
name: '组件C',
com: markRaw(C)
}
])
// 2. 把组件标记用 shallowRef 包裹
// 响应式组件,用于标记当前组件
let comId = shallowRef(A)
4. 补充用法
不用组件写法,用字符串写法
① 多写一个 script 标签,引入并注册组件,默认暴露
<script lang="ts">
import A from './components/A.vue';
import B from './components/B.vue';
import C from './components/C.vue';
export default {
components: {A, B, C}
}
</script>
② 把组件类型都换成字符串类型
// 响应式组件,用于标记当前组件
let comId = ref("A")
const data = reactive([
{
name: '组件A',
com: "A"
},
{
name: '组件B',
com: "B"
},
{
name: '组件C',
com: "C"
}
])