[已实现] iview-admin动态加载路由修改方法 · Issue #1158 · iview/iview-admin · GitHub
- -本示例基于iview-admin的template分支修改,其他分支应该也是支持的,通过mock方式模拟后台数据,将mock数据更改为自己的后端数据格式,转换方法稍加修改即可. @/mock/login.js中增加数据. 直接将@router/routers.js中,home节点到404节点之间的数据 __剪切 __过去即可.
本示例基于iview-admin的template分支修改,其他分支应该也是支持的,通过mock方式模拟后台数据,将mock数据更改为自己的后端数据格式,转换方法稍加修改即可
直接将@router/routers.js中,home节点到404节点之间的数据 __剪切 __过去即可
export const getUserMenus = req => { return [ // 粘贴到这里就可以了 // 需要把所有的component: () => import('@/view/**/*.vue') // 修改为component: 'view/**/*.vue' // 注意main和parent-view { path: '', name: 'doc', meta: { title: '文档', href: 'https://lison16.github.io/iview-admin-doc/#/', icon: 'ios-book' } }, { path: '/multilevel', name: 'multilevel', meta: { icon: 'md-menu', title: '多级菜单' }, component: 'components/main', children: [ { path: 'level_2_1', name: 'level_2_1', meta: { icon: 'md-funnel', title: '二级-1' }, component: 'view/multilevel/level-2-1.vue' }, { path: 'level_2_2', name: 'level_2_2', meta: { access: ['super_admin'], icon: 'md-funnel', showAlways: true, title: '二级-2' }, component: 'components/parent-view', children: [ { path: 'level_2_2_1', name: 'level_2_2_1', meta: { icon: 'md-funnel', title: '三级' }, component: 'view/multilevel/level-2-2/level-3-1.vue' } ] }, { path: 'level_2_3', name: 'level_2_3', meta: { icon: 'md-funnel', title: '二级-3' }, component: 'view/multilevel/level-2-3.vue' } ] } ] }
Mock.mock(/\/get_user_menus/, getUserMenus)
export const listUserMenus = () => { return axios.request({ url: 'get_user_menus', method: 'get' }) }
/** * @description 将后端菜单树转换为路由树 * @param {Array} menus * @returns {Array} */ export const backendMenusToRouters = (menus) => { let routers = [] forEach(menus, (menu) => { // 将后端数据转换成路由数据 let route = backendMenuToRoute(menu) // 如果后端数据有下级,则递归处理下级 if (menu.children && menu.children.length !== 0) { route.children = backendMenusToRouters(menu.children) } routers.push(route) }) return routers } /** * @description 将后端菜单转换为路由 * @param {Object} menu * @returns {Object} */ const backendMenuToRoute = (menu) => { // 具体内容根据自己的数据结构来定,这里需要注意的一点是 // 原先routers写法是component: () => import('@/view/error-page/404.vue') // 经过json数据转换,这里会丢失,所以需要按照上面提过的做转换,下面只写了核心点,其他自行处理 let route = Object.assign({}, menu) route.component = () => import(`@/${menu.component}`) return route }
export default { state: { routers: [], hasGetRouter: false }, getters: { menuList: (state) => (state, getters, rootState) => getMenuByRouter(state.routers, rootState.user.access), }, mutations: { setRouters (state, routers) { state.routers = routers }, setHasGetRouter (state, status) { state.hasGetRouter = status } }, actions: { getRouters ({ commit }) { return new Promise((resolve, reject) => { try { listUserMenus().then(res => { let routers = backendMenusToRouters(res.data) commit('setRouters', routers) commit('setHasGetRouter', true) resolve(routers) }).catch(err => { reject(err) }) } catch (error) { reject(error) } }) } } }
const turnTo = (to, access, next) => { if (canTurnTo(to.name, access, store.state.app.routers.concat(routes))) next() // 有权限,可访问 else next({ replace: true, name: 'error_401' }) // 无权限,重定向到401页面 } // 修改这部分代码 if (store.state.user.hasGetInfo && store.state.app.hasGetRouter) { turnTo(to, store.state.user.access, next) } else { // 加载用户信息 store.dispatch('getUserInfo').then(user => { // 加载用户菜单 store.dispatch('getRouters').then(routers => { // commonRoutes需要追加到路由解析最后的404,把原先的routers.js中的404删掉即可 router.addRoutes(routers.concat([ { path: '*', name: 'error_404', meta: { hideInMenu: true }, component: () => import('@/view/error-page/404.vue') } ])) next({ ...to }) }) }).catch(() => { setToken('') next({ name: 'login' }) }) }
需要修改注销的代码,注销成功后跳转到登录页面,这样可以起到强制刷新的作用,清空缓存的routers
logout () { this.handleLogOut().then(() => { window.location = '/login' })