新增:路由配置增加动态路由参数支持 和 高亮菜单配置;
| | |
| | | |
| | | 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: { |
| | |
| | | computed: { |
| | | menuTheme() { |
| | | return this.theme == 'light' ? this.theme : 'dark' |
| | | }, |
| | | routesMap() { |
| | | return toRoutesMap(this.options) |
| | | } |
| | | }, |
| | | created () { |
| | |
| | | }, |
| | | 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'}} |
| | |
| | | }) |
| | | }, |
| | | 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) { |
| | |
| | | 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 |