Преглед изворни кода

build: 处理子页面时父级菜单高亮

chaooo пре 2 година
родитељ
комит
0e7ac066bc
1 измењених фајлова са 50 додато и 18 уклоњено
  1. 50 18
      src/layout/components/Sidebar/SidebarItem.vue

+ 50 - 18
src/layout/components/Sidebar/SidebarItem.vue

@@ -1,10 +1,10 @@
 <script setup lang="ts">
+import { useRouter, onBeforeRouteUpdate } from "vue-router";
 import path from "path-browserify";
 import { isExternal } from "@/utils/index";
 import AppLink from "./Link.vue";
-
 import SvgIcon from "@/components/SvgIcon/index.vue";
-
+const router = useRouter();
 const props = defineProps({
   /**
    * 路由(eg:level_3_1)
@@ -39,26 +39,22 @@ function hasOneShowingChild(children = [], parent: any) {
       return false; // 过滤不显示的子路由
     } else {
       onlyOneChild.value = item; // 唯一子路由赋值(多个子路由情况 onlyOneChild 变量是用不上的)
-      //console.log(item);
       return true;
     }
   });
-
-  // 1:如果只有一个子路由, 返回 true
+  // 1:如果无显示的子路由, 复制当前路由信息作为其子路由,满足只拥有一个子路由的条件,所以返回 true
+  if (showingChildren.length === 0) {
+    onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
+    return true;
+  }
+  // 2:如果只有一个显示的子路由, 判断子路由children
   if (showingChildren.length === 1) {
     if (showingChildren[0].children) {
-      return hasOneShowingChild(
-        showingChildren[0].children,
-        showingChildren[0]
-      );
-    } else {
-      return true;
+      // 是否还有可显示的子路由
+      if (hasOneShowingChild(showingChildren[0].children, showingChildren[0])) {
+        return true;
+      }
     }
-  }
-
-  // 2:如果无子路由, 复制当前路由信息作为其子路由,满足只拥有一个子路由的条件,所以返回 true
-  if (showingChildren.length === 0) {
-    onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
     return true;
   }
   return false;
@@ -80,6 +76,39 @@ function resolvePath(routePath: string) {
   const fullPath = path.resolve(props.basePath, routePath); // 相对路径 → 绝对路径
   return fullPath;
 }
+
+/**
+ * 处理子页面时父级菜单高亮
+ */
+function addActiveClass(routePath) {
+  const currentBase = routePath.split("/")[1];
+  document.querySelectorAll(".el-menu-item").forEach((item) => {
+    const pathBase = item.attributes["mack"].value.split("/")[1];
+    if (currentBase == pathBase) {
+      if (document.querySelector(".el-menu-item.is-active")) {
+        document
+          .querySelector(".el-menu-item.is-active")
+          .classList.remove("is-active");
+      }
+      item.classList.add("is-active");
+      //console.log(currentBase, "is-active current路由");
+      return;
+    }
+  });
+}
+
+router.afterEach((to, from) => {
+  //console.log(to.fullPath, "路由变动");
+  setTimeout(() => {
+    addActiveClass(to.fullPath);
+  }, 100);
+});
+if (onMounted) {
+  onMounted(() => {
+    addActiveClass(router.currentRoute.value.fullPath);
+    //console.log(router.currentRoute.value.fullPath,"当前路由");
+  });
+}
 </script>
 <template>
   <div v-if="!item.meta || !item.meta.hidden">
@@ -91,7 +120,10 @@ function resolvePath(routePath: string) {
     >
       <!-- 只包含一个子路由节点的路由,显示其【唯一子路由】 -->
       <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
-        <el-menu-item :index="resolvePath(onlyOneChild.path)">
+        <el-menu-item
+          :index="resolvePath(onlyOneChild.path)"
+          :mack="resolvePath(onlyOneChild.path)"
+        >
           <svg-icon
             v-if="onlyOneChild.meta && onlyOneChild.meta.icon"
             :icon-class="onlyOneChild.meta.icon"
@@ -103,7 +135,7 @@ function resolvePath(routePath: string) {
       </app-link>
     </template>
     <el-sub-menu v-else :index="resolvePath(item.path)" teleported>
-      <!-- 包含多个子路由  -->
+      <!-- 包含多个子路由 $route.path  -->
       <template #title>
         <svg-icon
           v-if="item.meta && item.meta.icon"