预览地址:https://panjiachen.gitee.io/vue-element-admin/#/dashboard
GitHub地址:https://github.com/PanJiaChen/vue-element-admin
文档地址:https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/
看vue-element-admin代码,学到的逻辑点。
1. 路由权限生成,src目录下的permission.js文件
// 顶部进度条配置
NProgress.configure({ showSpinner: false }) // NProgress Configuration
// 白名单,无需进行路由权限控制,即可访问。
const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist
然后接下来就是全局路由导航守卫的逻辑
// 展示进度条
NProgress.start()
// 设置当前路由标题
document.title = getPageTitle(to.meta.title)
// 获取token
const hasToken = getToken()
// 如果访问的是登录路由
if (to.path === '/login') {
// 重定向到首页
next({ path: '/' })
NProgress.done()
}
else {
// 从vuex中取出role路由表,如果之前缓存过路由表直接跳转
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
}
const { roles } = await store.dispatch('user/getInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
// filterAsyncRoutes是递归查找路由
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
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
}
router.addRoutes
动态添加生成的路由表。router.addRoutes(accessRoutes)
next({ ...to, replace: true })
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
2. vuex中工程化导入文件
将modules下的文件自动导入,并挂载到store上
https://webpack.js.org/guides/dependency-management/#requirecontext
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
3. 路由表‘
constantRoutes
和 asyncRoutes
俩个路由数组,分别为公共路由和动态路由。
公共路由即没有权限控制,随便访问。
动态路由即根据登录用户权限动态生成对应的路由。