From 4f8d37483e93fe54bb51ff4e587d2ab859fae6dd Mon Sep 17 00:00:00 2001 From: 18278715334 <18278715334@163.com> Date: Tue, 9 Dec 2025 16:42:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc-auto-import.json | 1 + auto-imports.d.ts | 2 + components.d.ts | 1 + src/assets/styles/list-pages.css | 132 ++++++++++++++++ src/components/admin/ProductFormDialog.vue | 1 - src/components/common/DanmakuBar.vue | 6 +- src/components/common/ListPageLayout.vue | 20 +++ .../common/ResponsiveActionColumn.vue | 143 ++++++++++++++++++ src/composables/useMobileTable.js | 101 +++++++++++++ 9 files changed, 403 insertions(+), 4 deletions(-) create mode 100644 src/components/common/ResponsiveActionColumn.vue create mode 100644 src/composables/useMobileTable.js diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 0a6289a..7b77945 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -302,6 +302,7 @@ "useMediaQuery": true, "useMemoize": true, "useMemory": true, + "useMobileTable": true, "useModel": true, "useMounted": true, "useMouse": true, diff --git a/auto-imports.d.ts b/auto-imports.d.ts index d1fcea3..0d9fc22 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -336,6 +336,7 @@ declare global { const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] const useMemoize: typeof import('@vueuse/core')['useMemoize'] const useMemory: typeof import('@vueuse/core')['useMemory'] + const useMobileTable: typeof import('./src/composables/useMobileTable.js')['useMobileTable'] const useModel: typeof import('vue')['useModel'] const useMounted: typeof import('@vueuse/core')['useMounted'] const useMouse: typeof import('@vueuse/core')['useMouse'] @@ -747,6 +748,7 @@ declare module 'vue' { readonly useMediaQuery: UnwrapRef readonly useMemoize: UnwrapRef readonly useMemory: UnwrapRef + readonly useMobileTable: UnwrapRef readonly useModel: UnwrapRef readonly useMounted: UnwrapRef readonly useMouse: UnwrapRef diff --git a/components.d.ts b/components.d.ts index 8e791bb..d84387b 100644 --- a/components.d.ts +++ b/components.d.ts @@ -80,6 +80,7 @@ declare module 'vue' { ProductCard: typeof import('./src/components/product/ProductCard.vue')['default'] ProductDocumentationDialog: typeof import('./src/components/admin/ProductDocumentationDialog.vue')['default'] ProductFormDialog: typeof import('./src/components/admin/ProductFormDialog.vue')['default'] + ResponsiveActionColumn: typeof import('./src/components/common/ResponsiveActionColumn.vue')['default'] RichTextEditor: typeof import('./src/components/common/RichTextEditor.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] diff --git a/src/assets/styles/list-pages.css b/src/assets/styles/list-pages.css index 9738a6a..eb5f85b 100644 --- a/src/assets/styles/list-pages.css +++ b/src/assets/styles/list-pages.css @@ -396,6 +396,138 @@ .filter-buttons { justify-content: center; } + + /* ===== 移动端表格优化 ===== */ + /* 表格容器允许横向滚动 */ + .table-wrapper { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + /* 隐藏滚动条但保持滚动功能 */ + scrollbar-width: thin; + } + + /* 移除固定列效果 - 通过覆盖 Element Plus 的固定列样式 */ + .list-page-container .el-table .el-table__fixed, + .list-page-container .el-table .el-table__fixed-right { + position: static !important; + box-shadow: none !important; + background-color: transparent !important; + } + + /* 固定列的表头和表体都改为静态定位 */ + .list-page-container .el-table .el-table__fixed-header-wrapper, + .list-page-container .el-table .el-table__fixed-body-wrapper, + .list-page-container .el-table .el-table__fixed-footer-wrapper { + position: static !important; + } + + /* 表格单元格在移动端优化 */ + .list-page-container .el-table th, + .list-page-container .el-table td { + padding: 12px 8px !important; + font-size: 13px; + } + + /* 操作按钮组在移动端改为紧凑布局 */ + .list-page-container .el-table .el-table__cell .flex.gap-2, + .list-page-container .el-table .el-table__cell .flex.items-center, + .list-page-container .el-table .el-table__cell .flex.space-x-2 { + flex-wrap: wrap; + gap: 6px !important; + } + + /* 操作按钮在移动端缩小 */ + .list-page-container .el-table .el-button--small { + padding: 6px 10px; + font-size: 12px; + min-width: auto; + } + + /* 表格列宽度优化 - 允许更灵活的宽度 */ + .list-page-container .el-table .el-table__cell { + min-width: 80px; + } + + /* 操作列宽度自适应,不设置最小宽度 */ + .list-page-container .el-table .el-table__cell[data-label="操作"], + .list-page-container .el-table th:last-child, + .list-page-container .el-table td:last-child { + min-width: auto !important; + width: auto !important; + } + + /* 隐藏部分次要列在移动端 - 通过类名控制 */ + .list-page-container .el-table .el-table__cell.hidden-mobile { + display: none; + } + + /* 操作按钮在移动端自动换行,避免溢出 */ + .list-page-container .el-table .el-table__cell .el-button + .el-button { + margin-left: 0; + } + + /* 表格在移动端允许横向滚动 */ + .list-page-container .el-table { + min-width: 600px; + } + + /* 操作列在移动端不设置最小宽度,允许换行 */ + .list-page-container .el-table .el-table__cell[data-label="操作"] { + white-space: normal; + word-break: break-word; + } + + /* 操作按钮组在移动端更紧凑 */ + .list-page-container .el-table .el-table__cell .flex { + justify-content: flex-start; + } + + /* 下拉菜单按钮在移动端优化 */ + .list-page-container .el-table .el-dropdown .el-button { + padding: 6px 10px; + } +} + +/* 超小屏幕进一步优化 */ +@media (max-width: 480px) { + .list-page-container { + padding: 12px; + } + + .list-page-header { + padding: 16px 12px 12px; + } + + .list-page-title { + font-size: 20px; + } + + .list-page-filters { + padding: 16px 12px; + } + + .list-page-table { + padding: 0 12px 12px; + } + + /* 表格单元格进一步缩小 */ + .list-page-container .el-table th, + .list-page-container .el-table td { + padding: 10px 6px !important; + font-size: 12px; + } + + /* 操作按钮更紧凑 */ + .list-page-container .el-table .el-button--small { + padding: 4px 8px; + font-size: 11px; + } + + /* 操作按钮组更紧凑 */ + .list-page-container .el-table .el-table__cell .flex.gap-2, + .list-page-container .el-table .el-table__cell .flex.items-center { + gap: 4px !important; + } } /* 动画效果 */ diff --git a/src/components/admin/ProductFormDialog.vue b/src/components/admin/ProductFormDialog.vue index 5651191..5ff79c3 100644 --- a/src/components/admin/ProductFormDialog.vue +++ b/src/components/admin/ProductFormDialog.vue @@ -316,7 +316,6 @@ import RichTextEditor from '@/components/common/RichTextEditor.vue' import { Rank, Search } from '@element-plus/icons-vue' import { ElMessage } from 'element-plus' -import draggable from 'vuedraggable' const props = defineProps({ modelValue: { diff --git a/src/components/common/DanmakuBar.vue b/src/components/common/DanmakuBar.vue index 43944ae..98ffcbe 100644 --- a/src/components/common/DanmakuBar.vue +++ b/src/components/common/DanmakuBar.vue @@ -47,9 +47,9 @@ import { onMounted, onUnmounted, ref } from 'vue' }) // 固定配置 - const FETCH_PAGE_SIZE = 5// 每次获取的记录数 - const BASE_EMIT_INTERVAL = 4700// 基础5秒,避免弹幕重叠 - const RANDOM_EMIT_RANGE = 1000 // 0-1秒随机范围 + const FETCH_PAGE_SIZE = 8// 每次获取的记录数 + const BASE_EMIT_INTERVAL = 5500// 基础5秒,避免弹幕重叠 + const RANDOM_EMIT_RANGE = 2000 // 0-1秒随机范围 const enabled = ref(true) const danmakuWrapper = ref(null) diff --git a/src/components/common/ListPageLayout.vue b/src/components/common/ListPageLayout.vue index ce6f82a..00f4b89 100644 --- a/src/components/common/ListPageLayout.vue +++ b/src/components/common/ListPageLayout.vue @@ -38,6 +38,9 @@ + diff --git a/src/composables/useMobileTable.js b/src/composables/useMobileTable.js new file mode 100644 index 0000000..392630c --- /dev/null +++ b/src/composables/useMobileTable.js @@ -0,0 +1,101 @@ +import { ref, onMounted, onUnmounted, nextTick } from 'vue' + +/** + * 移动端表格优化 composable + * 用于在移动端移除表格固定列,优化显示效果 + */ +export function useMobileTable() { + const isMobile = ref(false) + const isTablet = ref(false) + + // 检测屏幕尺寸 + const checkScreenSize = () => { + if (typeof window === 'undefined') return + const width = window.innerWidth + isMobile.value = width < 768 + isTablet.value = width >= 768 && width < 1024 + } + + // 移除表格固定列 + const removeFixedColumns = () => { + if (typeof window === 'undefined') return + + // 只在移动端执行 + if (!isMobile.value) { + // 桌面端恢复固定列样式 + const tables = document.querySelectorAll('.list-page-container .el-table') + tables.forEach((table) => { + const fixedElements = table.querySelectorAll('.el-table__fixed, .el-table__fixed-right') + fixedElements.forEach((el) => { + el.style.position = '' + el.style.boxShadow = '' + el.style.backgroundColor = '' + }) + }) + return + } + + // 使用 nextTick 确保 DOM 已更新 + nextTick(() => { + setTimeout(() => { + const tables = document.querySelectorAll('.list-page-container .el-table') + tables.forEach((table) => { + // 移除固定列元素 + const fixedElements = table.querySelectorAll('.el-table__fixed, .el-table__fixed-right') + fixedElements.forEach((el) => { + el.style.position = 'static' + el.style.boxShadow = 'none' + el.style.backgroundColor = 'transparent' + el.style.zIndex = 'auto' + }) + + // 移除固定列的表头、表体、表尾包装器 + const fixedWrappers = table.querySelectorAll( + '.el-table__fixed-header-wrapper, .el-table__fixed-body-wrapper, .el-table__fixed-footer-wrapper' + ) + fixedWrappers.forEach((el) => { + el.style.position = 'static' + }) + + // 移除固定列的遮罩层 + const fixedPatch = table.querySelectorAll('.el-table__fixed-right-patch, .el-table__fixed-patch') + fixedPatch.forEach((el) => { + el.style.display = 'none' + }) + }) + }, 150) + }) + } + + // 监听窗口大小变化 + const handleResize = () => { + const wasMobile = isMobile.value + checkScreenSize() + // 如果移动状态发生变化,重新应用优化 + if (wasMobile !== isMobile.value) { + removeFixedColumns() + } + } + + onMounted(() => { + checkScreenSize() + if (typeof window !== 'undefined') { + window.addEventListener('resize', handleResize) + // 初始移除固定列 + removeFixedColumns() + } + }) + + onUnmounted(() => { + if (typeof window !== 'undefined') { + window.removeEventListener('resize', handleResize) + } + }) + + return { + isMobile, + isTablet, + removeFixedColumns + } +} +