官網https://panjiachen.github.io/vue-element-admin-site/zh/guide/#%E5%8A%9F%E8%83%BD
vue項目做的少,elementUI也是最近才接觸,所以文檔看了一周才有了點思路,最難的就是用戶登錄權限部分
目錄結構

頁面都在/src/views 下
登錄權限
登錄在src/views/login/index.vue ,登錄只是賬號密碼,登錄后獲取用戶信息其中包含用戶角色,路由配置在src/router/index.js,路由中配置了每個路由對應的角色
側邊欄動態渲染
src/router/index.js 路由配置里有公共的路由constantRoutes和異步路由asyncRoutes,異步路由是根據在 meta里設置roles來實現動態的meta: { title: 'permission', icon: 'lock', roles: ['admin', 'editor']},
權限的判斷 是在 src/store/modules/permission.js文件里,有個actions。判斷如果角色里包含admin(一個用戶可多個角色,所以返回的角色是個數組),就顯示全部的,否則的話需要做判斷,還是根據 route.meta.roles.includes(role) 來判斷路由是否包含返回的角色
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
動態加載路由肯定要在全局做判斷,需要寫在路由跳轉之前router.beforeEach,根據目錄結構可以知道是在src/permission.js中, store.dispatch('GenerateRoutes') 通過調用vuex中的方法獲得路由權限,沒有權限的話就跳401
1 router.beforeEach((to, from, next) => {
2 if (store.getters.token) { // 判斷是否有token
3 if (to.path === '/login') {
4 next({ path: '/' });
5 } else {
6 if (store.getters.roles.length === 0) { // 判斷當前用戶是否已拉取完user_info信息
7 store.dispatch('GetInfo').then(res => { // 拉取info
8 const roles = res.data.role;
9 store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可訪問的路由表
10 router.addRoutes(store.getters.addRouters) // 動態添加可訪問路由表
11 next({ ...to, replace: true }) // hack方法 確保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
12 })
13 }).catch(err => {
14 console.log(err);
15 });
16 } else {
17 next() //當有用戶權限的時候,說明所有可訪問路由已生成 如訪問沒權限的全面會自動進入404頁面
18 }
19 }
20 } else {
21 if (whiteList.indexOf(to.path) !== -1) { // 在免登錄白名單,直接進入
22 next();
23 } else {
24 next('/login'); // 否則全部重定向到登錄頁
25 }
26 }
27 });
后台權限配置
3月15號剛更新的后台可以進行權限配置了,先看下界面

也就是說權限路由可以動態的設置了,不用每個角色都去路由下邊配置了(異步路由asyncRoutes),但是改成這樣的話,路由就需要每次登錄后動態從接口獲取,返回的格式是用戶的角色對應角色下邊的路由,而我們的router文件里的異步路由對應角色,所以獲取到的數據需要與現有的路由列表做一下匹配
返回的數據:
1 {
2 key: 'intern',
3 name: 'intern',
4 description: '亂入者',
5 routes: [
6 {
7 path: '',
8 redirect: 'dashboard',
9 children: [
10 {
11 path: 'dashboard',
12 name: 'Dashboard',
13 meta: { title: '首頁', icon: 'dashboard', noCache: true, affix: true }
14 }
15 ]
16 },
17 {
18 path: '/permission',
19 redirect: '/permission/index',
20 alwaysShow: true, // will always show the root menu
21 meta: {
22 title: '權限管理',
23 icon: 'lock',
24 },
25 children: [
26 {
27 path: 'user',
28 name: 'UserPermission',
29 meta: {
30 title: '用戶管理',
31 }
32 },
33 ]
34 },
35 ]
36 }
對數據進行處理,與現有的路由asyncRoutes匹配
function getAsyncRoutes(userRoute, localRoute, role) {
let asyncRoute = localRoute.filter(item => item.path == userRoute.path);
if (asyncRoute.length > 0) {
asyncRoute[0].meta.roles.push(role);
if (userRoute.children) {
userRoute.children.forEach(item => {
getAsyncRoutes(item, asyncRoute[0].children, role)
})
}
}
}
rolesData.forEach(userData => {
userData.routes.forEach(userRoute => {
getAsyncRoutes(userRoute, asyncRoutes, userData.key);
})
})
總結:在每個異步路由上角色都寫上admin,登錄后獲取每個用戶對應的路由,與現有寫死的路由進行匹配,將角色添加到異步路由中
后台動態路由權限設置
用戶登錄之后會跳轉路由,跳轉路由的時候全局權限里邊做了用戶信息的判斷,沒有用戶信息的情況下會先獲取用戶信息。
獲取到用戶信息會返回用戶的角色及角色對應的路由,在xuex中,會先把角色對應的路由添加到路由上,然后再根據角色去匹配路由,
返回的就是該用戶的路由了(一個用戶可對應多個角色)

