vue3 tab切换 动态组件
先看一张图
具体代码:
组件实例信息
如果你把组件实例放到Reactive Vue会给你一个警告: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
.
Vue 收到一个组件,它被做成一个反应性对象。这可能会导致不必要的性能开销,应通过使用“markRaw”标记组件或使用“shallowRef”而不是“ref”来避免。
index.vue
<template>
<a-layout class="layout">
<a-layout-content class="main-container">
<div class="data-bar" :class="{ collapsed: collapsed }">
<div class="data-bar-container">
<div class="data-bar-icon-box">
<img :src="logo" @click="handleBackDashboard" />
</div>
<div class="data-bar-button" @click="handleBack">
<LeftOutlined />
返回上一页
</div>
</div>
</div>
<a-affix offset-top="0">
<div class="tab-bar">
<div class="tabs">
<template v-for="(tab, tabIndex) in tabs" :key="tabIndex">
<div
v-if="tab.show"
:class="'tab' + `${activeTab === tabIndex ? ' tab-active' : ''}`"
@click="handleSwitchTab(tabIndex)"
>
{{ tab.title }}
</div>
</template>
</div>
</div>
</a-affix>
<div class="result-panel">
<menu-unfold-outlined
v-if="collapsed"
class="trigger"
@click="() => (collapsed = !collapsed)"
/>
<menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)" />
<a-button size="small" type="danger" class="report-btn" @click="handleReport"
>结果报告</a-button
>
<component :is="comId" :baseData="baseData" :collapsed="collapsed"></component>
</div>
</a-layout-content>
</a-layout>
</template>
<script lang="ts" setup>
import { markRaw, shallowRef, watch, onMounted, reactive, ref } from 'vue';
import { LeftOutlined, MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { useRouter } from 'vue-router';
import logo from '/@/assets/icons/logo.svg';
import { useBarcode } from './hooks/useBarcode';
import { useTabs } from './hooks/useTabs';
import * as PhyloTreeApi from '/@/serve/api/phyloTree';
const router = useRouter();
const query = JSON.parse(JSON.stringify(router.currentRoute.value.query));
for (let key in query) Object.assign(query, { [key]: String(query[key]) });
const { taskId, barcodeId, sampleId, generation, barcodeName, primerList } = query;
const baseData = reactive({
barcodeId,
taskId,
sampleId,
barcodeName,
primerList: primerList.split(','),
generation,
});
const { activeTab, tabs, comId, handleSwitchTab } = useTabs(generation);
const { barcodeConfig } = useBarcode(baseData);
const collapsed = ref(true);
const handleBack = () => {
router.go(-1);
};
const handleReport = () => {
router.push(
`/hiv/report?taskId=${taskId}&sampleId=${sampleId}&barcodeId=${barcodeId}&generation=${generation}&barcodeName=${barcodeName}`,
);
};
const handleBackDashboard = () => {
router.push('/dashboard');
};
</script>
<style lang="less" scoped>
@import '/@/assets/styles/views/result2.less';
</style>
useTabs.ts
import { reactive, ref, markRaw, shallowRef } from 'vue';
import NanoStats from '../../nanoStats/index.vue';
import HtvHtml from '../../htvHtml/index.vue';
import ResultAnalyse from '../../resultAnalyse/index.vue';
import ResultTable from '../../resultTable/index.vue';
import SeqOverview from '../../seqOverview/index.vue';
import Medaka from '../../medaka/index.vue';
import MinTree from '../../minTree/index.vue';
import EvolveTree from '../../evolveTree/index.vue';
export const useTabs = (generation: string) => {
const tabs: Array<{ title: string; show: boolean; com: any }> = reactive([
{
title: '数据统计',
show: generation == '5' ? true : false,
com: markRaw(NanoStats),
},
{
title: '分子溯源',
show: generation == '6' ? true : false,
com: markRaw(HtvHtml),
},
{
title: '准种结果分析',
show: generation == '5' ? true : false,
com: markRaw(ResultAnalyse),
},
{
title: '原始聚类结果表',
show: generation == '5' ? true : false,
com: markRaw(ResultTable),
},
{
title: '多序列比对结果',
show: generation == '5' ? true : false,
com: markRaw(SeqOverview),
},
{
title: '准种序列文本',
show: generation == '5' ? true : false,
com: markRaw(Medaka),
},
{
title: '最小生成树',
show: generation == '5' ? true : false,
com: markRaw(MinTree),
},
{
title: '进化树',
show: generation == '5' ? true : false,
com: markRaw(EvolveTree),
},
]);
const activeTab = ref(0);
const comId = shallowRef(NanoStats);
if (generation == '5') {
activeTab.value = 0;
comId.value = NanoStats;
} else if (generation == '6') {
activeTab.value = 1;
comId.value = HtvHtml;
}
const handleSwitchTab = (tabIndex: number) => {
comId.value = tabs[tabIndex].com;
activeTab.value = tabIndex;
document.body.scrollTop = document.documentElement.scrollTop = 0;
};
return {
activeTab,
comId,
tabs,
handleSwitchTab,
};
};