依照
iView-admin2.0动态菜单路由【版1】 归纳几个节点
动态路由获取方式2 ——> easymock假数据 ——> 数据转组件处理、addRoutes ——> localStorage存储 ——> 动态路由path刷新
修改操作--关于动态路由
1. 删掉src/main.js中mounted调用的初始化动态路由函数initRouter()——————即没做修改的初状态写法即可 ,【版1】去掉修改src/main.js的步骤
2.新增src/libs/router-util.js做请求动态路由的数据处理,转为路由组件,commit更新updateMenuList[写在src/store/module/app.js]左侧菜单并addRoutes到路由表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * ①添 * @@新增 定义初始化菜单 */ import { getToken, localSave, localRead } from '@/libs/util' // import config from '@/config' import store from '@/store' import { lazyLoadingCop } from '@/libs/tools' import { mockAntRouter } from '@/api/mockApi' import Main from '@/components/main' // Main 是架构组件,不在后台返回,在文件里单独引入 import parentView from '@/components/parent-view' // parentView 是二级架构组件,不在后台返回,在文件里单独引入 // const _import = require('@/router/_import_' + process.env.NODE_ENV)// 获取组件的方法 var gotRouter // 初始化路由 export const initRouter = () => { let antRouter = localRead('dynamicRouter'); if (!antRouter) { mockAntRouter().then(res => { if (res.status === 200) { var routerData = res.data.router // 后台拿到路由 localSave('dynamicRouter', JSON.stringify(routerData)) // 存储路由到localStorage gotRouter = filterAsyncRouter(routerData) // 过滤路由,路由组件转换 store.commit('updateMenuList', gotRouter); dynamicRouterAdd() } else { console.log('请求失败') } }) } else { gotRouter = dynamicRouterAdd() } return gotRouter } // 加载路由菜单,从localStorage拿到路由,在创建路由时使用 export const dynamicRouterAdd = () => { let dynamicRouter = [] let data = localRead('dynamicRouter') if (!data) { return dynamicRouter } dynamicRouter = filterAsyncRouter(JSON.parse(data)) return dynamicRouter } // @函数: 遍历后台传来的路由字符串,转换为组件对象 export const filterAsyncRouter = (asyncRouterMap) => { const accessedRouters = asyncRouterMap.filter(route => { if (route.component) { if (route.component === 'Main') { // Main组件特殊处理 route.component = Main } else if (route.component === 'parentView') { // parentView组件特殊处理 route.component = parentView } else { // route.component = _import(route.component) route.component = lazyLoadingCop(route.component) } } if (route.children && route.children.length) { route.children = filterAsyncRouter(route.children) } return true }) return accessedRouters }
附加1. src/libs/tools.js增加 引入组件 封装函数lazyLoadingCop (此demo暂以此方式)
// @函数: 引入组件 export const lazyLoadingCop = file => require('@/view/' + file + '.vue').default
附加2. src/router中新增_import_development.js和_import_production.js为引入.vue组件的封装【俩种环境】
_import_development.js
module.default = file => require('@/view/' + file + '.vue').default // vue-loader at least v13.0.0+
_import_production.js
module.exports = file => () => import('@/view/' + file + '.vue')
3.修改src/store/module/app.js中getters的menuList函数,左侧显示动态获取的[这样减少了字段hideInMenu,同时menuList存储量也减少了默认的router]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { . getMenuByRouter, . . localSave, localRead } from '@/libs/util' . . import { dynamicRouterAdd } from '@/libs/router-util' // ①添 引入加载菜单 . . export default { state: { . tagNavList: [], . . menuList: [] }, getters: { // menuList: (state, getters, rootState) => getMenuByRouter(routers, rootState.user.access),//初始 menuList: (state, getters, rootState) => getMenuByRouter(dynamicRouterAdd(), rootState.user.access), // ①改 通过路由列表得到菜单列表 }, mutations: { . . updateMenuList (state, routes) { // ①添 接受前台数组,刷新菜单 console.log(state, routes, 'updateMenuList') router.addRoutes(routes); // 动态添加路由 state.menuList = routes; } }, . . }
4.src/router/router.js引入dynamicRouterAdd,在routes初始创建时调用dynamicRouterAdd()服务于减少动态路由的异步请求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import Main from '@/components/main' import { dynamicRouterAdd } from '@/libs/router-util' // ①添 引入加载菜单 /** * iview-admin中meta除了原生参数外可配置的参数: * meta: { * title: { String|Number|Function } * 显示在侧边栏、面包屑和标签栏的文字 * 使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置; * 可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由 * hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置 * hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项 * notCache: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致 * access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由 * icon: (-) 该页面在左侧菜单、面包屑和标签导航处显示的图标,如果是自定义图标,需要在图标名称前加下划线'_' * beforeCloseName: (-) 设置该字段,则在关闭当前tab页时会去'@/router/before-close.js'里寻找该字段名对应的方法,作为关闭前的钩子函数 * } */ // 不作为Main组件的子页面展示的页面单独写 export const otherRouter = [{ path: '/login', name: 'login', meta: { title: 'Login - 登录', hideInMenu: true }, component: () => import('@/view/login/login.vue') }, { path: '/401', name: 'error_401', meta: { hideInMenu: true }, component: () => import('@/view/error-page/401.vue') }, { path: '/500', meta: { title: '500-服务端错误' }, name: 'error_500', component: () => import('@/view/error-page/500.vue') } ]; // 作为Main组件的子页面展示但是不在左侧菜单显示的路由写在mainRouter里 export const mainRouter = [{ path: '/', name: '_home', redirect: '/home', component: Main, meta: { hideInMenu: true, notCache: true }, children: [ { path: '/home', name: 'home', meta: { hideInMenu: true, title: '首页', notCache: true, icon: 'md-home' }, component: () => import('@/view/single-page/home') } ] }, { path: '/message', name: 'message', component: Main, meta: { hideInBread: true, hideInMenu: true }, children: [ { path: 'message_page', name: 'message_page', meta: { icon: 'md-notifications', title: '消息中心' }, component: () => import('@/view/single-page/message/index.vue') } ] }]; // 作为Main组件的子页面展示并且在左侧菜单显示的路由写在appRouter里 export const appRouter = [...dynamicRouterAdd()]; export const routes = [ ...otherRouter, ...mainRouter, ...appRouter ] // 所有上面定义的路由都要写在下面输出 export default routes
5.src/router/index.js引入initRouter,在router.beforeEach路由跳转前调用initRouter()服务于动态路由页的跳转/刷新
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
. . . import { initRouter } from '@/libs/router-util' . . router.beforeEach((to, from, next) => { . if (!token && to.name !== LOGIN_PAGE_NAME) { . . . } else { initRouter() . . . } }) . . export default router
6.src/store/module/user.js引入initRouter,在handleLogin登录时调用initRouter()用于初始请求动态路由及其处理等;在handleLogOut登出时localSave('dynamicRouter',[])清空本地存储localStorage中的dynamicRouter
附加. 登出操作清空tagNaveList快捷导航:src/store/module/user.js中,handleLogOut登出时localSave('tagNaveList',[]) //清空localStorage中的tagNaveList记录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
. . import { initRouter } from '@/libs/router-util' // ①添 引入加载菜单 export default { . . . actions: { // 登录 handleLogin ({ commit }, { userName, password }) { userName = userName.trim() return new Promise((resolve, reject) => { login({ userName, password }).then(res => { . . initRouter() . . }).catch(err => { reject(err) }) }) }, // 退出登录 handleLogOut ({ state, commit }) { return new Promise((resolve, reject) => { logout(state.token).then(() => { . . . localSave('dynamicRouter',[]) localSave('tagNaveList',[]) //清空localStorage中的tagNaveList记录 resolve() }).catch(err => { reject(err) }) . }) } . . . } }
修改操作--其他
7.左侧菜单显示中文,是否使用国际化vue-i18n:默认为false。 src/config/index.js中修改useI18n: false
经过反复测试,此修复版动态路由菜单成功显示,跳转,刷新,清空。
喜欢就点个推荐吧~