Browse Source

✨ 菜单可多层嵌套

晓晓晓晓丶vv 4 years ago
parent
commit
3652155884
6 changed files with 100 additions and 17 deletions
  1. 51 0
      src/layout/components/AppSubMenu.vue
  2. 19 16
      src/layout/index.vue
  3. 20 0
      src/router/async.ts
  4. 4 1
      src/views/Page3.vue
  5. 3 0
      src/views/Page5.vue
  6. 3 0
      src/views/Page6.vue

+ 51 - 0
src/layout/components/AppSubMenu.vue

@@ -0,0 +1,51 @@
+<template>
+  <a-sub-menu class="nav-item"
+              :key="menus.path"
+              :title="menus.meta.title">
+    <template v-for="child in menus.children">
+      <template v-if="child.children">
+        <app-sub-menu :menus="child"
+                      :parent-path="formatRoutes(child.path, parentPath)"
+                      :key="formatRoutes(child.path, parentPath)" />
+      </template>
+      <template v-else>
+        <router-link :key="formatRoutes(child.path, parentPath)"
+                     :to="formatRoutes(child.path, parentPath)"
+                     custom
+                     v-slot={navigate}>
+          <a-menu-item>
+            <p @click.stop="navigate">{{child.meta.title}}</p>
+          </a-menu-item>
+        </router-link>
+      </template>
+    </template>
+  </a-sub-menu>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+
+import { pathResolve } from "@/helper";
+
+const AppSubMenu = defineComponent({
+  name: "AppSubMenu",
+  props: {
+    menus: {
+      type: Object,
+      default: () => [],
+    },
+    parentPath: String,
+  },
+  setup(props) {
+    console.log(props.menus);
+    const formatRoutes = (path: string, base: string = "/") =>
+      pathResolve(path, base);
+
+    return {
+      formatRoutes,
+    };
+  },
+});
+
+export default AppSubMenu;
+</script>

+ 19 - 16
src/layout/index.vue

@@ -13,19 +13,10 @@
                 :selected-keys="menuActive">
           <template v-for="route in filterRoutes">
             <template v-if="route.children && route.children.length">
-              <a-sub-menu class="nav-item"
-                          :key="route.path"
-                          :title="route.meta.title">
-                <router-link v-for="child in route.children"
-                             :key="formatRoutes(child.path, route.path)"
-                             :to="formatRoutes(child.path, route.path)"
-                             custom
-                             v-slot={navigate}>
-                  <a-menu-item>
-                    <p @click.stop="navigate">{{child.meta.title}}</p>
-                  </a-menu-item>
-                </router-link>
-              </a-sub-menu>
+              <app-sub-menu class="nav-item"
+                            :menus="route"
+                            :parent-path="route.path"
+                            :key="route.path" />
             </template>
             <template v-else>
               <router-link :key="route.path"
@@ -56,6 +47,7 @@
 import { computed, defineComponent, reactive, ref, toRefs } from "vue";
 
 import appHeader from "./components/AppHeader.vue";
+import appSubMenu from "./components/AppSubMenu.vue";
 
 import useApp from "@/hooks/useApp";
 import { pathResolve } from "@/helper/index";
@@ -66,13 +58,11 @@ import { RouteConfig } from "@/types/route";
 const LayoutComponent = defineComponent({
   components: {
     appHeader,
+    appSubMenu,
   },
   setup() {
     const { store, route, router } = useApp();
 
-    // 待优化
-    let openKeys = ref(["/" + route.path.substr(1).split("/")[0]]);
-
     const data = reactive({
       navRoutes: computed(() => store.getters.permissionRoutes),
       roles: computed(() => store.getters.userRoles),
@@ -99,6 +89,19 @@ const LayoutComponent = defineComponent({
       return icon_url;
     };
 
+    const onCalcOpenKeys = () => {
+      const routeArr = route.path.split("/");
+      let openKeys: string[] = [];
+      routeArr.forEach((r) => {
+        routeArr.pop();
+        let target = routeArr.join("/");
+        openKeys.push(target);
+      });
+      return openKeys;
+    };
+    // 待优化
+    let openKeys = ref(onCalcOpenKeys());
+
     return {
       ...toRefs(data),
       openKeys,

+ 20 - 0
src/router/async.ts

@@ -25,6 +25,26 @@ export const Page2: RouteConfig = {
         title: "Page 3",
         roles: ["admin"],
       },
+      children: [
+        {
+          name: "Page5",
+          path: "page5",
+          meta: {
+            title: "Page 5",
+            roles: ["admin"],
+          },
+          component: () => import("@/views/Page5.vue"),
+        },
+        {
+          name: "Page6",
+          path: "page6",
+          meta: {
+            title: "Page 6",
+            roles: ["admin"],
+          },
+          component: () => import("@/views/Page6.vue"),
+        },
+      ],
       component: () => import("@/views/Page3.vue"),
     },
     {

+ 4 - 1
src/views/Page3.vue

@@ -1,3 +1,6 @@
 <template>
-  <div>page 3</div>
+  <div>
+    <div>page 3</div>
+    <router-view></router-view>
+  </div>
 </template>

+ 3 - 0
src/views/Page5.vue

@@ -0,0 +1,3 @@
+<template>
+  <div>page 5</div>
+</template>

+ 3 - 0
src/views/Page6.vue

@@ -0,0 +1,3 @@
+<template>
+  <div>Page 6</div>
+</template>