運用場景一:做登錄判斷
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: '影院詳情' } } ] } ]
接着在名為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即可,其下的所有子路由不必添加。
運用場景二:側邊欄路由導航
當一個模塊下面有多個子路由時,切換到子路由的同時,這個模塊依然要處於高亮狀態,這個時候,可以利用路由的to.matched 屬性,to.matched返回的是一個多層路由組成的數組,只要改數組里面有保護父路由路徑,就設置高亮
if (to.matched[1] && (to.matched[1].name === 'ScreenControl')) { // 存在二級路由且名字為啥 }
總結:當有用到嵌套路由時,該模塊下,所有嵌套路由都要用到某個屬性進行判斷,這時候可以通過設置判斷共同父路由進行屬性設置