From 9b8299e89558dd2d5e747905ad68141d01a4c4c3 Mon Sep 17 00:00:00 2001 From: zimo493 <2081182432@qq.com> Date: Thu, 14 Aug 2025 16:40:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20:recycle:=20(layouts)=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=A0=87=E7=AD=BE=E9=A1=B5=E7=BB=84=E4=BB=B6=20`TagsV?= =?UTF-8?q?iew`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用 el-tag 组件替换自定义标签样式 - 改进右键菜单功能,使用 Teleport 组件优化显示位置,修复在混合布局下的位置显示错误 - 移除未使用的 layout 计算属性和冗余代码 --- src/layouts/components/TagsView/index.vue | 254 ++++++++-------------- 1 file changed, 86 insertions(+), 168 deletions(-) diff --git a/src/layouts/components/TagsView/index.vue b/src/layouts/components/TagsView/index.vue index c1a3fd58..7689b157 100644 --- a/src/layouts/components/TagsView/index.vue +++ b/src/layouts/components/TagsView/index.vue @@ -1,56 +1,69 @@ - - openContextMenu(tag, event)" - > - - {{ translateRouteTitle(tag.title) }} - - - × - - + + + openContextMenu(tag, event)" + @close="closeSelectedTag(tag)" + @click=" + router.push({ + path: tag.fullPath, + query: tag.query, + }) + " + > + {{ translateRouteTitle(tag.title) }} + + - - - - 刷新 - - - - 关闭 - - - - 关闭其它 - - - - 关闭左侧 - - - - 关闭右侧 - - - - 关闭所有 - - + + + + + 刷新 + + + + 关闭 + + + + 关闭其它 + + + + 关闭左侧 + + + + 关闭右侧 + + + + 关闭所有 + + + @@ -58,8 +71,7 @@ import { useRoute, useRouter, type RouteRecordRaw } from "vue-router"; import { resolve } from "path-browserify"; import { translateRouteTitle } from "@/utils/i18n"; -import { usePermissionStore, useTagsViewStore, useSettingsStore } from "@/store"; -import { LayoutMode } from "@/enums"; +import { usePermissionStore, useTagsViewStore } from "@/store"; interface ContextMenu { visible: boolean; @@ -67,17 +79,12 @@ interface ContextMenu { y: number; } -const instance = getCurrentInstance(); -const proxy = instance?.proxy; const router = useRouter(); const route = useRoute(); // 状态管理 const permissionStore = usePermissionStore(); const tagsViewStore = useTagsViewStore(); -const settingsStore = useSettingsStore(); - -// const { visitedViews } = storeToRefs(tagsViewStore); const visitedViews = ref([]); @@ -88,8 +95,6 @@ watchEffect(() => { tagsViewStore.setCacheRoutes(names, permissionStore.allCacheRoutes); }); -const layout = computed(() => settingsStore.layout); - // 当前选中的标签 const selectedTag = ref(null); @@ -224,19 +229,8 @@ const handleMiddleClick = (tag: TagView) => { * 打开右键菜单 */ const openContextMenu = (tag: TagView, event: MouseEvent) => { - const MENU_MIN_WIDTH = 105; - const MENU_MARGIN = 15; - - const containerRect = proxy?.$el.getBoundingClientRect(); - const offsetLeft = containerRect?.left || 0; - const containerWidth = proxy?.$el.offsetWidth || 0; - - const maxLeft = containerWidth - MENU_MIN_WIDTH; - const leftPosition = event.clientX - offsetLeft + MENU_MARGIN; - - contextMenu.x = Math.min(leftPosition, maxLeft); - // 混合模式下,需要减去顶部菜单(fixed)的高度 - contextMenu.y = layout.value === LayoutMode.MIX ? event.clientY - 50 : event.clientY; + contextMenu.x = event.clientX; + contextMenu.y = event.clientY; contextMenu.visible = true; selectedTag.value = tag; @@ -386,113 +380,37 @@ useContextMenuManager(); .tags-container { width: 100%; height: $tags-view-height; - background-color: var(--el-bg-color); - border: 1px solid var(--el-border-color-light); - box-shadow: 0 1px 1px var(--el-box-shadow-light); + padding: 0 15px; + border-top: 1px solid var(--el-border-color-light); .scroll-container { white-space: nowrap; } +} +.contextmenu { + position: absolute; + z-index: 3000; + padding: 5px 0; + margin: 0; + font-size: 12px; + font-weight: 400; + color: var(--el-text-color-primary); + list-style-type: none; + background: var(--el-bg-color); + border-radius: 4px; + box-shadow: var(--el-box-shadow-light); - .tags-item { - position: relative; - display: inline-flex; + li { + display: flex; + gap: 8px; align-items: center; - height: 26px; - padding: 0 8px; - margin-top: 4px; - margin-left: 5px; - font-size: 12px; - line-height: 26px; - color: var(--el-text-color-primary); - background: var(--el-bg-color); - border: 1px solid var(--el-border-color); - transition: all 0.2s ease; - - &:first-of-type { - margin-left: 15px; - } - &:last-of-type { - margin-right: 15px; - } - - .tag-text { - display: inline-block; - vertical-align: middle; - } - - .tag-close-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 16px; - height: 16px; - margin-left: 5px; - font-size: 12px; - font-weight: bold; - color: var(--el-text-color-secondary); - cursor: pointer; - border-radius: 50%; - transition: all 0.2s ease; - - &:hover { - color: var(--el-color-white); - background-color: var(--el-text-color-placeholder); - } - } - - &.active { - color: var(--el-color-white); - background-color: var(--el-color-primary); - border-color: var(--el-color-primary); - - &::before { - position: relative; - display: inline-block; - width: 8px; - height: 8px; - margin-right: 2px; - content: ""; - background: var(--el-color-white); - border-radius: 50%; - } - - .tag-close-btn { - color: var(--el-color-white); - - &:hover { - color: var(--el-color-white); - background-color: rgba(255, 255, 255, 0.3); - } - } - } - } - - .contextmenu { - position: absolute; - z-index: 3000; - padding: 5px 0; + padding: 7px 16px; margin: 0; - font-size: 12px; - font-weight: 400; - color: var(--el-text-color-primary); - list-style-type: none; - background: var(--el-bg-color); - border-radius: 4px; - box-shadow: var(--el-box-shadow-light); + cursor: pointer; + transition: background-color 0.2s; - li { - display: flex; - gap: 8px; - align-items: center; - padding: 7px 16px; - margin: 0; - cursor: pointer; - transition: background-color 0.2s; - - &:hover { - background: var(--el-fill-color-light); - } + &:hover { + background: var(--el-fill-color-light); } } }