導航守衛(wèi)
正如其名奸汇,vue-router提供的導航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)吻商,有多種機會植入路由導航過程種:全局的薄霜,單個路由獨享的茎芭,或者組件級的
記住 參數(shù)或查詢的改變并不會觸發(fā)進入/離開的導航守衛(wèi)。 你可以通過觀察 $route 對象來應對這些變化看锉,或使用 beforeRouteUpdata 的組件內(nèi)守衛(wèi)姿锭。
全局守衛(wèi)
你可以使用router.beforeEach 注冊一個全局前置守衛(wèi):
const router = new VueRouter({...})
router.beforeEach((to,form,next)=>{
})
當一個導航觸發(fā)時,全局前置守衛(wèi)按照創(chuàng)建順序調(diào)用伯铣。守衛(wèi)是異步解析執(zhí)行呻此,此時導航在所有守衛(wèi)resolve完之前一直處于 等待中
每個守衛(wèi)方法接受三個參數(shù):
to:Route:即將要進入的目標 路由對象
from: Route :當前導航正要離開的路由
next: Function: 一定要調(diào)用該方法來resolve這個鉤子,執(zhí)行效果依賴next方法調(diào)用參數(shù)
- next():進行管道中的下一個鉤子腔寡,如果全部鉤子執(zhí)行完了焚鲜,則導航的狀態(tài)就是confirmed(確認的)
- next(false): 中斷當前的導航。如果瀏覽器的url改變了(可能是用戶手動或者瀏覽器后退按鈕)蹬蚁,那么url地址會重置到 from 路由對應的地址恃泪。
- next('/')或者next({path: '/'}):跳轉(zhuǎn)到一個不同的地址,當前的導航被中斷犀斋,然后進行一個新的導航贝乎。你可以向next傳遞任意位置對象,且允許設置諸如 replace:true叽粹、name: 'home'之類的選項以及任何用在router-link的toprop或者router.push中的選項
- next(error):(2.4.0+)如果傳入next的參數(shù)是一個Error實例览效,則導航會被終止且該錯誤會被傳遞給router.onError()注冊過的回調(diào)
確保要調(diào)用 next 方法却舀,否則鉤子就不會被 resolved
完整的導航解析
- 導航被觸發(fā)
- 在失活的組件里調(diào)用離開守衛(wèi)
- 調(diào)用全局的 beforeEach 守衛(wèi)
- 在重用的組件里調(diào)用 beforeRouteUpdata 守衛(wèi)
- 在路由配置里調(diào)用 beforeEnter
- 解析異步路由組件
- 在被激活的組件里調(diào)用 beforeRouteEnter
- 調(diào)用全局的 beforeResolve 守衛(wèi)(2.5+)
- 導航被確認
- 調(diào)用全局的 afterEach 鉤子
- 觸發(fā)DOM 更新
- 用創(chuàng)建好的實例調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)
滾動行為
使用前端路由,當切換到新路由時锤灿,想要頁面滾動到頂部挽拔,或者時保持原先的滾動位置,就像重新加載頁面那樣但校,vue-router就能做到
ps:這個功能只在支持 history.pushState 的瀏覽器中可用
當創(chuàng)建一個 Router 實例螃诅,你可以提供一個 scrollBehavior 方法:
const router = new VueRouter({
routes: [...]
scrollBehavior(to,from,savedPosition){
// return 期望滾動到哪個的位置
}
})
scrollBehavior 方法接收 to 和 from 路由對象,第三個參數(shù) savedPosition 當且僅當 popstate 導航(通過瀏覽器的 前進\后退 按鈕觸發(fā))時才可用
路由懶加載
當打包構建應用時状囱,javascript包會變得非常大术裸、影響頁面加載,如果我們能把不同路由對應得組件分割成不同得代碼塊亭枷,然后當路由訪問的時候才在家對應組件袭艺,這樣更加高效
結合Vue的異步組件和webpack的代碼分割功能,輕松實現(xiàn)路由組件的懶加載叨粘。
首先猾编,可以將異步組件定義為返回一個Promise的工廠函數(shù)
const Foo = () => Promise.resolve({// 組件定義對象})
第二,在webpack2中升敲,我們可以使用動態(tài) import語法來定義代碼分塊點
import('./Foo.vue')
ps: 如果使用的時babel答倡,你將需要添加 sybtax-dynamic-import 插件,才能使Babel可以正確的解析語法
結合這兩者冻晤,這就使如何定義一個能夠被webpack自動代碼分割的異步組件
const Foo = () => import('./Foo.vue')
在路由配置中什么都不需要改變苇羡,只需要像往常一樣使用Foo:
const router = new VueRouter({
routes: [
{path: '/foo', component: Foo}
]
})
把組件按組分塊
有時候我們想把某個路由下的所有組件都打包在同個異步塊中绸吸,只需要使用命名 chunk鼻弧,一個特殊的注釋語法來提高chunk name(需要webpack>2.4)
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
webpack 會將任何一個異步模塊與相同的塊名稱組合到相同的異步塊中