refactor: 优化设备和产品详情页组件加载
- 引入 defineAsyncComponent 实现异步组件加载 - 在产品详情页添加 Metadata 组件预取 - 优化标签页 active-key绑定方式
This commit is contained in:
parent
ac343f006a
commit
78c7cff383
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted } from 'vue';
|
||||
import { computed, defineAsyncComponent, onMounted, onUnmounted } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
@ -12,10 +12,18 @@ import { deviceStateOptions } from '#/constants/dicts';
|
|||
import { useDeviceStore } from '#/store/device';
|
||||
import { getWebSocket } from '#/utils/websocket';
|
||||
|
||||
import BasicInfo from './components/BasicInfo.vue';
|
||||
import DeviceSimulation from './components/DeviceSimulation.vue';
|
||||
import LogManagement from './components/LogManagement.vue';
|
||||
import RunningStatus from './components/RunningStatus.vue';
|
||||
const BasicInfo = defineAsyncComponent(
|
||||
() => import('./components/BasicInfo.vue'),
|
||||
);
|
||||
const DeviceSimulation = defineAsyncComponent(
|
||||
() => import('./components/DeviceSimulation.vue'),
|
||||
);
|
||||
const LogManagement = defineAsyncComponent(
|
||||
() => import('./components/LogManagement.vue'),
|
||||
);
|
||||
const RunningStatus = defineAsyncComponent(
|
||||
() => import('./components/RunningStatus.vue'),
|
||||
);
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
@ -207,7 +215,7 @@ onUnmounted(() => {
|
|||
|
||||
<!-- 标签页内容 -->
|
||||
<Tabs
|
||||
v-model:active-key="activeTab"
|
||||
:active-key="activeTab"
|
||||
class="detail-tabs"
|
||||
@change="handleTabChange"
|
||||
:destroy-inactive-tab-pane="true"
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
h,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
} from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons-vue';
|
||||
import { Image, message, Modal, Switch, TabPane, Tabs } from 'ant-design-vue';
|
||||
import {
|
||||
Image,
|
||||
message,
|
||||
Modal,
|
||||
Spin,
|
||||
Switch,
|
||||
TabPane,
|
||||
Tabs,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
productPushMetadataById,
|
||||
|
@ -13,9 +28,35 @@ import {
|
|||
} from '#/api/device/product';
|
||||
import { useProductStore } from '#/store/product';
|
||||
|
||||
import BasicInfo from './components/BasicInfo.vue';
|
||||
import DeviceAccess from './components/DeviceAccess.vue';
|
||||
import Metadata from './components/Metadata.vue';
|
||||
const BasicInfo = defineAsyncComponent(
|
||||
() => import('./components/BasicInfo.vue'),
|
||||
);
|
||||
const DeviceAccess = defineAsyncComponent(
|
||||
() => import('./components/DeviceAccess.vue'),
|
||||
);
|
||||
|
||||
// Metadata 异步组件:loading 占位 + 预取
|
||||
const MetadataLoading = defineComponent({
|
||||
name: 'MetadataLoading',
|
||||
setup() {
|
||||
return () =>
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
style:
|
||||
'display:flex;align-items:center;justify-content:center;padding:24px;',
|
||||
},
|
||||
[h(Spin, { tip: '正在加载物模型...' })],
|
||||
);
|
||||
},
|
||||
});
|
||||
const loadMetadataAsync = () =>
|
||||
import(/* webpackPrefetch: true */ './components/Metadata.vue');
|
||||
const Metadata = defineAsyncComponent({
|
||||
loader: loadMetadataAsync,
|
||||
loadingComponent: MetadataLoading,
|
||||
delay: 200,
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
@ -32,6 +73,16 @@ const loadProductInfo = async () => {
|
|||
// TODO: 这里需要添加获取设备数量的逻辑
|
||||
// 暂时设置为 0
|
||||
productStore.setDeviceCount(0);
|
||||
// 空闲时预取 Metadata 代码,减少首次切换等待
|
||||
if (activeTab.value !== 'Metadata') {
|
||||
const idle = (cb: () => void) =>
|
||||
(window as any).requestIdleCallback
|
||||
? (window as any).requestIdleCallback(cb)
|
||||
: setTimeout(cb, 200);
|
||||
idle(() => {
|
||||
loadMetadataAsync().catch(() => undefined);
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
message.error('加载产品信息失败');
|
||||
}
|
||||
|
@ -154,7 +205,7 @@ onUnmounted(() => {
|
|||
|
||||
<!-- 标签页内容 -->
|
||||
<Tabs
|
||||
v-model:active-key="activeTab"
|
||||
:active-key="activeTab"
|
||||
class="detail-tabs"
|
||||
@change="handleTabChange"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue