老板让我十分钟上手nx-admin
大體流程
參考資料:
nx-admin項目地址
首先這里就不講解vue和vuex之類的基礎(chǔ)東西了 有興趣的可以去官方文檔了解。這里根據(jù)流程走向大概說說
路由配置
首先找到路由配置,路由配置放在了src/router/index.js路由配置里暴露了兩個常量 一個是 constantRouterMap 另外一個是 asyncRouterMap 這里先說說constantRouterMap。 nx-admin的權(quán)限驗證大概是
- 1 默認大家都能訪問的頁面,不需要權(quán)限, 都訪問的頁面定義為 constantRouterMap
- 2 需要登錄或者需要權(quán)限的頁面路由定義為 asyncRouterMap
根據(jù)后臺獲取到用戶信息role(權(quán)限)的不同來動態(tài)加載asyncRouterMap中meta.role的權(quán)限對應(yīng)的頁面
登錄成功后做的事情
點擊登錄以后 左側(cè)的側(cè)邊欄有導(dǎo)航列表。 這里提出兩個疑問?
- 根據(jù)路由配置說的 動態(tài)加載對應(yīng)的權(quán)限路由 那么側(cè)邊欄那么多路由 肯定不能寫死吧?
- 我點擊登錄后 那些登錄流程怎么走的?用戶權(quán)限存在哪里?token在哪里?
側(cè)邊欄的動態(tài)渲染
根據(jù)問題1來回答 首先我們找到layout也就是src/views/layout/Layout.vue,
因為在路由配置文件我們看見asyncRouterMap中好多組件的父組件都是Layout 在Layout中我們就可以看到有個組件sidebar。
ok繼續(xù)找sidebar這個組件 src/views/layout/components/Sidebar/index.vue,發(fā)現(xiàn)這里就是渲染側(cè)邊欄的,然后找到渲染的變量是permission_routers 這個變量是存在vuex里面的,也就是說路由是存在vuex的 所以咋們?nèi)uex里面找找看 src/store/modules/permission.js。
路由的動態(tài)加載
src/store/modules/permission.js 這個文件里面有個actions
GenerateRoutes({ commit }, data) {return new Promise(resolve => {const { roles } = datalet accessedRoutersif (roles.indexOf('admin') >= 0) {accessedRouters = asyncRouterMap} else {accessedRouters = filterAsyncRouter(asyncRouterMap, roles)}commit('SET_ROUTERS', accessedRouters)resolve()})}發(fā)現(xiàn)就是這一段代碼更改了permission_routers,具體邏輯咱們不看 簡單解釋來說就是
如果用戶的權(quán)限是管理員把asyncRouterMap所有的路由頁面都渲染出來,畢竟管理員嘛 你懂的權(quán)限嘛。否則 我不是管理員但是也不是游客就是一小市民 那么我要去asyncRouterMap中找找我小市民能夠訪問哪些頁面。看完這段邏輯咋們就知道了這個路由是如何動態(tài)更改的了,等等,是不是忘了啥? 雖然我知道這個actions,但是。。。在哪調(diào)用的? 經(jīng)過深思熟慮的著想,在花了0.1s后 就得出,既然是路由嘛 肯定是有個全局的地方要做判斷的 所以得出結(jié)論就是 router.beforeEach, 一開始去找那個啥src/main.js,發(fā)現(xiàn)beforeEach被分離在src/permission.js 打開這個文件。一切疑問都解開了。
用戶權(quán)限的獲取
說真的。。這個文件好長。。都不想看了。。。。 下圖的代碼這么長 看個毛啊。。于是我簡單翻譯了下
router.beforeEach((to, from, next) => {NProgress.start() // start progress bar if (getToken()) { // 判斷是否有tokenif (to.path === '/login') {next({ path: '/' })NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發(fā)afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!} else {if (store.getters.roles.length === 0) { // 判斷當前用戶是否已拉取完user_info信息store.dispatch('GetUserInfo').then(res => { // 拉取user_infoconst roles = res.data.rolestore.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可訪問的路由表router.addRoutes(store.getters.addRouters) // 動態(tài)添加可訪問路由表next({ ...to, replace: true }) // hack方法 確保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record})}).catch(() => {store.dispatch('FedLogOut').then(() => {Message.error('Verification failed, please login again')next({ path: '/login' })})})} else {// 沒有動態(tài)改變權(quán)限的需求可直接next() 刪除下方權(quán)限判斷 ↓if (hasPermission(store.getters.roles, to.meta.role)) {next()//} else {next({ path: '/401', query: { noGoBack: true }})NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發(fā)afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!}// 可刪 ↑}}} else {if (whiteList.indexOf(to.path) !== -1) { // 在免登錄白名單,直接進入next()} else {next('/login') // 否則全部重定向到登錄頁NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發(fā)afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!}} })請說人話,翻譯成人話的版本。。。
每次更改頁面路由你有沒有token啊?有啊好的,你的權(quán)限是默認的權(quán)限0么?是的。。我就是一游客系統(tǒng)獲取我的信息..拿到權(quán)限值,動態(tài)加載路由(GenerateRoutes)...通行...不是。。我是權(quán)限汪(admin)等等..我看看作者有沒有把你降級沒有好了。。你還是權(quán)限汪 請進有滾吧,你已經(jīng)不是權(quán)限汪了,作者已經(jīng)把你寫成戰(zhàn)斗力只有5的渣渣了沒有沒有還敢闖這里?滾去關(guān)口(/login)沒錯,就這么簡單。整個權(quán)限驗證流程就完整了。剩下的就是讀讀文檔啊,看看如何使用組件之類的了。
參考 https://github.com/Relsoul
總結(jié)
以上是生活随笔為你收集整理的老板让我十分钟上手nx-admin的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用php实现Google /Baidu
- 下一篇: 【洛谷 P3304】[SDOI2013]