1.創建vue實例的時候 掛載vue-router
2.用戶登錄後獲取role 將role和路由美國頁面權限比較 生成最終用戶可訪問的路由表
3.調用router.addRoutes 添加可訪問路由
4.使用vuex管理路由 根據vuex中可訪問路由渲染側邊欄組件
在router文件夾下有一個index.js文件 就是用來控制頁面權限的 template模板已經有了靜態路由在index.js文件裡邊
需要在此文件添加動態路由 怎麼menu沒有出現這個動態的側邊欄呢😭 繼續找找看為啥
ps:靜態路由 :代表不需要動態判斷權限的路由
動態路由:代表需要動態判斷權限並通過個的頁面
- 在router文件夾下面的index.js增加動態路由
export const asyncRoutes = [
{
path:'/inquiry',
component: Layout,
alwaysShow: true,
meta: {
title: 'Inquiry',
icon: 'lock',
roles: ['admin']
},
children: [
{
path: 'create',
component: () => import('@/views/inquiry/form'),
name: 'CreateInquiry',
meta: {
title: 'CreateInquiry',
icon: 'lock',
roles: ['admin']
}
}
]
}
]
2. 因為是mock數據,所以要在mock下添加routes.js
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: 'Dashboard', icon: 'dashboard' }
}]
},
{
path: '/example',
component: Layout,
redirect: '/example/table',
name: 'Example',
meta: { title: 'Example', icon: 'example' },
children: [
{
path: 'table',
name: 'Table',
component: () => import('@/views/table/index'),
meta: { title: 'Table', icon: 'table' }
},
{
path: 'tree',
name: 'Tree',
component: () => import('@/views/tree/index'),
meta: { title: 'Tree', icon: 'tree' }
}
]
},
{
path: '/form',
component: Layout,
children: [
{
path: 'index',
name: 'Form',
component: () => import('@/views/form/index'),
meta: { title: 'Form', icon: 'form' }
}
]
},
{
path: '/nested',
component: Layout,
redirect: '/nested/menu1',
name: 'Nested',
meta: {
title: 'Nested',
icon: 'nested'
},
children: [
{
path: 'menu1',
component: () => import('@/views/nested/menu1/index'), // Parent router-view
name: 'Menu1',
meta: { title: 'Menu1' },
children: [
{
path: 'menu1-1',
component: () => import('@/views/nested/menu1/menu1-1'),
name: 'Menu1-1',
meta: { title: 'Menu1-1' }
},
{
path: 'menu1-2',
component: () => import('@/views/nested/menu1/menu1-2'),
name: 'Menu1-2',
meta: { title: 'Menu1-2' },
children: [
{
path: 'menu1-2-1',
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
name: 'Menu1-2-1',
meta: { title: 'Menu1-2-1' }
},
{
path: 'menu1-2-2',
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
name: 'Menu1-2-2',
meta: { title: 'Menu1-2-2' }
}
]
},
{
path: 'menu1-3',
component: () => import('@/views/nested/menu1/menu1-3'),
name: 'Menu1-3',
meta: { title: 'Menu1-3' }
}
]
},
{
path: 'menu2',
component: () => import('@/views/nested/menu2/index'),
meta: { title: 'menu2' }
}
]
},
{
path: 'external-link',
component: Layout,
children: [
{
path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
meta: { title: 'External Link', icon: 'link' }
}
]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
export const asyncRoutes = [
{
path: '/inquiry',
component: Layout,
redirect: '/inquiry/list',
name: 'Inquiry',
meta: { title: '詢價', icon: 'example' },
children: [
{
path: 'create',
name: 'Inquiry',
component: () => import('@/views/inquiry/form'),
meta: { title: '創建詢價單', icon: 'table', roles: ['admin'] }
},
{
path: 'list',
name: 'List',
component: () => import('@/views/inquiry/list'),
meta: { title: '詢價列表', icon: 'tree', roles: ['admin'] }
}
]
}
]
3.這個時候 發現store下的getters.js沒有把獲取路由的方法 好了 添加進去 😭 怎麼回事
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
roles: state => state.user.roles,
promission_routes: state => state.promission_routes
}
4.因為沒有permission 許可啊 啊啊啊
import { asyncRoutes, constantRoutes } from '@/router'
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
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) {
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
}
5.api文件耶應該響應的增加請求頁面權限的api
import request from '@/utils/request'
export function getRoutes() {
return request({
url: '/routes',
method: 'get'
})
}
export function getRoles() {
return request({
url: '/roles',
method: 'get'
})
}
export function addRole(data) {
return request({
url: '/role',
method: 'post',
data
})
}
export function updateRole(id, data) {
return request({
url: `/role/${id}`,
method: 'put',
data
})
}
export function deleteRole(id) {
return request({
url: `/role/${id}`,
method: 'delete'
})
}
5.喔 no 還有需要路由列表和權限比較啊(在utils文件夾下增加 permission.js)
import store from '@/store'
export default function checkPermission(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
return false
}
return true
} else {
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
}
6.然後還需要在組件下面sidebar的index加入計算屬性
computed: {
...mapGetters([
'premission_routes',
'sidebar'
]),
然後 然後 發現頁面登錄成功無法跳轉了😭
7. 最後需要在src下permission添加權限控制邏輯
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
} else {
try {
// get user info
const { roles } = await store.dispatch('user/getInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
router.addRoutes(accessRoutes)
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()
}
}
}
}
大功告成
代碼會同步到github上 大家有空可以去看看