Skip to content

Commit faea4d8

Browse files
committed
使用addRoutes重构权限
1 parent 624af00 commit faea4d8

File tree

10 files changed

+191
-192
lines changed

10 files changed

+191
-192
lines changed

src/main.js

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import Sticky from 'components/Sticky'; // 粘性header组件
2020
import vueWaves from './directive/waves';// 水波纹指令
2121
import errLog from 'store/errLog';// error log组件
2222
import './mock/index.js'; // 该项目所有请求使用mockjs模拟
23-
import permission from 'store/permission'; // 权限控制
2423

2524
// register globally
2625
Vue.component('multiselect', Multiselect);
@@ -36,6 +35,7 @@ Object.keys(filters).forEach(key => {
3635
// permissiom judge
3736
function hasPermission(roles, permissionRoles) {
3837
if (roles.indexOf('admin') >= 0) return true; // admin权限 直接通过
38+
if (!permissionRoles) return true;
3939
return roles.some(role => permissionRoles.indexOf(role) >= 0)
4040
}
4141

@@ -47,42 +47,24 @@ router.beforeEach((to, from, next) => {
4747
if (to.path === '/login') {
4848
next({ path: '/' });
4949
} else {
50-
if (to.meta && to.meta.role) { // 判断即将进入的页面是否需要权限
51-
if (store.getters.roles.length !== 0) { // 判断当前用户是否已拉取完info信息
52-
if (hasPermission(store.getters.roles, to.meta.role)) { // 判断权限
53-
next(); // 有权限
54-
} else {
55-
next({ path: '/401', query: { noGoBack: true } }); // 无权限
56-
}
57-
} else { // 未拉取info信息
58-
store.dispatch('GetInfo').then(() => { // 拉取info
59-
permission.init({ // 初始化权限
60-
roles: store.getters.roles,
61-
router: router.options.routes
62-
});
63-
if (hasPermission(store.getters.roles, to.meta.role)) { // 判断权限
64-
next();// 有权限
65-
} else {
66-
next({ path: '/401', query: { noGoBack: true } }); // 无权限
67-
}
68-
}).catch(err => {
69-
console.log(err);
70-
});
71-
}
72-
} else { // 页面不需要权限 直接进入
73-
if (store.getters.roles.length !== 0) {
74-
next();
50+
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完info信息
51+
store.dispatch('GetInfo').then(res => { // 拉取info
52+
const roles = res.data.role;
53+
store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
54+
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
55+
next(to); // hack方法 确保addRoutes已完成
56+
})
57+
}).catch(err => {
58+
console.log(err);
59+
});
60+
} else {
61+
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
62+
if (hasPermission(store.getters.roles, to.meta.role)) {
63+
next();//
7564
} else {
76-
store.dispatch('GetInfo').then(() => {
77-
permission.init({
78-
roles: store.getters.roles,
79-
router: router.options.routes
80-
});
81-
next();
82-
}).catch(err => {
83-
console.log(err);
84-
});
65+
next({ path: '/401', query: { noGoBack: true } });
8566
}
67+
// 可删 ↑
8668
}
8769
}
8870
} else {
@@ -95,6 +77,7 @@ router.beforeEach((to, from, next) => {
9577
}
9678
});
9779

80+
9881
router.afterEach(() => {
9982
NProgress.done(); // 结束Progress
10083
});

src/router/index.js

Lines changed: 102 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -70,49 +70,56 @@ Vue.use(Router);
7070
* noDropdown : if noDropdown:true will not has submenu
7171
* meta : { role: ['admin'] } will control the page role
7272
*/
73-
export default new Router({
74-
// mode: 'history', //后端支持可开
75-
scrollBehavior: () => ({ y: 0 }),
76-
routes: [
73+
74+
export const constantRouterMap = [
7775
{ path: '/login', component: Login, hidden: true },
7876
{ path: '/authredirect', component: authRedirect, hidden: true },
7977
{ path: '/sendpwd', component: sendPWD, hidden: true },
8078
{ path: '/reset', component: reset, hidden: true },
8179
{ path: '/404', component: Err404, hidden: true },
8280
{ path: '/401', component: Err401, hidden: true },
83-
{
84-
path: '/',
85-
component: Layout,
86-
redirect: '/dashboard',
87-
name: '首页',
88-
hidden: true,
89-
children: [{ path: 'dashboard', component: dashboard }]
90-
},
91-
{
92-
path: '/introduction',
93-
component: Layout,
94-
redirect: '/introduction/index',
95-
icon: 'xinrenzhinan',
96-
noDropdown: true,
97-
children: [{ path: 'index', component: Introduction, name: '简述' }]
98-
},
99-
{
100-
path: '/permission',
101-
component: Layout,
102-
redirect: '/permission/index',
103-
name: '权限测试',
104-
icon: 'quanxian',
105-
meta: { role: ['admin'] },
106-
noDropdown: true,
107-
children: [{ path: 'index', component: Permission, name: '权限测试页', meta: { role: ['admin'] } }]
108-
},
109-
{
110-
path: '/components',
111-
component: Layout,
112-
redirect: '/components/index',
113-
name: '组件',
114-
icon: 'zujian',
115-
children: [
81+
{
82+
path: '/',
83+
component: Layout,
84+
redirect: '/dashboard',
85+
name: '首页',
86+
hidden: true,
87+
children: [{ path: 'dashboard', component: dashboard }]
88+
},
89+
{
90+
path: '/introduction',
91+
component: Layout,
92+
redirect: '/introduction/index',
93+
icon: 'xinrenzhinan',
94+
noDropdown: true,
95+
children: [{ path: 'index', component: Introduction, name: '简述' }]
96+
}
97+
]
98+
99+
export default new Router({
100+
// mode: 'history', //后端支持可开
101+
scrollBehavior: () => ({ y: 0 }),
102+
routes: constantRouterMap
103+
});
104+
105+
export const asyncRouterMap = [
106+
{
107+
path: '/permission',
108+
component: Layout,
109+
redirect: '/permission/index',
110+
name: '权限测试',
111+
icon: 'quanxian',
112+
meta: { role: ['admin'] },
113+
noDropdown: true,
114+
children: [{ path: 'index', component: Permission, name: '权限测试页', meta: { role: ['admin'] } }]
115+
},
116+
{
117+
path: '/components',
118+
component: Layout,
119+
redirect: '/components/index',
120+
name: '组件',
121+
icon: 'zujian',
122+
children: [
116123
{ path: 'index', component: componentsIndex, name: '介绍 ' },
117124
{ path: 'tinymce', component: Tinymce, name: '富文本编辑器' },
118125
{ path: 'markdown', component: Markdown, name: 'Markdown' },
@@ -124,75 +131,73 @@ export default new Router({
124131
{ path: 'sticky', component: Sticky, name: 'Sticky' },
125132
{ path: 'countto', component: CountTo, name: 'CountTo' },
126133
{ path: 'mixin', component: Mixin, name: '小组件' }
127-
]
128-
},
129-
{
130-
path: '/charts',
131-
component: Layout,
132-
redirect: '/charts/index',
133-
name: '图表',
134-
icon: 'tubiaoleixingzhengchang',
135-
children: [
134+
]
135+
},
136+
{
137+
path: '/charts',
138+
component: Layout,
139+
redirect: '/charts/index',
140+
name: '图表',
141+
icon: 'tubiaoleixingzhengchang',
142+
children: [
136143
{ path: 'index', component: chartIndex, name: '介绍' },
137144
{ path: 'keyboard', component: KeyboardChart, name: '键盘图表' },
138145
{ path: 'keyboard2', component: KeyboardChart2, name: '键盘图表2' },
139146
{ path: 'line', component: LineMarker, name: '折线图' },
140147
{ path: 'mixchart', component: MixChart, name: '混合图表' }
141-
]
142-
},
143-
{
144-
path: '/errorpage',
145-
component: Layout,
146-
redirect: 'noredirect',
147-
name: '错误页面',
148-
icon: '404',
149-
children: [
148+
]
149+
},
150+
{
151+
path: '/errorpage',
152+
component: Layout,
153+
redirect: 'noredirect',
154+
name: '错误页面',
155+
icon: '404',
156+
children: [
150157
{ path: '401', component: Err401, name: '401' },
151158
{ path: '404', component: Err404, name: '404' }
152-
]
153-
},
154-
{
155-
path: '/errlog',
156-
component: Layout,
157-
redirect: 'noredirect',
158-
name: 'errlog',
159-
icon: 'bug',
160-
noDropdown: true,
161-
children: [{ path: 'log', component: ErrorLog, name: '错误日志' }]
162-
},
163-
{
164-
path: '/excel',
165-
component: Layout,
166-
redirect: 'noredirect',
167-
name: 'excel',
168-
icon: 'EXCEL',
169-
noDropdown: true,
170-
children: [{ path: 'download', component: ExcelDownload, name: '导出excel' }]
171-
},
172-
{
173-
path: '/theme',
174-
component: Layout,
175-
redirect: 'noredirect',
176-
name: 'theme',
177-
icon: 'theme',
178-
noDropdown: true,
179-
children: [{ path: 'index', component: Theme, name: '换肤' }]
180-
},
181-
{
182-
path: '/example',
183-
component: Layout,
184-
redirect: 'noredirect',
185-
name: '综合实例',
186-
icon: 'zonghe',
187-
children: [
159+
]
160+
},
161+
{
162+
path: '/errlog',
163+
component: Layout,
164+
redirect: 'noredirect',
165+
name: 'errlog',
166+
icon: 'bug',
167+
noDropdown: true,
168+
children: [{ path: 'log', component: ErrorLog, name: '错误日志' }]
169+
},
170+
{
171+
path: '/excel',
172+
component: Layout,
173+
redirect: 'noredirect',
174+
name: 'excel',
175+
icon: 'EXCEL',
176+
noDropdown: true,
177+
children: [{ path: 'download', component: ExcelDownload, name: '导出excel' }]
178+
},
179+
{
180+
path: '/theme',
181+
component: Layout,
182+
redirect: 'noredirect',
183+
name: 'theme',
184+
icon: 'theme',
185+
noDropdown: true,
186+
children: [{ path: 'index', component: Theme, name: '换肤' }]
187+
},
188+
{
189+
path: '/example',
190+
component: Layout,
191+
redirect: 'noredirect',
192+
name: '综合实例',
193+
icon: 'zonghe',
194+
children: [
188195
{ path: 'dynamictable', component: DynamicTable, name: '动态table' },
189196
{ path: 'dragtable', component: DragTable, name: '拖拽table' },
190197
{ path: 'inline_edit_table', component: InlineEditTable, name: 'table内编辑' },
191198
{ path: 'table', component: Table, name: '综合table' },
192199
{ path: 'form1', component: Form1, name: '综合form1' }
193-
]
194-
},
195-
196-
{ path: '*', redirect: '/404', hidden: true }
197-
]
198-
});
200+
]
201+
},
202+
{ path: '*', redirect: '/404', hidden: true }
203+
];

src/store/getters.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const getters = {
22
sidebar: state => state.app.sidebar,
3-
livenewsChannels: state => state.app.livenewsChannels,
43
token: state => state.user.token,
54
avatar: state => state.user.avatar,
65
name: state => state.user.name,
@@ -10,6 +9,8 @@ const getters = {
109
auth_type: state => state.user.auth_type,
1110
status: state => state.user.status,
1211
roles: state => state.user.roles,
13-
setting: state => state.user.setting
12+
setting: state => state.user.setting,
13+
permission_routers: state => state.permission.routers,
14+
addRouters: state => state.permission.addRouters
1415
};
1516
export default getters

src/store/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import Vue from 'vue';
22
import Vuex from 'vuex';
33
import app from './modules/app';
44
import user from './modules/user';
5+
import permission from './modules/permission';
56
import getters from './getters';
67

78
Vue.use(Vuex);
89

910
const store = new Vuex.Store({
1011
modules: {
1112
app,
12-
user
13+
user,
14+
permission
1315
},
1416
getters
1517
});

src/store/modules/app.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,11 @@ const app = {
1616
Cookies.set('sidebarStatus', 0);
1717
}
1818
state.sidebar.opened = !state.sidebar.opened;
19-
},
20-
SET_LIVENEWS_CHANNELS: (status, channels) => {
21-
status.livenewsChannels = JSON.stringify(channels);
22-
Cookies.set('livenewsChannels', JSON.stringify(channels));
2319
}
2420
},
2521
actions: {
2622
ToggleSideBar: ({ commit }) => {
2723
commit('TOGGLE_SIDEBAR')
28-
},
29-
setTheme: ({ commit }, theme) => {
30-
commit('SET_THEME', theme)
31-
},
32-
setlivenewsChannels: ({ commit }, channels) => {
33-
commit('SET_LIVENEWS_CHANNELS', channels)
3424
}
3525
}
3626
};

0 commit comments

Comments
 (0)