使用vue-element-admin框架从后端动态获取菜单功能的实现

2022-04-15 0 822
目录
  • 2、详解
    • 2.1、新增asyncRoutes路由
    • 2.2、新建permission.js文件
    • 2.3、在vuex中注册permission模块
    • 2.4、在getters中增加路由状态
    • 2.5、修改菜单生成数据来源
    • 2.6、登陆后获取菜单
    • 2.7、解决刷新后页面空白
  • 3、总结

    2、详解

    ​整体思路为:登陆 > 成功后根据用户信息获取菜单 > 根据菜单生成路由信息

    2.1、新增asyncRoutes路由

    ​在vue-router路径src\router\index.js中新增asyncRoutes数组,用来存放后端获取的菜单对应的路由信息。

    export const asyncRoutes = [
      { path: '*', redirect: '/404', hidden: true }
    ]

    使用vue-element-admin框架从后端动态获取菜单功能的实现

    constantRoutes和asyncRoutes的区别

    constantRoutes:不需要动态判断权限的路由,如登录页、404等通用页面。

    asyncRoutes:需求动态判断权限并通过addRoutes动态添加的页面

    2.2、新建permission.js文件

    ​在vuex路径src\store\modules\permission.js下新建permission.js文件,该操作为最重要的一步,主要是从后端查询菜单并生成路由。

    import { asyncRoutes, constantRoutes } from '@/router'
    import { fetchUserMenuList } from '@/api/user'
    import Layout from '@/layout'
    
    /**
     * 静态路由懒加载
     * @param view  格式必须为 xxx/xxx 开头不要加斜杠
     * @returns 
     */
    export const loadView = (view) => {
      return (resolve) => require([`@/views/${view}.vue`], resolve)
    }
    
    /**
     * 把从后端查询的菜单数据拼装成路由格式的数据
     * @param routes
     * @param data 后端返回的菜单数据
     */
    export function generaMenu(routes, data) {
      data.forEach(item => {
        const menu = {
          path: item.url, 
          component: item.component === '#' ? Layout : loadView(item.component), 
          hidden: item.status === 0, // 状态为0的隐藏
          redirect: item.redirect,
          children: [],
          name: item.code,
          meta: item.meta
        }
    
        if (item.children) {
          generaMenu(menu.children, item.children)
        }
        routes.push(menu)
      })
      return routes
    }
    
    const state = {
      routes: [],
      addRoutes: []
    }
    
    const mutations = {
      SET_ROUTES: (state, routes) => {
        state.addRoutes = routes
        // 拼接静态路由和动态路由
        state.routes = constantRoutes.concat(routes)
      }
    }
    
    const actions = {
      generateRoutes({ commit }, token) {
        return new Promise(resolve => {
          // 通过token从后端获取用户菜单,并加入全局状态
          fetchUserMenuList(token).then(res => {
            const menuData = Object.assign([], res.data)
            const tempAsyncRoutes = Object.assign([], asyncRoutes)
            const accessedRoutes = generaMenu(tempAsyncRoutes, menuData)
    
            commit('SET_ROUTES', accessedRoutes)
            resolve(accessedRoutes)
          }).catch(error => {
            console.log(error)
          })
        })
      }
    }
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions
    }
    

    2.3、在vuex中注册permission模块

    ​如果使用的是vue-element-admin请跳过此步,因为它在src\store\index.js中自动注册了src\store\modules下的所有模块。如果你使用的是vue-element-template,可以参考admin,将index.js文件改造一下,也可以手动import一下。

    import Vue from 'vue'
    import Vuex from 'vuex'
    import getters from './getters'
    
    Vue.use(Vuex)
    
    // https://webpack.js.org/guides/dependency-management/#requirecontext
    const modulesFiles = require.context('./modules', true, /\.js$/)
    
    // you do not need `import app from './modules/app'`
    // it will auto require all vuex module from modules file
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
      // set './app.js' => 'app'
      const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
      const value = modulesFiles(modulePath)
      modules[moduleName] = value.default
      return modules
    }, {})
    
    const store = new Vuex.Store({
      modules,
      getters
    })
    
    export default store

    2.4、在getters中增加路由状态

    ​在vuex路径src\store\getters.js添加menusRoutes状态

    menusRoutes: state => state.permission.routes

    使用vue-element-admin框架从后端动态获取菜单功能的实现

    2.5、修改菜单生成数据来源

    ​在路径src\layout\components\Sidebar\index.vue修改routes数据来源,原来数据源是路由,改为从vuex中获取。

    routes() {
          // return this.$router.options.routes
          return this.$store.getters.menusRoutes
        },

    使用vue-element-admin框架从后端动态获取菜单功能的实现

    ​至此,从后端获取菜单数据到页面展示的逻辑已经完毕,下面开始在登陆后进行调用。

    2.6、登陆后获取菜单

    ​在vuex路径src\store\modules\user.js的login方法中,加入登陆成功通过token获取菜单生成路由逻辑。

     // 获取菜单,调用其他文件中actions时必须加 { root: true }
              dispatch('permission/generateRoutes', data, { root: true }).then((accessRoutes) => {
                router.addRoutes(accessRoutes)
              })

    使用vue-element-admin框架从后端动态获取菜单功能的实现

    2.7、解决刷新后页面空白

    ​以上内容已经可以实现登陆后展示左侧菜单功能,但是会发现每次刷新页面后,页面都会变空白。这是因为在页面刷新时,会重新加载vue实例,vuex的store中的数据会被重新赋值,导致我们存在vuex中的路由信息被清空。

    ​在src\permission.js中增加重新获取路由代码。

    const accessRoutes = await store.dispatch('permission/generateRoutes', store.getters.token)
              router.addRoutes(accessRoutes)
              next({ ...to, replace: true })
    

    使用vue-element-admin框架从后端动态获取菜单功能的实现

    3、总结

    ​至此根据用户信息动态获取菜单内容已经全部完成。

    到此这篇关于使用vue-element-admin框架从后端动态获取菜单的文章就介绍到这了,更多相关vue-element-admin动态获取菜单内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

    免责声明:
    1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

    2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
    如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
    如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

    NICE源码网 JavaScript 使用vue-element-admin框架从后端动态获取菜单功能的实现 https://www.niceym.com/34145.html