element-ui 动态路由
很多时候,需要动态加载路由,来控制权限。
基于element ui 得动态路由写法
1.设置不需要权限的路由constantRoutes和需要判断权限的路由asyncRoutes ,动态过滤需要判断权限的路由,并通过addRoutes添加路由
router/index,js
/*
* @Descripttion:
* @Version:
* @Date: 2021-06-11 13:58:03
*/
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
// 这里放着不需要判断权限的路由
export const constantRoutes = [{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
// 作品评审
{
path: '/theme',
redirect: '/theme/list',
name: 'theme',
component: Layout,
meta: {
title: '作品评审',
icon: 'dashboard',
},
children: [{
meta: {
title: '作品评审',
icon: 'dashboard',
},
name: 'themelist',
path: 'list',
component: () => import('@/views/theme/list'),
},
{
meta: {
title: '作品评审',
icon: 'dashboard',
activeMenu: '/theme/list'
},
name: 'themeadd',
hidden: true,
path: 'add',
component: () => import('@/views/theme/add'),
},
]
},
]
// 需要判断权限的路由
export const asyncRoutes = [{
path: '/',
redirect: '/list',
name: 'dat',
component: Layout,
meta: {
title: '数据管理',
icon: 'example',
// 区分权限得标识
roles: ["管理员"]
},
children: [{
meta: {
title: '数据管理',
icon: 'example'
},
path: 'list',
name: 'manageList',
component: () => import('@/views/area/list.vue'),
},
{
meta: {
title: '数据管理',
icon: 'example',
activeMenu: '/list'
},
path: 'add',
name: 'manageAdd',
component: () => import('@/views/area/add.vue'),
hidden: true
},
]
},
// 账号管理
{
path: '/tag',
redirect: '/tag/list',
name: 'tag',
component: Layout,
meta: {
title: '账号管理',
icon: 'example',
// 区分权限得标识
roles: ["管理员"]
},
children: [{
meta: {
title: '账号管理',
icon: 'example'
},
path: 'list',
name: 'taglist',
component: () => import('@/views/tag/list.vue'),
},
{
meta: {
title: '账号管理',
icon: 'example',
activeMenu: '/tag/list'
},
path: 'add',
name: 'tagadd',
component: () => import('@/views/tag/add.vue'),
hidden: true
},
]
},
{
path: '*',
redirect: '/404',
hidden: true
}
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({
y: 0
}),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
router.beforeEach((to, from, next) => {
if (to.path === '/login') {
next();
} else {
let token = localStorage.getItem('Authorization');
if (token === 'null' || token === '') {
next('/login');
} else {
next();
}
}
});
export default router
登录login.vue
this.$store.dispatch("user/login", this.loginForm)
store中user模块 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: ""
}
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 = {
// 登录
login({
commit
}, userInfo) {
const {
username,
password
} = userInfo
return new Promise((resolve, reject) => {
// 数据结构
// var res={
// token:"123",
// username:"123",
// role:"管理员"
// }
// 调用登录方法 走接口
login({
username: username.trim(),
password: password
}).then(response => {
console.log(response)
var res = response.data;
// 登录成功后将token存储在cookie之中
setToken(res.token)
sessionStorage.setItem('username', res.username)
sessionStorage.setItem('role', res.role)
sessionStorage.setItem('id', res.id)
commit('SET_NAME', res.username)
commit('SET_TOKEN', res.token)
// commit('SET_ROLES', res.role)
// commit('SET_ROLES', response.data.role)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 设置角色
setRole({
commit
}, role) {
commit('SET_ROLES', role)
},
// 等处登录
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)
})
})
},
// 移除token
resetToken({
commit
}) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', "")
removeToken()
resolve()
})
},
}
export default {
namespaced: true,
state,
mutations,
actions
}
store/modules/permission.js 过滤动态路由,
/* * @Descripttion: * @Version: 1.0.1 * @Date: 2021-06-11 13:58:03 */ import { constantRoutes, asyncRoutes } from '@/router' /** * 使用meta.role确定当前用户是否具有权限 * @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 } } /** * 递归过滤异步路由表 * @param routes asyncRoutes * @param roles */ export function filterAsyncRoutes(routes, roles) { console.log(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); console.log(state.routes) } } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes; // 管理员是最高权限,所有路由均可访问得情况下 就把注释放出来 // if (roles.includes('管理员')) { // accessedRoutes = asyncRoutes || [] // } else { // 获取符合条件的需要添加的动态路由 accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) // } commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } export default { namespaced: true, state, mutations, actions }
全局路由守卫 permission.js
/* * @Descripttion: * @Version: 1.0.1 * @Date: 2021-06-11 13:58:03 */ import router from './router' import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' NProgress.configure({ showSpinner: false }) // NProgress Configuration router.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() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 } else { // determine whether the user has obtained his permission roles through getInfo const hasRoles = store.getters.roles if (hasRoles) { next() } else { try { // 登陆以后获取到用户角色,用来判断权限 const roles = sessionStorage.getItem('role') // 写入角色 store.dispatch('user/setRole', roles) // 获取需要动态添加得路由 const accessRoutes = await store.dispatch('permission/generateRoutes', [roles]) router.options.routes = store.getters.routes; // 动态添加可访问路由 router.addRoutes(accessRoutes) //hack方法以确保addRoutes是完整的 //设置replace:true,这样导航就不会留下历史记录 next({ ...to, replace: true }) } catch (error) { // 删除token并转到登录页以重新登录 await store.dispatch('user/resetToken') Message.error(error || 'Has Error') next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { // 这里可以设置白名单 ,不需要判断得路由导航,例如注册,登录等,可以用数组,可以直接比较 if (to.path.includes('login')) { next() } else { // 没有访问权限的其他页将重定向到登录页 next(`/login?redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { // finish progress bar NProgress.done() })

浙公网安备 33010602011771号