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"><divv-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-outlinedv-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,};
};