diff --git a/src/components/device/device-tree/device-tree.vue b/src/components/device/device-tree/device-tree.vue index d737378..a2179ba 100644 --- a/src/components/device/device-tree/device-tree.vue +++ b/src/components/device/device-tree/device-tree.vue @@ -4,7 +4,7 @@ import { useDeviceTree, usePermission, type UseDeviceTreeReturn } from '@/compos import { DEVICE_TYPE_NAMES, DEVICE_TYPE_LITERALS, tryGetDeviceType, type DeviceType, PERMISSION_TYPE_LITERALS } from '@/enums'; import { isNvrCluster } from '@/helpers'; import { useDeviceStore, usePermissionStore } from '@/stores'; -import { watchImmediate } from '@vueuse/core'; +import { watchDebounced, watchImmediate } from '@vueuse/core'; import destr from 'destr'; import { isFunction } from 'es-toolkit'; import { @@ -27,7 +27,7 @@ import { type TreeProps, } from 'naive-ui'; import { storeToRefs } from 'pinia'; -import { computed, h, nextTick, onBeforeUnmount, ref, toRefs, useTemplateRef, watch, type CSSProperties } from 'vue'; +import { computed, h, nextTick, onBeforeUnmount, onMounted, ref, toRefs, useTemplateRef, watch, type CSSProperties } from 'vue'; const props = defineProps<{ /** @@ -67,15 +67,15 @@ const { selectedStationCode, selectedDeviceType, selectedDevice, + syncFromRoute, + syncToRoute, selectDevice, // 设备管理 exportDevice, exportDeviceTemplate, importDevice, deleteDevice, -} = useDeviceTree({ - syncRoute: computed(() => !!syncRoute.value), -}); +} = useDeviceTree(); // 将 `selectDevice` 函数暴露给父组件 emit('exposeSelectDeviceFn', selectDevice); @@ -484,11 +484,38 @@ const onLocateDeviceTree = async () => { animated.value = true; }; -// 渲染全线设备树时,当选择的设备发生变化,则定位设备树 + +// 当选择的设备发生变化时,定位设备树,并同步选中状态到路由参数 // 暂时不考虑多次执行的问题,因为当选择的设备在设备树视口内时,不会发生滚动 -watch(selectedDevice, async () => { +watch(selectedDevice, async (newDevice, oldDevice) => { if (!!station.value) return; - await onLocateDeviceTree(); + if (newDevice?.id === oldDevice?.id) return; + // console.log('selectedDevice changed'); + onLocateDeviceTree(); + syncToRoute(); +}); + +// 当全线设备发生变化时,从路由参数同步选中状态 +// 但lineDevices是shallowRef,因此需要深度侦听才能获取内部变化, +// 而单纯的深度侦听又可能会引发性能问题,因此尝试使用防抖侦听 +watchDebounced( + lineDevices, + (newLineDevices) => { + if (syncRoute.value) { + // console.log('lineDevices changed'); + syncFromRoute(newLineDevices); + } + }, + { + debounce: 500, + deep: true, + }, +); + +onMounted(() => { + if (syncRoute.value) { + syncFromRoute(lineDevices.value); + } }); diff --git a/src/composables/device/use-device-selection.ts b/src/composables/device/use-device-selection.ts index 4c0e839..136d16d 100644 --- a/src/composables/device/use-device-selection.ts +++ b/src/composables/device/use-device-selection.ts @@ -1,39 +1,33 @@ import type { LineDevices, NdmDeviceResultVO, Station } from '@/apis'; import { tryGetDeviceType, type DeviceType } from '@/enums'; -import { useDeviceStore } from '@/stores'; -import { watchDebounced } from '@vueuse/core'; -import { storeToRefs } from 'pinia'; -import { onMounted, ref, toValue, watch, type MaybeRefOrGetter } from 'vue'; +import { ref } from 'vue'; import { useRoute, useRouter } from 'vue-router'; -export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter }) => { - const { syncRoute } = options ?? {}; - +export const useDeviceSelection = () => { const route = useRoute(); const router = useRouter(); - const deviceStore = useDeviceStore(); - const { lineDevices } = storeToRefs(deviceStore); - const selectedStationCode = ref(); const selectedDeviceType = ref(); const selectedDevice = ref(); - const initFromRoute = (lineDevices: LineDevices) => { - const { stationCode, deviceType, deviceDbId } = route.query; - if (stationCode) { - selectedStationCode.value = stationCode as Station['code']; + // 从路由参数同步选中的车站、设备类型以及设备 + const syncFromRoute = (lineDevices: LineDevices) => { + // console.log('sync from route'); + const { stationCode: routeStationCode, deviceType: routeDeviceType, deviceDbId: routeDeviceDbId } = route.query; + if (routeStationCode) { + selectedStationCode.value = routeStationCode as Station['code']; } - if (deviceType) { - selectedDeviceType.value = deviceType as DeviceType; + if (routeDeviceType) { + selectedDeviceType.value = routeDeviceType as DeviceType; } - if (deviceDbId && selectedStationCode.value && selectedDeviceType.value) { - const selectedDeviceDbId = deviceDbId as string; + if (routeDeviceDbId && selectedStationCode.value && selectedDeviceType.value) { + const selectedDeviceDbId = routeDeviceDbId as string; const stationDevices = lineDevices[selectedStationCode.value]; if (stationDevices) { - const devices = stationDevices[selectedDeviceType.value]; - if (devices) { - const device = devices.find((device) => device.id === selectedDeviceDbId); + const classifiedDevices = stationDevices[selectedDeviceType.value]; + if (classifiedDevices) { + const device = classifiedDevices.find((device) => device.id === selectedDeviceDbId); if (device) { selectedDevice.value = device; } @@ -51,7 +45,9 @@ export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter { + // console.log('sync to route'); const query = { ...route.query }; // 当选中的设备发生变化时,删除fromPage参数 if (selectedDevice.value?.id && route.query.deviceDbId !== selectedDevice.value.id) { @@ -69,39 +65,13 @@ export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter { - if (toValue(syncRoute)) { - syncToRoute(); - } - }); - - // lineDevices是shallowRef,因此需要深度侦听才能获取内部变化, - // 而单纯的深度侦听又可能会引发性能问题,因此尝试使用防抖侦听 - watchDebounced( - lineDevices, - (newLineDevices) => { - if (toValue(syncRoute)) { - initFromRoute(newLineDevices); - } - }, - { - debounce: 500, - deep: true, - }, - ); - - onMounted(() => { - if (toValue(syncRoute)) { - initFromRoute(lineDevices.value); - } - }); - return { selectedStationCode, selectedDeviceType, selectedDevice, - initFromRoute, + syncFromRoute, + syncToRoute, selectDevice, }; }; diff --git a/src/composables/device/use-device-tree.ts b/src/composables/device/use-device-tree.ts index 619c2d4..4980c87 100644 --- a/src/composables/device/use-device-tree.ts +++ b/src/composables/device/use-device-tree.ts @@ -1,11 +1,8 @@ -import type { MaybeRefOrGetter } from 'vue'; import { useDeviceManagement } from './use-device-management'; import { useDeviceSelection } from './use-device-selection'; -export const useDeviceTree = (options?: { syncRoute?: MaybeRefOrGetter }) => { - const { syncRoute } = options ?? {}; - - const deviceSelection = useDeviceSelection({ syncRoute }); +export const useDeviceTree = () => { + const deviceSelection = useDeviceSelection(); const deviceManagement = useDeviceManagement(); return {