浏览代码

route almost completed - wait constant-routes config

hare8999@163.com 2 年之前
父节点
当前提交
8138be613b
共有 2 个文件被更改,包括 80 次插入24 次删除
  1. 2 12
      src/layout/components/Sidebar/index.vue
  2. 78 12
      src/store/modules/mx-permission.js

+ 2 - 12
src/layout/components/Sidebar/index.vue

@@ -33,15 +33,9 @@ export default {
   components: { SidebarItem, Logo },
   computed: {
     ...mapState(['settings']),
-    ...mapGetters(['sidebarRouters', 'sidebar']),
+    ...mapGetters(['sidebarRouters', 'sidebar', 'activeSidePath']),
     activeMenu() {
-      const route = this.$route
-      const { meta, path } = route
-      // if set path, the sidebar will highlight the path you set
-      if (meta.activeMenu) {
-        return meta.activeMenu
-      }
-      return path
+      return this.activeSidePath
     },
     showLogo() {
       return this.$store.state.settings.sidebarLogo
@@ -58,10 +52,6 @@ export default {
       fal: false
     }
   },
-  watch: {
-    $route: function(route) {
-    }
-  },
   methods: {
     activeMenuList(data, activeMenu) {
       data.forEach((item) => {

+ 78 - 12
src/store/modules/mx-permission.js

@@ -38,20 +38,29 @@ const permission = {
       state.routes = constantRoutes.concat(routes)
       state.routeCache[token] = routes
     },
-    SET_TOPBAR_ROUTES: (state, routes) => {
+    SET_TOPBAR_ROUTERS: (state, routes) => {
       state.topbarRouters = routes
     },
-    SET_MIDDLE_ROUTES: (state, routes) => {
-      state.middlebarRoutes = routes
+    SET_MIDDLEBAR_ROUTERS: (state, routes) => {
+      state.middlebarRouters = routes
     },
     SET_SIDEBAR_ROUTERS: (state, routes) => {
       state.sidebarRouters = routes
     },
-    SET_IS_WIDESCREEN: (state, routes) => {
-      state.isWideScreen = routes
+    SET_IS_WIDESCREEN: (state, trueOrFalse) => {
+      state.isWideScreen = trueOrFalse
     },
     SET_CURRENT_ROUTE: (state, route) => {
       state.currentRoute = route
+    },
+    SET_ACTIVE_TOP_PATH: (state, path) => {
+      state.activeTopPath = path
+    },
+    SET_ACTIVE_MIDDLE_PATH: (state, path) => {
+      state.activeMiddlePath = path
+    },
+    SET_ACTIVE_SIDE_PATH: (state, path) => {
+      state.activeSidePath = path
     }
   },
   actions: {
@@ -76,7 +85,7 @@ const permission = {
 
           // 目前只能确定全局路由与top路由,middle/side需要等路由跳转
           commit('SET_ROUTES', { routes: addRoutes, token })
-          commit('SET_TOPBAR_ROUTES', topRoutes)
+          commit('SET_TOPBAR_ROUTERS', topRoutes)
           router.addRoutes(addRoutes)
           routeAdded = !!addRoutes.length
           resolve(routeAdded)
@@ -85,19 +94,60 @@ const permission = {
     },
     SetLocation({ commit, state }, { to, from }) {
       // 定位路由,显示合适的菜单
-      console.log('receive set-location request', to, from)
+      // console.log('receive set-location request', to, from)
       commit('SET_CURRENT_ROUTE', to)
+      commit('SET_IS_WIDESCREEN', to.meta?.isWideScreen)
       // 现在开始设置top/middle/side三级的当前路由
       // 有两项任务,1是要设置菜单集合,2是设置当前菜单
-      const parentPath = to._parentPath
-
+      const topRoutes = state.topbarRouters
+      const ancestors = { fullMatched: false, matches: [] }
+      let targetPath = to.path
+      traceAncestorRoutesInMenus(topRoutes, targetPath, ancestors)
+      if (!ancestors.fullMatched && to._parentPath) {
+        targetPath = to._parentPath
+        ancestors.matches.length = 0 // clear for re-trace
+        traceAncestorRoutesInMenus(topRoutes, targetPath, ancestors)
+      }
+
+      // 完全匹配,开始操作菜单
+      if (ancestors.fullMatched) {
+        const activeCommits = [
+          {
+            name: 'SET_ACTIVE_TOP_PATH',
+            getPath: (routes, idx) => routes[idx]?.path || ''
+          },
+          {
+            name: 'SET_ACTIVE_MIDDLE_PATH',
+            getPath: (routes, idx) => routes[idx]?.path || ''
+          },
+          {
+            name: 'SET_ACTIVE_SIDE_PATH',
+            getPath: (routes, idx) => (routes[idx] && routes.last())?.path || ''
+          }]
+        // 设置高亮菜单
+        activeCommits.forEach((config, idx) => {
+          commit(config.name, config.getPath(ancestors.matches, idx))
+        })
+        // 设置middle/side菜单集合
+        const topMatch = ancestors.matches[0]
+        if (topMatch) {
+          commit('SET_MIDDLEBAR_ROUTERS', topMatch.children || [])
+          commit('SET_SIDEBAR_ROUTERS', []) // 先清空,可能立即又会被后续代码赋值
+        } else {
+          commit('SET_MIDDLEBAR_ROUTERS', [])
+          commit('SET_SIDEBAR_ROUTERS', [])
+        }
+        const middleMatch = ancestors.matches[1]
+        if (middleMatch) {
+          commit('SET_SIDEBAR_ROUTERS', middleMatch.children || [])
+        }
+      }
     },
     RemoveRoutes({ commit }) {
       commit('REMOVE_ROUTES')
     },
     AccessDeepMenu({ commit }, route) {
       const path = route._firstLeafPath || route.path
-      // noinspection ES6ShorthandObjectProperty
       router.push(path)
     }
   }
@@ -177,8 +227,24 @@ function handleAsyncRouterLocalReference(route, parent, level) {
   route.children?.forEach(child => handleAsyncRouterLocalReference(child, route, level + 1))
 }
 
-function traceAncestorRoutes(rootRoutes, targetPath) {
-
+function traceAncestorRoutesInMenus(routes, path, ancestors) {
+  // 从routes中找到目标路径,才算完全成功
+  const fullMath = routes.first(r => r.path == path)
+  if (fullMath) {
+    ancestors.fullMatched = true
+    ancestors.matches.push(fullMath)
+    return
+  }
+  const partialMath = routes.first(r => path.startsWith(r.path))
+  if (partialMath) {
+    ancestors.fullMatched = false
+    ancestors.matches.push(partialMath)
+
+    // 继续往下找
+    if (partialMath.children?.length) {
+      traceAncestorRoutesInMenus(partialMath.children, path, ancestors)
+    }
+  }
 }
 
 export const loadView = (view) => { // 路由懒加载