说明下 ⼩编是19年1⽉开始接触vue-element-admin的,⼀直没时间整理笔记 就随意整理⼀下吧 其实也没什么说的 太简单了 就说说动态路由鉴权的原理是 两个接⼝ 流程其实是这样的
1.登录页⾯按钮点击
2.vuex ⾥⾯的 login ⽅法被调⽤
3.vuex ⾥⾯的 login ⽅法被调⽤ 完毕
4.监听路由改变 然后获取当前登录的⽤户⾓⾊
5.获取当前⽤户信息 获取⾓⾊组 并保存登录状态,返回当前⾓⾊信息6.通过 ⾓⾊ 和 所有路由 匹配出对应⾓⾊拥有的路由权限 返回路由组7将上⾯获取到的 路由权限 挂载到真实的路由上⾯去
然后说下参与路由权限 牵扯的⽂件吧
/src/view/login/index.vue 登录页⾯的⼊⼝⽂件/src/store/modules/user.js vuex 的⽂件 全局⽅法/src/permission.js 监听路由改变后的js
/src/store/mudules/permission.js 通过 ⾓⾊返回 登录⾓⾊的对应路由列表的⽅法
src\\views\\permission\\components/SwitchRoles.vue 切换⾓⾊的⽂件 这个登录不⾛ 切换⾓⾊才会⾛
不说了直接上代码
///src/view/login/index.vue
///src/view/login/index.vue v-model=\"loginForm.username\" placeholder=\"Username\" name=\"username\" type=\"text\" tabindex=\"1\" autocomplete=\"on\" /> v-model=\"loginForm.password\" :type=\"passwordType\" placeholder=\"Password\" name=\"password\" tabindex=\"2\" autocomplete=\"on\" @keyup.native=\"checkCapslock\" @blur=\"capsTooltip = false\" @keyup.enter.native=\"handleLogin\" /> Username : admin Password : any Username : editor Password : any Can not be simulated on local, so please combine you own business simulation! ! ! Login Form
/src/store/modules/user.js
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'import router, { resetRouter } from '@/router'//状态列表const state = {
token: getToken(), name: '', avatar: '',
introduction: '', roles: []}
//修改vuex 的⼊⼝const mutations = {
SET_TOKEN: (state, token) => { state.token = token },
SET_INTRODUCTION: (state, introduction) => { state.introduction = introduction },
SET_NAME: (state, name) => { state.name = name },
SET_AVATAR: (state, avatar) => { state.avatar = avatar },
SET_ROLES: (state, roles) => { state.roles = roles }}
//全局⽅法
const actions = {
// user login 登录⽅法
login({ commit }, userInfo) {
console.info(\"2.vuex ⾥⾯的 login ⽅法被调⽤\"); const { username, password } = userInfo return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => { //登录成功后 保存 token const { data } = response
commit('SET_TOKEN', data.token) setToken(data.token) resolve();//返回成功 }).catch(error => { reject(error) }) }) },
// get user info 获取⽤户信息 getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
console.info(\"5.获取当前⽤户信息 获取⾓⾊组 并保存登录状态,返回当前⾓⾊信息\"); getInfo(state.token).then(response => { const { data } = response
if (!data) {
reject('Verification failed, please Login again.') }
const { roles, name, avatar, introduction } = data // roles must be a non-empty array if (!roles || roles.length <= 0) {
reject('getInfo: roles must be a non-null array!') }
//修改⽤户登录的信息 调⽤ commit⽅法 commit('SET_ROLES', roles) commit('SET_NAME', name) commit('SET_AVATAR', avatar)
commit('SET_INTRODUCTION', introduction);
resolve(data) }).catch(error => { reject(error) }) }) },
// user logout 退出登录
logout({ commit, state, dispatch }) {
return new Promise((resolve, reject) => { logout(state.token).then(() => { commit('SET_TOKEN', '') commit('SET_ROLES', []) removeToken() resetRouter()
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485 dispatch('tagsView/delAllViews', null, { root: true }) resolve()
}).catch(error => { reject(error) }) }) },
// remove token 清除登录信息 token什么的 resetToken({ commit }) {
return new Promise(resolve => { commit('SET_TOKEN', '') commit('SET_ROLES', []) removeToken() resolve()
}) },
// dynamically modify permissions 更改⾓⾊ 这个⽅法登录的时候应该不调⽤ 是在登录成功后切换⾓⾊使⽤的 changeRoles({ commit, dispatch }, role) {
//console.info(\"4.调⽤vuex changeRoles ⽅法 进⼊\"); return new Promise(async resolve => { const token = role + '-token' commit('SET_TOKEN', token) setToken(token)
const { roles } = await dispatch('getInfo');//调⽤这个⽂件⾥⾯的 getInfo⽅法 resetRouter()
// generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true }) // dynamically add accessible routes router.addRoutes(accessRoutes)
// reset visited views and cached views
dispatch('tagsView/delAllViews', null, { root: true }) resolve() }) }}
export default {
namespaced: true, state,
mutations, actions}
/src/permission.js
import router from './router'import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress barimport 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookieimport getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configurationconst whiteList = ['/login', '/auth-redirect'] // no redirect whitelistrouter.beforeEach(async(to, from, next) => { // start progress bar NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title) // determine whether the user has logged in const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page next({ path: '/' }) NProgress.done() } else {
// determine whether the user has obtained his permission roles through getInfo const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try {
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] //监听路由改变的时候 调⽤ 获取当前登录⽤户⾝份信息
console.info(\"4.监听路由改变 然后获取当前登录的⽤户⾓⾊\");
const { roles } = await store.dispatch('user/getInfo');//拿到当前的⽤户信息 ⾓⾊ // generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', roles);
//将上⾯获取到的 路由权限 挂载到真实的路由上⾯去
console.info(\"7.将上⾯获取到的 路由权限 挂载到真实的路由上⾯去\"); // dynamically add accessible routes router.addRoutes(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
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() } } }
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else {
// other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } }})
router.afterEach(() => { // finish progress bar NProgress.done()})
/src/store/mudules/permission.js
import { asyncRoutes, constantRoutes } from '@/router'/**
* Use meta.role to determine if the current user has permission * @param roles * @param route */
function hasPermission(roles, route) { if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role)) } else {
return true }}
/**
* Filter asynchronous routing tables by recursion * @param routes asyncRoutes * @param roles */
export function filterAsyncRoutes(routes, roles) { const res = []
routes.forEach(route => { const tmp = { ...route }
if (hasPermission(roles, tmp)) { if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles) }
res.push(tmp) } }) return res}
const state = { routes: [], addRoutes: []}
const mutations = {
SET_ROUTES: (state, routes) => { state.addRoutes = routes
state.routes = constantRoutes.concat(routes) }}
const actions = {
//通过 ⾓⾊ 和 所有路由 匹配出对应⾓⾊拥有的路由权限 generateRoutes({ commit }, roles) {
console.info(\"6.通过 ⾓⾊ 和 所有路由 匹配出对应⾓⾊拥有的路由权限 返回路由组\"); return new Promise(resolve => { let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || [] } else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) }
commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) }}
export default {
namespaced: true, state,
mutations, actions}
最后讲下怎么动态切换⾝份加路由吧 权限开关src\\views\\permission\\components/SwitchRoles.vuesrc\\views\\permission\\page.vue
Switch roles:
页⾯⾥⾯ 通过指令来区分⾝份 内置⾃带的⾃定义指令/src/views/permission/directive.vue
好了 重头戏来了 动态修改⾓⾊的权限 这个可是⼀个好东西 直接上代码吧
{{ scope.row.name }} :autosize=\"{ minRows: 2, maxRows: 4}\" type=\"textarea\" placeholder=\"Role Description\" /> class=\"permission-tree\" />
因篇幅问题不能全部显示,请点此查看更多更全内容