Vue实战:基于Vue-ElementUI的权限管理系统之动态路由和动态按钮显示

1.首先登录

2.调用permission.js 的router.beforeEach((to, from, next)

to:进入到哪个路由去
from:从哪个路由离开
next:路由的控制参数,常用的有next(true)和next(false)
首先判断进入的是否是login页面?然后再判断是否已经登陆?
已经登陆了就进入你要跳转的页面,没登录就进入login页面

为了更加明显一点,我将页面命名的简单一些,ps:

Login.vue是登陆页面
Index.vue是全局页面(包含公共导航组件)
A.vue是普通页面(此处我做为首页)
B.vue是普通页面

permission.js router.beforeEach(async(to, from, next) => {   NProgress.start()   document.title = getPageTitle(to.meta.title)   const hasToken = getToken()   // 判断是否存在token,没有就重新登陆   if (hasToken) {     if (to.path === '/login') {       // if is logged in, redirect to the home page       next({ path: '/' })       NProgress.done()     } else {       // 这里指的是src/store/getters.js的roles       const hasRoles = store.getters.roles && store.getters.roles.length > 0       if (hasRoles) {         next()       } else {         try {           // 获取roles           // get user info 获取当前登录用户的Button按钮列表,和当前用户角色名           store.dispatch('user/getInfo')            // generate accessible routes map based on roles 获取后端角色列表            const DbRoutes = await store.dispatch('permission/getSideMenus')           router.addRoutes(DbRoutes)           next({ ...to, replace: true })         } catch (error) {           // remove token and go to login page to re-login           await store.dispatch('user/resetToken')           Message.error(error || 'Has Error')           next(`/login?redirect=${to.path}`)           NProgress.done()         }       }     }   } })

2.store.getter

const getters = {   token: state => state.user.token,   name: state => state.user.name,   roles: state => state.user.roles,//角色名列表   permission_routes: state => state.permission.routes,//页面路由   permissions: state => state.user.permissions //菜单按钮列表 } export default getters

3.store.dispatch('user/getInfo')调用 Store文件夹下user.js的 getInfo方法 获取当前登录用户的Button按钮列表,和当前用户角色名

import { login, logout, getInfo, getRoleList } from '@/api/user' import { getToken, setToken, removeToken } from '@/utils/auth' import router, { resetRouter } from '@/router'  const state = {   token: getToken(),   roles: [] }  const mutations = {   SET_TOKEN: (state, token) => {     state.token = token   },   //存储登录角色信息   SET_ROLES: (state, roles) => {     state.roles = roles   },  //存储按钮信息   SET_PERMISSIONS: (state, permissions) => {     state.permissions = permissions   } }  const actions = {     // 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.')         }         const { roles, permissions } = data         console.error('roles' + roles)         console.error('permissions' + permissions)         // roles must be a non-empty array         if (!roles || roles.length <= 0) {           reject('getInfo: roles must be a non-null array!')         }         if (!permissions || permissions.length <= 0) {           reject('getInfo: permissions must be a non-null array!')         }          commit('SET_ROLES', roles)         commit('SET_PERMISSIONS', permissions)         resolve(data)       }).catch(error => {         reject(error)       })     })   } }  export default {   namespaced: true,   state,   mutations,   actions }

4. store.dispatch('permission/getSideMenus')调用 Store文件夹下psermission.js的 getSideMenus方法

const actions = {   getSideMenus({ commit, state }) {     return new Promise((resolve, reject) => {        //import { listForRouter } from '@/api/user'       listForRouter().then(response => {         const menus = response.data         //import { traverseRoutes } from '@/utils/router'         const remoteroutes = traverseRoutes(menus)         commit('SET_ROUTES', remoteroutes)         resolve(remoteroutes)       }).catch(error => {         console.log('list', error)         router.replace({           path: '/login',           query: { redirect: router.currentRoute.path }         })         // reject(error)       })     })   } }

import { traverseRoutes } from '@/utils/router'

export function traverseRoutes(menus) {   const routes = menus.map(menu => {     if (menu.children === null) {       menu.children = []     }     if (menu.component) {       const name = menu.component       menu.component = (resolve) => require(['@/' + name], resolve)       // menu.component = resolve => require(['@/views/UserManagement/user'], resolve)     }      if (menu.children && menu.children.length) {       menu.children = traverseRoutes(menu.children)     }     return menu   })   return routes }
api文件夹下user.js import { userInfo} from '@/api/user' export function getInfo(token) {   return request({     url: '/admin/info',     method: 'get',     params: { token }   }) }

api文件夹下role.js import { listForRouter } from '@/api/role'

export function listForRouter() {   return request({     url: '/admin/getLoginSideBarMenus',     method: 'get'   }) }

后端admin/Info 返回给前端信息

{ "code":200, "msg":"成功", "data": {"permissions":["userAdd","userDeleted","userUpdated","userReset","userSetRole","roleAdd","userDeleted", "roleUpdated","authAdd","authDeleted","authUpdated"], "roles":["超级管理员"] } }

后端admin/getLoginSideBarMenus返回给前端信息

{"code":200,"msg":"成功", "data":[{"id":1,"parentId":0,"path":"/system","component":"layout","name":"系统管理","num":1,"hidden":false,"url":"/system","meta":{"title":"系统管理","icon":"form"},"children":[{"id":2,"parentId":1,"path":"/user","component":"views/UserManagement/user.vue","name":"用户管理","num":1,"hidden":false,"url":"/user","meta":{"title":"用户管理","icon":"user"},"children":null},{"id":8,"parentId":1,"path":"/role","component":"views/UserManagement/role.vue","name":"角色管理","num":1,"hidden":false,"url":"/role","meta":{"title":"角色管理","icon":"international"},"children":null},{"id":14,"parentId":1,"path":"/auth","component":"views/UserManagement/auth.vue","name":"资源管理","num":1,"hidden":false,"url":"/auth","meta":{"title":"资源管理","icon":"list"},"children":null},{"id":18,"parentId":1,"path":"/test","component":"views/test/index.vue","name":"测试菜单","num":1,"hidden":false,"url":"/test","meta":{"title":"测试菜单","icon":"lock"},"children":[{"id":19,"parentId":18,"path":"/children1","component":"views/test/children/children1.vue","name":"测试菜单1","num":2,"hidden":false,"url":"/children1","meta":{"title":"测试菜单1","icon":"icon"},"children":null}]}]}]}

动态按钮显示

main.js

// main.js import { checkArray } from './utils/btnPermission.js' Vue.directive('permission', {   inserted(el, binding) {     const permission = binding.value // 获取到 v-permission的值     if (permission) {       const hasPermission = checkArray(permission) // 检测是否有权限       if (!hasPermission) { // 没有权限 移除Dom元素         el.parentNode && el.parentNode.removeChild(el)       }     }   } })

./utils/btnPermission.js

import store from '@/store' export function checkArray(key) {   // store.dispatch('user/getInfo')    const arr = store.getters.permissions //store文件下getter.   const index = arr.indexOf(key)   if (index > -1) {     return true // 有权限   } else {     return false // 无权限   } }

界面使用方法 auth.js

界面使用方法 auth.js  <el-table-column fixed="right" label="操作" width="300px">           <template slot-scope="scope">             <el-button               v-permission="'authAdd'"               icon="el-icon-plus"               type="success"               size="small"               @click="add(scope.row.code,scope.row.pcodes)"             >               新增子级             </el-button>             <el-button               v-permission="'authUpdated'"               type="primary"               icon="el-icon-edit"               size="small"               @click="handleEdit(scope.row.id, scope.row)"             >编辑</el-button>             <el-button               v-permission="'authDeleted'"               type="danger"               icon="el-icon-delete"               size="small"               @click.native.prevent="deleted(scope.row.id)"             >               删除             </el-button>           </template>         </el-table-column>