頁面訪問權
在登陸的時候確定權限
- 在定義路由的時候區分靜態路由和動態路由,靜態路由是所有用戶都可以訪問的,動態路由只有有權限的時候才可以訪問,后續可以通過router.addRoutes()添加擁有的權限路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
import approvalsRouter from './modules/approvals'
import departmentsRouter from './modules/departments'
/* 動態路由 */
export const asyncRoutes = [
approvalsRouter,
departmentsRouter
]
/* 靜態路由 */
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首頁', icon: 'dashboard' }
}
]
}
]
const createRouter = () =>
new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
//重置router的方法,需要在退出的時候重置router,否則下一個人登陸后也能訪問上一個人的路由
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
const router = createRouter()
export default router
- 右側導航項是遍歷router.options.routes的,但router.addRoutes()調用后並不能更改router.options.routes的值,只能控制添加路由的跳轉,所以就需要使用vuex來存儲擁有的所有路由
//store 的perimission模塊
import { constantRoutes, asyncRoutes } from '@/router'
const state = {
routes: constantRoutes // 路由表
}
const mutations = {
setRoutes(state, newRoutes) {
state.routes = [...constantRoutes, ...newRoutes]
}
}
const actions = {
filterRoutes(context, menus) {
const routes = []
menus.forEach(key => {
routes.push(...asyncRoutes.filter(item => item.name === key))
})
context.commit('setRoutes', routes)
return routes //在路由攔截器中調用這個actions,修改store中routes,store中routes的值是用來遍歷得到右側導航欄的,return的值是router.addRoutes()的參數,當然也可以使用store中俄 routes,但是沒有return來的方便
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
- 在路由全局前置后衛中做權限攔截,獲取用戶資料,用戶資料中roles是當前用戶的權限數據,其中roles.menus是用戶的頁面訪問權信息,roles.ponits是用戶的按鈕點擊權的信息
/*
* @User: <jf>
* @Date: 2021-09-09 19:35:50
*/
import router from '@/router'
import store from '@/store'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
NProgress.start()
if (store.getters.token) {
if (to.path === '/login') {
next('/')
} else {
if (!store.getters.userId) {
try {
// 獲取用戶信息,用戶信息使用vuex管理的 roles.menus 是當前用戶所擁有的 頁面訪問權限點
const { roles } = await store.dispatch('user/getUserInfo')
const routes = await store.dispatch(
'permission/filterRoutes',
roles.menus
)
router.addRoutes([
...routes,
{ path: '*', redirect: '/404', hidden: true }
]) // 此時用戶可以訪問所得靜態路由和篩選出來當前用戶所有擁有的動態路由
next(to.path)
} catch (error) {
console.log(error)
}
} else {
next()
}
}
} else {
if (whiteList.some(x => x === to.path)) {
next()
} else {
next('/login')
}
}
NProgress.done()
})
router.afterEach((to, from, next) => {
NProgress.done()
})
- 在便用生成右側菜單的時候使用store中的routes數據,而不要使用router.options.routes的數據
computed: {
...mapGetters(["routes"]),
routes1() {
return this.$router.options.routes; //不要使用這個數據,這個並會因為有router.addRoutes()的調用而改變
}
}
退出重置路由和重置store中的路由數據
const actions = {
// 登陸
async login(context, data) {
const res = await login(data)
context.commit('setToken', res)
setTimeStamp()
},
//退出 清除 token和用戶資料
logout(context) {
context.commit('removeToken')
context.commit('removeUserInfo')
// 重置路由
// resetRouter()
// context.commit('permission/setRoutes', [], { root: true })
}
}
按鈕點擊權
- 在路由全局前置后衛中做權限攔截,獲取用戶資料,用戶資料中roles是當前用戶的權限數據,其中roles.menus是用戶的頁面訪問權信息,roles.ponits是用戶的按鈕點擊權的信息,每一個按鈕都一個標識,定義一個方法根據roles.points中的按鈕權限點返回true/false,true表示可以點擊
// 定義一個mixin方法,全局注冊
import store from '@/store/index'
export default {
methods: {
checkPermission(key) {
//userInfo是用戶的資料
const { userInfo } = store.state.user
if (userInfo.roles && userInfo.roles.points) {
return userInfo.roles.points.some(item => item === key)
}
return false
}
}
}
// 在頁面中調用mixin的方法,將方法返回的結果給button的disabled屬性
<el-button :disabled="!checkPermission('add-depts')" @click='add'>添加</button>