【vue】iView-admin2.0動態菜單路由【版2】


依照
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到路由表 

/**
 * ①添
 * @@新增 定義初始化菜單
 */

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
}
View Code

    附加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]

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;
    }
  },
    . 
    .
}
View Code

4.src/router/router.js引入dynamicRouterAdd,在routes初始創建時調用dynamicRouterAdd()服務於減少動態路由的異步請求

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
View Code

5.src/router/index.js引入initRouter,在router.beforeEach路由跳轉前調用initRouter()服務於動態路由頁的跳轉/刷新

.
.
.
import { initRouter } from '@/libs/router-util'

.
.

router.beforeEach((to, from, next) => {
.
  if (!token && to.name !== LOGIN_PAGE_NAME) {
.
.
.
  } else {
    initRouter()
.
.
.
  }
})

.
.

export default router
View Code

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記錄

.
.
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)
        })
.
      })
    }
.
.
.
  }
}
View Code

修改操作--其他

7.左側菜單顯示中文,是否使用國際化vue-i18n:默認為false。 src/config/index.js中修改useI18n: false

 

經過反復測試,此修復版動態路由菜單成功顯示,跳轉,刷新,清空。

喜歡就點個推薦吧~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM