Vue 巢狀路由的導航守衛

導航守衛的條件,在巢狀路由和單層路由中,做法有一點點不同。在單層路由的條件只要查索到 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 意見