From 8b0e5a5642ff16feb5181ab13507bb2b97f8dca3 Mon Sep 17 00:00:00 2001 From: molong Date: Mon, 26 Jan 2026 13:05:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/boot.js | 2 +- src/layouts/components/breadcrumb.vue | 43 +++++--- src/layouts/components/menu-item.vue | 52 ++++++++- src/layouts/components/menu.vue | 54 +++++++++ src/layouts/components/setting.vue | 12 +- src/layouts/components/tags.vue | 66 ++++++++--- src/layouts/components/userbar.vue | 45 +++++++- src/layouts/index.vue | 151 ++++++++++++++++++++++++-- 8 files changed, 382 insertions(+), 43 deletions(-) diff --git a/src/boot.js b/src/boot.js index f03da87..f14393e 100644 --- a/src/boot.js +++ b/src/boot.js @@ -8,7 +8,7 @@ export default { } for (const [key, component] of Object.entries(ElementPlusIconsVue)) { - app.component(`${key}`, component) + app.component(`ElIcon${key}`, component) } }, } diff --git a/src/layouts/components/breadcrumb.vue b/src/layouts/components/breadcrumb.vue index b5d85ad..5206cc3 100644 --- a/src/layouts/components/breadcrumb.vue +++ b/src/layouts/components/breadcrumb.vue @@ -16,7 +16,7 @@ - + diff --git a/src/layouts/components/menu.vue b/src/layouts/components/menu.vue index 553fb09..0581eb2 100644 --- a/src/layouts/components/menu.vue +++ b/src/layouts/components/menu.vue @@ -94,5 +94,59 @@ const handleSelect = (index) => { diff --git a/src/layouts/components/setting.vue b/src/layouts/components/setting.vue index 6703007..c1dde4b 100644 --- a/src/layouts/components/setting.vue +++ b/src/layouts/components/setting.vue @@ -274,15 +274,25 @@ onMounted(() => { border-radius: 6px 0 0 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 9999; - transition: all 0.3s; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + user-select: none; .el-icon { font-size: 20px; + transition: transform 0.3s; } &:hover { width: 56px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + + .el-icon { + transform: rotate(90deg); + } + } + + &:active { + transform: translateY(-50%) scale(0.95); } } diff --git a/src/layouts/components/tags.vue b/src/layouts/components/tags.vue index 78b0dc7..1952a07 100644 --- a/src/layouts/components/tags.vue +++ b/src/layouts/components/tags.vue @@ -59,9 +59,17 @@ const left = ref(0) const selectedTag = ref(null) const affixTags = ref([]) -// 可见的标签 +// 可见的标签(去重) const visibleTags = computed(() => { - return layoutStore.viewTags || [] + const tags = layoutStore.viewTags || [] + // 使用 Map 根据 fullPath 去重,保留最后出现的 + const tagMap = new Map() + tags.forEach((tag) => { + if (tag.fullPath) { + tagMap.set(tag.fullPath, tag) + } + }) + return Array.from(tagMap.values()) }) // 判断是否激活 @@ -223,6 +231,8 @@ onMounted(() => { background: var(--el-fill-color-blank); border-bottom: 1px solid var(--el-border-color-light); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); + position: relative; + z-index: 9; .tags-view-wrapper { white-space: nowrap; @@ -233,6 +243,20 @@ onMounted(() => { :deep(.el-scrollbar__wrap) { height: 34px; overflow-x: auto; + scrollbar-width: thin; + + &::-webkit-scrollbar { + height: 4px; + } + + &::-webkit-scrollbar-thumb { + background-color: var(--el-border-color-darker); + border-radius: 2px; + } + + &::-webkit-scrollbar-track { + background-color: transparent; + } } :deep(.el-scrollbar__bar.is-horizontal) { @@ -241,20 +265,22 @@ onMounted(() => { } .tags-view-item { - display: inline-block; + display: inline-flex; position: relative; + align-items: center; cursor: pointer; height: 26px; line-height: 26px; border: 1px solid var(--el-border-color-light); color: var(--el-text-color-regular); background: var(--el-fill-color-blank); - padding: 0 8px; + padding: 0 12px; font-size: 12px; margin-left: 5px; margin-top: 4px; - border-radius: 2px; - transition: all 0.3s; + border-radius: 3px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + user-select: none; &:first-of-type { margin-left: 10px; @@ -267,40 +293,54 @@ onMounted(() => { &:hover { background-color: var(--el-fill-color-light); color: var(--el-color-primary); + border-color: var(--el-color-primary-light-7); + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); } &.active { background-color: var(--el-color-primary); border-color: var(--el-color-primary); color: #fff; + font-weight: 500; + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(var(--el-color-primary-rgb), 0.3); &::before { content: ''; background: #fff; display: inline-block; - width: 8px; - height: 8px; + width: 6px; + height: 6px; border-radius: 50%; position: relative; - margin-right: 2px; + margin-right: 6px; + flex-shrink: 0; } } .el-icon-close { + display: inline-flex; + align-items: center; + justify-content: center; border-radius: 50%; text-align: center; transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); transform-origin: 100% 50%; font-size: 12px; - margin-left: 5px; - width: 14px; - height: 14px; - line-height: 14px; + margin-left: 6px; + width: 16px; + height: 16px; + line-height: 16px; vertical-align: middle; + flex-shrink: 0; + opacity: 0.7; &:hover { background-color: #fff; color: var(--el-color-danger); + opacity: 1; + transform: rotate(90deg); } } } diff --git a/src/layouts/components/userbar.vue b/src/layouts/components/userbar.vue index 5f21240..51e7363 100644 --- a/src/layouts/components/userbar.vue +++ b/src/layouts/components/userbar.vue @@ -219,16 +219,18 @@ onUnmounted(() => { align-items: center; gap: 8px; cursor: pointer; - padding: 4px 8px; - border-radius: 4px; - transition: background-color 0.3s; + padding: 6px 12px; + border-radius: 6px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); &:hover { background-color: var(--el-fill-color-light); + transform: translateY(-1px); } .username { font-size: 14px; + font-weight: 500; color: var(--el-text-color-primary); max-width: 100px; overflow: hidden; @@ -239,10 +241,11 @@ onUnmounted(() => { .el-icon-caret-bottom { font-size: 12px; color: var(--el-text-color-regular); - transition: transform 0.3s; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); .avatar-wrapper:hover & { transform: rotate(180deg); + color: var(--el-color-primary); } } } @@ -254,25 +257,55 @@ onUnmounted(() => { width: 36px; height: 36px; cursor: pointer; - border-radius: 4px; - transition: background-color 0.3s; + border-radius: 6px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + user-select: none; .el-icon { font-size: 18px; color: var(--el-text-color-regular); + transition: all 0.3s; } &:hover { background-color: var(--el-fill-color-light); + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); .el-icon { color: var(--el-color-primary); } } + &:active { + transform: translateY(0); + } + :deep(.el-badge__content) { transform: translateY(-8px) translateX(8px); + border: 2px solid var(--el-bg-color); + } + + :deep(.el-badge__content.is-fixed) { + transform: translateY(-8px) translateX(8px); } } } + +// 下拉菜单样式优化 +:deep(.el-dropdown-menu__item) { + display: flex; + align-items: center; + gap: 8px; + transition: all 0.3s; + + .el-icon { + font-size: 16px; + } + + &:hover { + background-color: var(--el-fill-color-light); + color: var(--el-color-primary); + } +} diff --git a/src/layouts/index.vue b/src/layouts/index.vue index 46ae791..310aa5a 100644 --- a/src/layouts/index.vue +++ b/src/layouts/index.vue @@ -5,8 +5,7 @@
- logo - {{ logoText }} + logo