|
|
@@ -0,0 +1,103 @@
|
|
|
+<template>
|
|
|
+ <aside class="app-sidebar">
|
|
|
+ <div
|
|
|
+ v-for="group in menuGroups"
|
|
|
+ :key="group.key"
|
|
|
+ class="app-sidebar-group"
|
|
|
+ >
|
|
|
+ <div class="app-sidebar-group-title">{{ group.label }}</div>
|
|
|
+ <button
|
|
|
+ v-for="item in group.children"
|
|
|
+ :key="item.key"
|
|
|
+ type="button"
|
|
|
+ class="app-sidebar-item"
|
|
|
+ :class="{ 'is-active': item.key === activeKey }"
|
|
|
+ @click="handleClick(item)"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </aside>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { computed } from "vue";
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
+
|
|
|
+defineOptions({
|
|
|
+ name: "AppSidebar",
|
|
|
+});
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+const menuGroups = [
|
|
|
+ {
|
|
|
+ key: "project",
|
|
|
+ label: "项目管理",
|
|
|
+ children: [
|
|
|
+ { key: "overview", label: "项目概览", routeName: "overview" },
|
|
|
+ { key: "detail", label: "项目明细", routeName: "projectDetail" },
|
|
|
+ { key: "map", label: "一张图", routeName: "oneMap" },
|
|
|
+ { key: "plan", label: "总体计划", routeName: "overallPlan" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: "settings",
|
|
|
+ label: "设置",
|
|
|
+ children: [
|
|
|
+ { key: "permission", label: "权限管理", routeName: "permission" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+const activeKey = computed(() => {
|
|
|
+ const name = route.name;
|
|
|
+ for (const group of menuGroups) {
|
|
|
+ const matched = group.children.find((item) => item.routeName === name);
|
|
|
+ if (matched) return matched.key;
|
|
|
+ }
|
|
|
+ return "overview";
|
|
|
+});
|
|
|
+
|
|
|
+const handleClick = (item) => {
|
|
|
+ if (!item.routeName || item.routeName === route.name) return;
|
|
|
+ router.push({ name: item.routeName });
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.app-sidebar {
|
|
|
+ box-sizing: border-box;
|
|
|
+ flex-shrink: 0;
|
|
|
+ width: 220px;
|
|
|
+ background: #e8edf3;
|
|
|
+ color: #16213a;
|
|
|
+}
|
|
|
+
|
|
|
+.app-sidebar-group {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.app-sidebar-group-title {
|
|
|
+ padding: 16px 16px 8px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #808695;
|
|
|
+}
|
|
|
+
|
|
|
+.app-sidebar-item {
|
|
|
+ margin: 0;
|
|
|
+ padding: 12px 16px;
|
|
|
+ border: none;
|
|
|
+ background: transparent;
|
|
|
+ text-align: left;
|
|
|
+ cursor: pointer;
|
|
|
+ color: inherit;
|
|
|
+
|
|
|
+ &.is-active {
|
|
|
+ background: #d6e6f8;
|
|
|
+ color: #2382e7;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|