依照
iView-admin2.0動態菜單路由【版1】 概括幾個節點
動態路由獲取方式2 ——> easymock假數據 ——> 數據轉組件處理、addRoutes ——> localStorage存儲 ——> 動態路由path刷新
/** * ①添 * @@新增 定義初始化菜單 */ 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 }
// @函數: 引入組件 export const lazyLoadingCop = file => require('@/view/' + file + '.vue').default
_import_development.jshtml
module.default = file => require('@/view/' + file + '.vue').default // vue-loader at least v13.0.0+
_import_production.jsvue
module.exports = file => () => import('@/view/' + file + '.vue')
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()服務於減小動態路由的異步請求api
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
. . . import { initRouter } from '@/libs/router-util' . . router.beforeEach((to, from, next) => { . if (!token && to.name !== LOGIN_PAGE_NAME) { . . . } else { initRouter() . . . } }) . . export default router
附加. 登出操做清空tagNaveList快捷導航:src/store/module/user.js中,handleLogOut登出時localSave('tagNaveList',[]) //清空localStorage中的tagNaveList記錄數組
. . 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緩存
通過反覆測試,此修復版動態路由菜單成功顯示,跳轉,刷新,清空。架構
喜歡就點個推薦吧~app