• vue-element-admin 实现动态路由(从后台查询出菜单列表绑定侧边栏)


    1. 在路由实例中保留基础路由

    router/index.js中只需要保留基础路由,其他的都删了

    2. 获取用户菜单,并保存到Vuex中

    stroe/modules/user.js中,有个getInfo方法查询用户基本信息,返回了用户的菜单列表

    // get user info
      getInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
          getInfo(state.token).then(response => {
            const { data } = response
            if (!data) {
              reject('Verification failed, please Login again.')
            }
            console.log(data)
            const menus =
            [{
              path: '/books',
              component: 'Layout',
              children: [{
                path: 'index',
                name: 'AddressBook',
                component: 'workbench/addressbook',
                meta: { title: '通讯录', icon: 'company' }
              }]
            },
            {
              path: '/systool',
              component: 'Layout',
              redirect: '/systool/coder',
              name: 'SysTool',
              meta: { title: '实验室', icon: 'example' },
              children: [
                {
                  path: 'calendar',
                  name: 'Calendar',
                  component: 'workbench/calendar',
                  meta: { title: '日程', icon: 'table' }
                }
              ]
            }]
            const { name, avatar, companyName, employeeid } = data
            commit('SET_NAME', name)
            commit('SET_AVATAR', avatar)
            commit('SET_CMPNAME', companyName)
            commit('SET_USERID', employeeid)
            commit('SET_MENUS', menus)
            resolve(data)
          }).catch(error => {
            reject(error)
          })
        })
      }
    user.js
    const getters = {
      sidebar: state => state.app.sidebar,
      device: state => state.app.device,
      token: state => state.user.token,
      avatar: state => state.user.avatar,
      name: state => state.user.name,
      cmpname: state => state.user.cmpname,
      userid: state => state.user.userid,
      menus: state => state.user.menus
    }
    export default getters
    getter.js

    3.动态生成权限路由(核心)

    根据环境配置导入组件,在vue中,将菜单路径作为参数,实现路由地址的注入

    在 src/router 文件夹下,建立两个文件,各只需添加一行代码, 定义导入方法

    src/router/_import_development.js
    //开发环境导入组件
    module.exports = file => require('@/views' + file + '.vue').default // vue-loader at least v13.0.0+
    
    --------------------------------------------------------------------- src/router/_import_production.js
    //生产环境导入组件 module.exports = file => () => import('@/views' + file + '.vue')

    A,组件导入 —— _import

    //获取组件的方法
    const _import = require('./router/_import_' + process.env.NODE_ENV)
    
    // .......
    
    //导入路径下的组件
    route.component = _import(route.path)

    B,在路由钩子中,过滤路由,并生成路由

    核心在src目录下的permission.js中,router.beforeEach路由钩子

      1 import router from './router'
      2 import store from './store'
      3 import {
      4   Message
      5 } from 'element-ui'
      6 import NProgress from 'nprogress' // progress bar
      7 import 'nprogress/nprogress.css' // progress bar style
      8 import {
      9   getToken
     10 } from '@/utils/auth' // get token from cookie
     11 import getPageTitle from '@/utils/get-page-title'
     12 import Layout from '@/layout'
     13 const _import = require('./router/_import_' + process.env.NODE_ENV) // 获取组件的方法
     14 
     15 NProgress.configure({
     16   showSpinner: false
     17 }) // NProgress Configuration
     18 
     19 const whiteList = ['/login'] // no redirect whitelist
     20 
     21 router.beforeEach(async(to, from, next) => {
     22   // start progress bar
     23   NProgress.start()
     24 
     25   // set page title
     26   document.title = getPageTitle(to.meta.title)
     27 
     28   // determine whether the user has logged in
     29   const hasToken = getToken()
     30 
     31   if (hasToken) {
     32     if (to.path === '/login') {
     33       // if is logged in, redirect to the home page
     34       next({
     35         path: '/'
     36       })
     37       NProgress.done()
     38     } else {
     39       const hasGetUserInfo = store.getters.name
     40       if (hasGetUserInfo) {
     41         next()
     42       } else {
     43         try {
     44           // get user info
     45           await store.dispatch('user/getInfo')
     46           if (store.getters.menus.length < 1) {
     47             global.antRouter = []
     48             next()
     49           }
     50           const menus = filterAsyncRouter(store.getters.menus) // 1.过滤路由
     51           router.addRoutes(menus) // 2.动态添加路由
     52           global.antRouter = menus // 3.将路由数据传递给全局变量,做侧边栏菜单渲染工作
     53           next({
     54             ...to,
     55             replace: true
     56           }) // hack方法 确保addRoutes已完成 ,set the replace
     57         } catch (error) {
     58           // remove token and go to login page to re-login
     59           await store.dispatch('user/resetToken')
     60           Message.error(error || 'Has Error')
     61           next(`/login?redirect=${to.path}`)
     62           NProgress.done()
     63         }
     64       }
     65     }
     66   } else {
     67     /* has no token*/
     68 
     69     if (whiteList.indexOf(to.path) !== -1) {
     70       // in the free login whitelist, go directly
     71       next()
     72     } else {
     73       // other pages that do not have permission to access are redirected to the login page.
     74       next(`/login?redirect=${to.path}`)
     75       NProgress.done()
     76     }
     77   }
     78 })
     79 
     80 router.afterEach(() => {
     81   // finish progress bar
     82   NProgress.done()
     83 })
     84 
     85 // 遍历后台传来的路由字符串,转换为组件对象
     86 function filterAsyncRouter(asyncRouterMap) {
     87   const accessedRouters = asyncRouterMap.filter(route => {
     88     if (route.component) {
     89       if (route.component === 'Layout') {
     90         route.component = Layout
     91       } else {
     92         route.component = _import(route.component) // 导入组件
     93       }
     94     }
     95     if (route.children && route.children.length) {
     96       route.children = filterAsyncRouter(route.children)
     97     }
     98     return true
     99   })
    100 
    101   return accessedRouters
    102 }

    4.最后一步,合并路由

  • 相关阅读:
    ThinkPHP 中入口文件中的APP_DEBUG为TRUE时不报错,改为FALSE时报错
    ASP.NET LinqDataSource数据绑定后,遇到[MissingMethodException: 没有为该对象定义无参数的构造函数。]问题。
    error 2593 operator << 不明确的可能的解决方法
    C++读取mysql中utf8mb4编码表数据乱码问题及UTF8转GBK编码
    arcgis flexviewer中由Application向widget传值
    Flash Builder中“Error: #2036 加载未完成”错误的解决方法
    ArcGIS Server API for JavaScript调用错误:已阻止跨源请求:同源策略禁止读取位于......
    Win10下E3-1231 V3开启Intel虚拟化技术(vt-x)安装HAXM
    GPS accuracy in Android
    解决Win7旗舰版开机后无线网络识别非常慢的问题
  • 原文地址:https://www.cnblogs.com/langhaoabcd/p/11346227.html
Copyright © 2020-2023  润新知