導航守衛的條件,在巢狀路由和單層路由中,做法有一點點不同。在單層路由的條件只要查索到 meta 屬性就可以了;但是巢狀路由中,父子路由的 meta 屬性是整串集結在 matched 這個屬性裡面,而且是以陣列的形式儲存起來的。所以,需要稍微做點調整,才能順利地擋住使用者造訪特定路徑。
單層路由的守衛方法
在導航守衛中,我們在注入點(main.js)添加了 router 的方法:
router.beforeEach(to, from, next){
// 導航方法
}
如果想要讓使用者在登入之後才能訪問某些特定頁面,只需要在 router 的設定檔中,那個路徑的元件增加 meta 屬性:
route: [
path: './login',
component: Login,
meta: {
requiresAuth: true
},
]
加上了這段之後,再回頭到導航的方法中補上:
{
if(to.meta.requiresAuth){...}
}
這樣,當導航守衛在偵測到使用者切換到下一個頁面(因為條件是 to,如果條件是 from 的話,導航守衛就會偵測使用者來自哪些頁面),就會檢查使用者路徑的紀錄中的 meta 屬性。
可是這樣在巢狀路由會失效
上面的方法只有在單一路徑時起作用。如果,今天我們的路由是巢狀的,像是這樣:
routes: [{
path: '/login',
component: Login,
children: [{
path: '',
component: Dashboard
}
]}]
(* 為了閱讀方便,我把不是重點的大小括號格式改掉了。)
這時候,只要做一點點調整就可以了:
const IfAuth = to.matched.some(record => {
return record.meta.requiresAuth
})
IfAuth 的值為布林。透過這個值,就能進一步的用在接下來的條件判斷啦~!
some() 是 JS 的陣列方法,用來搜索陣列中,只要有個項目條件符合,就回傳 true。
這點在導航守衛的檢查中,也滿合理的。
最後導航守衛的程式碼
router.beforeEach((to, from, next)=>{
const ifAuth = to.matched.some(record => {return record.meta.requiresAuth});
if(ifAuth){
//送出檢查是否為登入狀態的 ajax 請求
if(true){
next(); //如果是登入狀態,就到下一頁吧
}else{
next({path: '/login'}); //如果不是,請到登入頁面重新登入
}
}else{ next() };
})
0 意見