diff --git a/src/components/menu/menu.js b/src/components/menu/menu.js index 87075a9..f0ff305 100644 --- a/src/components/menu/menu.js +++ b/src/components/menu/menu.js @@ -38,6 +38,26 @@ import {getI18nKey} from '@/utils/routerUtil' const {Item, SubMenu} = Menu +const resolvePath = (path, params = {}) => { + let _path = path + Object.entries(params).forEach(([key, value]) => { + _path = _path.replace(new RegExp(`:${key}`, 'g'), value) + }) + return _path +} + +const toRoutesMap = (routes) => { + const map = {} + routes.forEach(route => { + map[route.fullPath] = route + if (route.children && route.children.length > 0) { + const childrenMap = toRoutesMap(route.children) + Object.assign(map, childrenMap) + } + }) + return map +} + export default { name: 'IMenu', props: { @@ -73,6 +93,9 @@ export default { computed: { menuTheme() { return this.theme == 'light' ? this.theme : 'dark' + }, + routesMap() { + return toRoutesMap(this.options) } }, created () { @@ -132,7 +155,8 @@ export default { }, renderMenuItem: function (h, menu) { let tag = 'router-link' - let config = {props: {to: menu.fullPath}, attrs: {style: 'overflow:hidden;white-space:normal;text-overflow:clip;'}} + const path = resolvePath(menu.fullPath, menu.meta.params) + let config = {props: {to: {path, query: menu.meta.query}, }, attrs: {style: 'overflow:hidden;white-space:normal;text-overflow:clip;'}} if (menu.meta && menu.meta.link) { tag = 'a' config = {attrs: {style: 'overflow:hidden;white-space:normal;text-overflow:clip;', href: menu.meta.link, target: '_blank'}} @@ -200,16 +224,23 @@ export default { }) }, updateMenu () { - const matchedRoutes = this.$route.matched.filter(item => item.path !== '') - this.selectedKeys = this.getSelectedKey(this.$route) - let openKeys = matchedRoutes.map(item => item.path) + this.selectedKeys = this.getSelectedKeys() + let openKeys = this.selectedKeys.filter(item => item !== '') openKeys = openKeys.slice(0, openKeys.length -1) if (!fastEqual(openKeys, this.sOpenKeys)) { this.collapsed || this.mode === 'horizontal' ? this.cachedOpenKeys = openKeys : this.sOpenKeys = openKeys } }, - getSelectedKey (route) { - return route.matched.map(item => item.path) + getSelectedKeys() { + let matches = this.$route.matched + const route = matches[matches.length - 1] + let chose = this.routesMap[route.path] + if (chose.meta && chose.meta.highlight) { + chose = this.routesMap[chose.meta.highlight] + const resolve = this.$router.resolve({path: chose.fullPath}) + matches = (resolve.resolved && resolve.resolved.matched) || matches + } + return matches.map(item => item.path) } }, render (h) { diff --git a/src/utils/routerUtil.js b/src/utils/routerUtil.js index f2d04a3..d16a873 100644 --- a/src/utils/routerUtil.js +++ b/src/utils/routerUtil.js @@ -44,17 +44,31 @@ function parseRoutes(routesConfig, routerMap) { router = typeof item === 'string' ? {path: item, name: item} : item } // 从 router 和 routeCfg 解析路由 + const meta = { + authority: router.authority, + icon: router.icon, + page: router.page, + link: router.link, + params: router.params, + query: router.query, + ...router.meta + } + const cfgMeta = { + authority: routeCfg.authority, + icon: routeCfg.icon, + page: routeCfg.page, + link: routeCfg.link, + params: routeCfg.params, + query: routeCfg.query, + ...routeCfg.meta + } + Object.assign(meta, cfgMeta) const route = { path: routeCfg.path || router.path || routeCfg.router, name: routeCfg.name || router.name, component: router.component, redirect: routeCfg.redirect || router.redirect, - meta: { - authority: routeCfg.authority || router.authority || routeCfg.meta?.authority || router.meta?.authority || '*', - icon: routeCfg.icon || router.icon || routeCfg.meta?.icon || router.meta?.icon, - page: routeCfg.page || router.page || routeCfg.meta?.page || router.meta?.page, - link: routeCfg.link || router.link || routeCfg.meta?.link || router.meta?.link - } + meta: {...meta, authority: meta.authority || '*'} } if (routeCfg.invisible || router.invisible) { route.meta.invisible = true