vue3 tab切换 动态组件

进阶组件技巧

异步组件示例

通过defineAsyncComponent加载一个异步组件,减轻应用的初始负载。

<template>
  <AsyncComponent />
</template>

<script>
import { defineAsyncComponent } from 'vue';

const AsyncComponent = defineAsyncComponent(() =>
  import('./ExpensiveComponent.vue')
);

export default {
  components: { AsyncComponent }
};
</script>

在这个例子中,ExpensiveComponent仅在AsyncComponent被渲染时才会被加载,达到按需加载的效果。

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,
  };
};

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜空孤狼啸

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值