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


Posted in Vue.js onApril 29, 2021

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动态获取菜单内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue+iview分页组件的封装
Nov 17 Vue.js
基于vue项目设置resolves.alias: '@'路径并适配webstorm
Dec 02 Vue.js
Vue实现简单计算器
Jan 20 Vue.js
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
vue实现同时设置多个倒计时
May 20 Vue.js
Vue鼠标滚轮滚动切换路由效果的实现方法
Aug 04 Vue.js
Vue组件更新数据v-model不生效的解决
Apr 02 Vue.js
Axios代理配置及封装响应拦截处理方式
Apr 07 Vue.js
vue实现书本翻页动画效果实例详解
Apr 08 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 Vue.js
Vue router配置与使用分析讲解
Dec 24 Vue.js
vue使用v-model进行跨组件绑定的基本实现方法
关于vue中如何监听数组变化
vue实现简单数据双向绑定
Apr 28 #Vue.js
vue引入Excel表格插件的方法
Apr 28 #Vue.js
原生JS封装vue Tab切换效果
vue项目两种方式实现竖向表格的思路分析
vue首次渲染全过程
You might like
计算2000年01月01日起到指定日的天数
2006/10/09 PHP
php上的memcache和memcached两个pecl库
2010/03/29 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
查询绑定数据岛的表格中的文本并修改显示方式的js代码
2009/12/15 Javascript
CutePsWheel javascript libary 控制输入文本框为可使用滚轮控制的js库
2010/02/07 Javascript
jquery创建一个新的节点对象(自定义结构/内容)的好方法
2013/01/21 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
ionic进入多级目录后隐藏底部导航栏(tabs)的完美解决方案
2016/11/23 Javascript
js放大镜放大购物图片效果
2017/01/18 Javascript
老生常谈jacascript DOM节点获取
2017/04/17 Javascript
微信小程序之获取当前位置经纬度以及地图显示详解
2017/05/09 Javascript
jQuery ajax读取本地json文件的实例
2017/10/31 jQuery
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
2018/03/06 Javascript
用ES6的class模仿Vue写一个双向绑定的示例代码
2018/04/20 Javascript
JavaScript简单实现关键字文本搜索高亮显示功能示例
2018/07/25 Javascript
详解js静态检查工具eslint配置文件
2018/11/23 Javascript
TypeScript开发Node.js程序的方法
2019/04/30 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
2020/05/27 Javascript
基于javascript原生判断DOM是否加载完毕
2020/10/14 Javascript
Python写的一个简单监控系统
2015/06/19 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
python简单实例训练(21~30)
2017/11/15 Python
python 自定义异常和异常捕捉的方法
2018/10/18 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
CSS3的RGBA中关于整数和百分比值的转换
2015/08/04 HTML / CSS
韩国11街:11STREET
2018/03/27 全球购物
20年同学聚会邀请函
2014/02/04 职场文书
总经理助理工作职责
2014/02/06 职场文书
规划编制实施方案
2014/03/15 职场文书
优秀少先队员主要事迹材料
2014/05/28 职场文书
师德先进个人事迹材料
2014/12/19 职场文书
mysql配置SSL证书登录的实现
2021/09/04 MySQL