1.vue項目當中通常都是通過設置routes配置項來控制路由跳轉,例如設置
routes: [ { path: '/cinema', redirect: '/page/cinema', component: BlankLayout, meta: { title: '影院' , requiresAuth: true} children: [ { path: '/cinema/plan', name: 'cinemaPlan', component: () => import('./views/cinema/Plan'), meta: { title: '影院排期' } }, { path: '/cinema/cinemaDetail', name: 'cinemaDetail', component: () => import('./views/cinema/CinemaDetail'), meta: { title: '影院詳情' } } ] } ]
利用routes中的meta屬性添加一個字段,用作標識,首先假設在名為router.js的文件中定義router,具體代碼如下:
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const router = new VueRouter({ routes }) export router
接着在名為perssion.js的文件中結合路由守衛,進行登陸驗證,另外這里如果用戶登錄成功之后,token會默認放在vuex中的getters中,所以在導航守衛中判斷對應getters是否存在,如果存在,證明用戶已登錄,允許用戶進入該路由。否則就跳轉登陸頁,並把當前頁的路由座位query參數傳遞給login頁面:
to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title}`)) if (to.matched.some(record => record.meta.requiresAuth)) { // this route requires auth, check if logged in // if not, redirect to login page. if (!store.getters.token) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { if (to.query.siteCode) { next() return } if (from.query.siteCode) { const query = JSON.parse(JSON.stringify(to.query)) query.siteCode = from.query.siteCode next({ path: to.path, query: query }) } else { next() // 確保一定要調用 next() } } }
2.主要說明下為什么要使用遍歷to.matched數組判斷meta的requiresAuth字段,而不直接使用to.meta.requiresAuth來判斷,首先例子當中給的是cinema,也即是1級路由設置了requiresAuth.而cinemaPlan沒有設置。假設兩種情況:
前提:vue路由匹配時會同時匹配滿足情況的所有路由,即如果路由是‘/cinema/plan’的話,‘/cinema’也會觸發。另外如果較高等級的路由需要登錄控制的話,它所有的嵌套路由都是基本需要登錄控制的。
(1)cinema具有登錄控制,而cinemaPlan 沒有。如果用戶正常點擊路由跳轉的話,它必然是先進一級路由,再去二級路由,一級路由實現登錄控制,利用to.meta是能夠滿足的,注意這里是用戶正常點擊,但是假如有用戶直接改變url地址的話去訪問cinemaPlan的話,則需要給cinemaPlan路由添加requiresAuth字段,同理也需要給cinemaDetail添加字段,如果路由比較多的話,就會很麻煩。
(2)cinema沒有登錄控制,而cinemaPlan有。這種情況確實不怕用戶直接改變url訪問二級路由了,但是同樣如果過多二級路由,也是需要設置許多requiresAuth。
所以,為了方便,直接遍歷to.matched數組,該數組中保存着匹配到的所有路由信息。就該例而言,訪問cinema時,matched數組長度為1,訪問cinemaPlan時,matched數組長度為2,即保存着‘/cinema’以及‘/cinema/plan’。其實啰嗦了這么多,直接使用to.meta判斷字段也可以,就是需要給所有需要控制的路由添加requiresAuth。而to.matched則只需要給較高一級的路由添加requiresAuth即可,其下的所有子路由不必添加。