|
|
@@ -1,13 +1,18 @@
|
|
|
<template>
|
|
|
- <div class="menu-item-wrapper">
|
|
|
+ <div class="menu-item-wrapper" :class="[`theme-${theme}`]">
|
|
|
+
|
|
|
<div
|
|
|
class="menu-row"
|
|
|
- :class="{
|
|
|
- 'is-root': level === 0,
|
|
|
- 'is-sub': level > 0,
|
|
|
- 'is-leaf': !hasChildren
|
|
|
- }"
|
|
|
- :style="{ paddingLeft: level * 20 + 20 + 'px' }"
|
|
|
+ :class="[
|
|
|
+ {
|
|
|
+ 'is-leaf': !hasChildren,
|
|
|
+ 'is-folder': hasChildren,
|
|
|
+ 'is-root': level === 0,
|
|
|
+ 'is-sub': level > 0
|
|
|
+ },
|
|
|
+ 'level-' + level
|
|
|
+ ]"
|
|
|
+ :style="{ paddingLeft: level * 20 + 15 + 'px' }"
|
|
|
@click="handleClick"
|
|
|
>
|
|
|
<i v-if="node.icon" :class="node.icon" class="node-icon"></i>
|
|
|
@@ -19,7 +24,7 @@
|
|
|
class="arrow-icon"
|
|
|
:class="{ 'is-open': isOpen }"
|
|
|
>
|
|
|
- ^
|
|
|
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>
|
|
|
</span>
|
|
|
</div>
|
|
|
|
|
|
@@ -29,6 +34,7 @@
|
|
|
:key="child.id"
|
|
|
:node="child"
|
|
|
:level="level + 1"
|
|
|
+ :theme="theme"
|
|
|
@node-click="passEventUp"
|
|
|
/>
|
|
|
</div>
|
|
|
@@ -37,27 +43,28 @@
|
|
|
|
|
|
<script>
|
|
|
export default {
|
|
|
- // 组件必须有 name 才能进行递归调用!
|
|
|
name: 'MenuItem',
|
|
|
props: {
|
|
|
node: {
|
|
|
type: Object,
|
|
|
required: true
|
|
|
},
|
|
|
- // 当前节点的层级,默认从 0 开始
|
|
|
level: {
|
|
|
type: Number,
|
|
|
default: 0
|
|
|
+ },
|
|
|
+ // 可选值:'tech' (科技渐变) | 'dark' (极简暗色)
|
|
|
+ theme: {
|
|
|
+ type: String,
|
|
|
+ default: 'tech'
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- // 默认展开所有节点(你可以根据需求改为 false)
|
|
|
isOpen: true
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
- // 判断是否有子节点
|
|
|
hasChildren() {
|
|
|
return this.node.children && this.node.children.length > 0;
|
|
|
}
|
|
|
@@ -65,14 +72,11 @@ export default {
|
|
|
methods: {
|
|
|
handleClick() {
|
|
|
if (this.hasChildren) {
|
|
|
- // 如果有子节点,点击则切换展开/折叠状态
|
|
|
this.isOpen = !this.isOpen;
|
|
|
} else {
|
|
|
- // 如果是叶子节点(最底层路口),触发点击事件,并把当前节点数据传出去
|
|
|
this.$emit('node-click', this.node);
|
|
|
}
|
|
|
},
|
|
|
- // 递归组件极其关键的一步:子组件触发了事件,父组件要继续往上抛,直到最外层
|
|
|
passEventUp(nodeData) {
|
|
|
this.$emit('node-click', nodeData);
|
|
|
}
|
|
|
@@ -81,74 +85,115 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-/* 基础行样式 */
|
|
|
+.menu-item-wrapper {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+/* ================== 公共基础样式 ================== */
|
|
|
.menu-row {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- height: 44px;
|
|
|
- font-size: 14px;
|
|
|
+ min-height: 44px;
|
|
|
+ max-height: 56px;
|
|
|
+ padding: 12px 20px;
|
|
|
cursor: pointer;
|
|
|
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
|
+ background: #081734;
|
|
|
transition: all 0.3s ease;
|
|
|
user-select: none;
|
|
|
}
|
|
|
|
|
|
-/* ================= 核心颜色配置区 ================= */
|
|
|
+.node-icon { margin-right: 8px; font-size: 16px; }
|
|
|
+.node-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
|
+.arrow-icon { margin-left: 10px; display: flex; justify-content: center; align-items: center; color: #909399; transform: rotate(180deg); transition: transform 0.3s ease; }
|
|
|
+.arrow-icon.is-open { transform: rotate(0deg); }
|
|
|
+
|
|
|
|
|
|
-/* 1. 主控中心标题 (顶级菜单 level: 0) 的背景颜色 */
|
|
|
-.menu-row.is-root {
|
|
|
- background-color: #112445; /* 偏亮的深蓝色背景 */
|
|
|
- color: #ffffff; /* 白色字体 */
|
|
|
- font-weight: bold; /* 标题可以稍微加粗 */
|
|
|
+/* ================== 风格 A: 科技渐变风 (theme-tech) ================== */
|
|
|
+
|
|
|
+/* 1. 最外层父节点 (level: 0) */
|
|
|
+.theme-tech.menu-item-wrapper {
|
|
|
+ background: linear-gradient( 180deg, rgba(5,20,46,0) 0%, #05142E 100%);
|
|
|
+}
|
|
|
+.theme-tech .menu-row.level-0 {
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 28px;
|
|
|
+ background: linear-gradient( 180deg, rgba(119,161,255,0) 0%, #77A1FF 100%);
|
|
|
+ border-radius: 2px 0px 0px 2px;
|
|
|
+ border: 1px solid rgba(161,190,255,0.7);
|
|
|
+ font-weight: bold;
|
|
|
}
|
|
|
|
|
|
-/* 2. 其他子菜单 (level > 0) 的背景颜色 */
|
|
|
-.menu-row.is-sub {
|
|
|
- background-color: #0b1a37; /* 更深的暗色背景 */
|
|
|
- color: #ffffff ; /* 浅灰色字体 */
|
|
|
+/* 2. 第二层子节点 (level: 1) */
|
|
|
+.theme-tech .menu-row.level-1 {
|
|
|
+ background: #0f224350;
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 25px;
|
|
|
+ color: #ffffff;
|
|
|
}
|
|
|
|
|
|
-/* 3. 最后一级菜单 (叶子节点) 的特殊样式 */
|
|
|
-.menu-row.is-leaf {
|
|
|
- color: #6b7280; /* 深灰色字体 (覆盖掉上面的浅灰色) */
|
|
|
+/* 3. 包含子节点的目录加粗 */
|
|
|
+.theme-tech .menu-row.is-folder {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 25px;
|
|
|
+ color: #ffffff;
|
|
|
}
|
|
|
|
|
|
-/* ================================================== */
|
|
|
+.theme-tech .menu-row.level-2 {
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 25px;
|
|
|
+ color: rgba(255,255,255, 0.8);
|
|
|
+}
|
|
|
|
|
|
-/* 统一的悬浮效果 */
|
|
|
-.menu-row:hover {
|
|
|
- background-color: rgba(0, 229, 255, 0.1); /* 鼠标放上去给一点科技蓝的反馈 */
|
|
|
- color: #00e5ff; /* 悬浮时文字变亮蓝 */
|
|
|
+/* 4. 叶子节点字体颜色 */
|
|
|
+.theme-tech .menu-row.is-leaf {
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 25px;
|
|
|
+ font-weight: normal;
|
|
|
+ color: #ffffff;
|
|
|
+ background: rgba(8,23,51,0.9);
|
|
|
+ color: rgba(255,255,255, 0.5);
|
|
|
}
|
|
|
|
|
|
-/* 最后一级菜单悬浮时,字体也要变亮,否则看不清 */
|
|
|
-.menu-row.is-leaf:hover {
|
|
|
+/* 5. 悬浮交互 */
|
|
|
+.theme-tech .menu-row:hover {
|
|
|
+ background: #3760A9;
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
+.theme-tech .menu-row.is-leaf:hover { color: #ffffff; }
|
|
|
+
|
|
|
+
|
|
|
+/* ================== 风格 B: 极简暗色风 (theme-dark) ================== */
|
|
|
|
|
|
-.node-icon {
|
|
|
- margin-right: 8px;
|
|
|
- font-size: 16px;
|
|
|
+/* 1. 主控中心标题 (顶级菜单 level: 0) */
|
|
|
+.theme-dark .menu-row.is-root {
|
|
|
+ background-color: #112445;
|
|
|
+ color: #ffffff;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 28px;
|
|
|
}
|
|
|
|
|
|
-.node-label {
|
|
|
- flex: 1; /* 占据剩余空间,把箭头挤到最右边 */
|
|
|
- white-space: nowrap;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
+/* 2. 其他子菜单 (level > 0) */
|
|
|
+.theme-dark .menu-row.is-sub {
|
|
|
+ background-color: #0b1a37;
|
|
|
+ color: #ffffff ;
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 25px;
|
|
|
}
|
|
|
|
|
|
-/* 右侧箭头样式与动画 */
|
|
|
-.arrow-icon {
|
|
|
- margin-right: 20px;
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
- /* 默认箭头朝下 (通过旋转实现) */
|
|
|
- transform: rotate(180deg);
|
|
|
- transition: transform 0.3s ease;
|
|
|
+/* 3. 叶子节点颜色 */
|
|
|
+.theme-dark .menu-row.is-leaf {
|
|
|
+ color: #6b7280;
|
|
|
+ font-weight: normal;
|
|
|
}
|
|
|
|
|
|
-/* 展开状态时,箭头朝上 */
|
|
|
-.arrow-icon.is-open {
|
|
|
- transform: rotate(0deg);
|
|
|
+/* 4. 悬浮交互 */
|
|
|
+.theme-dark .menu-row:hover {
|
|
|
+ background-color: rgba(0, 229, 255, 0.1);
|
|
|
+ color: #00e5ff;
|
|
|
}
|
|
|
+.theme-dark .menu-row.is-leaf:hover { color: #ffffff; }
|
|
|
</style>
|