⚡ 补充分割低频组件与响应式渲染优化
根据全站性能审计继续降低低频组件请求、重复 DOM 与重复缓存 URL 成本。 - 二维码组件改为详情弹窗实际渲染时异步加载 - 文件管理仅挂载当前断点对应的移动列表或桌面表格 - Vite 静态与动态资源统一使用 /theme-assets/ 前缀 - 已通过架构检查、类型检查、ESLint 和生产构建
This commit is contained in:
@@ -108,10 +108,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { inject } from 'vue'
|
import { defineAsyncComponent, inject } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { FileIcon, CalendarIcon, HardDriveIcon, DownloadIcon } from 'lucide-vue-next'
|
import { FileIcon, CalendarIcon, HardDriveIcon, DownloadIcon } from 'lucide-vue-next'
|
||||||
import QRCode from 'qrcode.vue'
|
|
||||||
import type { ReceivedFileRecord } from '@/types'
|
import type { ReceivedFileRecord } from '@/types'
|
||||||
import { buildDownloadUrl, buildReceivedRecordQrValue } from '@/utils/share-url'
|
import { buildDownloadUrl, buildReceivedRecordQrValue } from '@/utils/share-url'
|
||||||
|
|
||||||
@@ -129,6 +129,7 @@ defineProps<Props>()
|
|||||||
defineEmits<Emits>()
|
defineEmits<Emits>()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const isDarkMode = inject('isDarkMode')
|
const isDarkMode = inject('isDarkMode')
|
||||||
|
const QRCode = defineAsyncComponent(() => import('qrcode.vue'))
|
||||||
|
|
||||||
const getDownloadUrl = (record: ReceivedFileRecord) => {
|
const getDownloadUrl = (record: ReceivedFileRecord) => {
|
||||||
return buildDownloadUrl(record.downloadUrl)
|
return buildDownloadUrl(record.downloadUrl)
|
||||||
|
|||||||
@@ -168,7 +168,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, inject } from 'vue'
|
import { computed, defineAsyncComponent, inject } from 'vue'
|
||||||
import {
|
import {
|
||||||
ClipboardCopyIcon,
|
ClipboardCopyIcon,
|
||||||
ClockIcon,
|
ClockIcon,
|
||||||
@@ -177,7 +177,7 @@ import {
|
|||||||
TerminalIcon,
|
TerminalIcon,
|
||||||
XIcon
|
XIcon
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
import QRCode from 'qrcode.vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import type { SentFileRecord } from '@/types'
|
import type { SentFileRecord } from '@/types'
|
||||||
|
|
||||||
@@ -195,6 +195,7 @@ defineEmits<{
|
|||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const isDarkMode = inject('isDarkMode')
|
const isDarkMode = inject('isDarkMode')
|
||||||
|
const QRCode = defineAsyncComponent(() => import('qrcode.vue'))
|
||||||
const qrValue = computed(() => (props.record ? props.getQRCodeValue(props.record) : ''))
|
const qrValue = computed(() => (props.record ? props.getQRCodeValue(props.record) : ''))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -262,6 +262,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
|
v-if="isMobileViewport"
|
||||||
class="theme-2026-card mb-5 overflow-hidden rounded-[24px] shadow-md md:hidden"
|
class="theme-2026-card mb-5 overflow-hidden rounded-[24px] shadow-md md:hidden"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between gap-3 border-b px-4 py-3" :class="[isDarkMode ? 'border-gray-700' : 'border-[#d9e4e6]']">
|
<div class="flex items-center justify-between gap-3 border-b px-4 py-3" :class="[isDarkMode ? 'border-gray-700' : 'border-[#d9e4e6]']">
|
||||||
@@ -463,7 +464,7 @@
|
|||||||
</aside>
|
</aside>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<div class="hidden md:block">
|
<div v-if="!isMobileViewport" class="hidden md:block">
|
||||||
<DataTable :title="t('fileManage.allFiles')" :headers="fileTableHeaders" table-class="min-w-[1120px]">
|
<DataTable :title="t('fileManage.allFiles')" :headers="fileTableHeaders" table-class="min-w-[1120px]">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<BaseButton variant="secondary" :loading="isLoading" @click="refreshFileList">
|
<BaseButton variant="secondary" :loading="isLoading" @click="refreshFileList">
|
||||||
@@ -1663,7 +1664,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref, watch, type Component } from 'vue'
|
import { computed, onMounted, onUnmounted, ref, watch, type Component } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import type {
|
import type {
|
||||||
@@ -1810,6 +1811,11 @@ const {
|
|||||||
|
|
||||||
const isFilterPanelOpen = ref(false)
|
const isFilterPanelOpen = ref(false)
|
||||||
const showMobilePolicyActions = ref(false)
|
const showMobilePolicyActions = ref(false)
|
||||||
|
const mobileMediaQuery = window.matchMedia('(max-width: 767px)')
|
||||||
|
const isMobileViewport = ref(mobileMediaQuery.matches)
|
||||||
|
const syncMobileViewport = (event: MediaQueryListEvent) => {
|
||||||
|
isMobileViewport.value = event.matches
|
||||||
|
}
|
||||||
const isLifecycleExpanded = ref(false)
|
const isLifecycleExpanded = ref(false)
|
||||||
const visibleDetailTimeline = computed(() => {
|
const visibleDetailTimeline = computed(() => {
|
||||||
const rows = selectedFileDetail.value?.detailTimeline || []
|
const rows = selectedFileDetail.value?.detailTimeline || []
|
||||||
@@ -2321,11 +2327,16 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
mobileMediaQuery.addEventListener('change', syncMobileViewport)
|
||||||
params.value.health = getRouteHealthFilter()
|
params.value.health = getRouteHealthFilter()
|
||||||
void loadViewPresets()
|
void loadViewPresets()
|
||||||
void loadFiles()
|
void loadFiles()
|
||||||
void loadHistoryFiles()
|
void loadHistoryFiles()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
mobileMediaQuery.removeEventListener('change', syncMobileViewport)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
|
|||||||
import tailwindcss from 'tailwindcss'
|
import tailwindcss from 'tailwindcss'
|
||||||
import autoprefixer from 'autoprefixer'
|
import autoprefixer from 'autoprefixer'
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
base: '/theme-assets/',
|
||||||
plugins: [vue(), vueJsx()],
|
plugins: [vue(), vueJsx()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|||||||
Reference in New Issue
Block a user