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 @@