vue Router——基礎篇html
正如其名,vue-router
提供的導航守衛主要用來經過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程當中:全局的, 單個路由獨享的, 或者組件級的。前端
記住參數或查詢的改變並不會觸發進入/離開的導航守衛。你能夠經過觀察 $route
對象來應對這些變化,或使用 beforeRouteUpdate
的組件內守衛vue
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
當一個導航觸發時,全局前置守衛按照建立順序調用。守衛是異步解析執行,此時導航在全部守衛 resolve 完以前一直處於 等待中webpack
每一個守衛方法接收三個參數:web
to: Route
: 即將要進入的目標 路由對象from: Route
: 當前導航正要離開的路由next: Function
: 必定要調用該方法來 resolve 這個鉤子。執行效果依賴 next 方法的調用參數。
next()
: 進行管道中的下一個鉤子。若是所有鉤子執行完了,則導航的狀態就是 confirmed (確認的)next(false)
: 中斷當前的導航。若是瀏覽器的 URL 改變了 (多是用戶手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。next('/')
或者 next({ path: '/' })
: 跳轉到一個不一樣的地址。當前的導航被中斷,而後進行一個新的導航。你能夠向 next 傳遞任意位置對象,且容許設置諸如 replace: true
、name:
'home'
之類的選項以及任何用在 router-link
的 to
prop 或 router.push
中的選項。next(error)
: (2.4.0+) 若是傳入 next 的參數是一個 Error
實例,則導航會被終止且該錯誤會被傳遞給 router.onError()
註冊過的回調。舉個例子vue-router
router.beforeEach((to, from, next) => { if(to.name === 'One'){ next('Two') } next() })
當咱們訪問api
http://localhost:8080/#/One
時,就會跳到數組
http://localhost:8080/#/Two
在 2.5.0+ 你能夠用 router.beforeResolve 註冊一個全局守衛。這和 router.beforeEach 相似,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用。瀏覽器
router.beforeEach((to, from, next) => { if(to.name === 'One'){ next('Two') } next() }) router.beforeResolve((to, from, next) => { if(to.name === 'Two'){ next('Three') } next() })
當咱們訪問異步
http://localhost:8080/#/One
時,就會跳到
http://localhost:8080/#/Two
而後再跳到
http://localhost:8080/#/Three
你也能夠註冊全局後置鉤子,然而和守衛不一樣的是,這些鉤子不會接受 next 函數也不會改變導航自己
router.afterEach((to, from) => { // ... })
路由
{ path: '/One', name: 'One', component: One, beforeEnter: (to, from, next) => { if(to.name === 'One'){ next('Two') } next() } }
當咱們訪問
http://localhost:8080/#/One
時,就會跳到
http://localhost:8080/#/Two
beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` }
beforeRouteEnter
守衛 不能 訪問 this
,由於守衛在導航確認前被調用,所以即將登場的新組件還沒被建立。
不過,你能夠經過傳一個回調給 next
來訪問組件實例。在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數。
beforeRouteEnter (to, from, next) { next(vm => { // 經過 `vm` 訪問組件實例 }) }
注意 beforeRouteEnter
是支持給 next
傳遞迴調的惟一守衛。對於 beforeRouteUpdate
和 beforeRouteLeave
來講,this
已經可用了,因此不支持傳遞迴調,由於沒有必要了
beforeRouteUpdate (to, from, next) { // just use `this` this.name = to.params.name next() }
beforeRouteLeave (to, from , next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }
這個離開守衛一般用來禁止用戶在還未保存修改前忽然離開。該導航能夠經過 next(false) 來取消
beforeEach
守衛。beforeRouteUpdate
守衛 (2.2+)。beforeEnter
。beforeRouteEnter
。beforeResolve
守衛 (2.5+)。afterEach
鉤子。beforeRouteEnter
守衛中傳給 next
的回調函數。const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, meta: { requiresAuth: true } } ] } ] })
咱們稱 routes
配置中的每一個路由對象爲一個路由記錄。路由記錄能夠是嵌套的,所以,當一個路由匹配成功後,他可能匹配多個路由記錄
一個路由匹配到的全部路由記錄會暴露爲 $route
對象 (還有在導航守衛中的路由對象) 的 $route.matched
數組。所以,咱們須要遍歷 $route.matched
來檢查路由記錄中的 meta
字段。
在舉個栗子
router.beforeEach((to, from, next) => { //判斷路由記錄是否須要驗證登陸 if (to.matched.some(record => record.meta.requiresAuth)) { // 本身定義的判斷登陸的方法 let isLogin = getLoginStatus() if (!isLogin()) { next({ // 跳轉到登陸頁 path: '/login', // 登陸頁須要知道從哪跳過來的,方便登陸成功後回到原頁面 query: { redirect: to.fullPath } }) } else { next() } } else { next() // 確保必定要調用 next() } })
next必定要執行否則鉤子函數不會resolved。
使用前端路由,當切換到新路由時,想要頁面滾到頂部,或者是保持原先的滾動位置,就像從新加載頁面那樣。 vue-router 能作到,並且更好,它讓你能夠自定義路由切換時頁面如何滾動。
注意: 這個功能只在支持 history.pushState 的瀏覽器中可用。
當建立一個 Router 實例,你能夠提供一個 scrollBehavior 方法
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { if(to.name === 'BookDetails'){ return { x: 0, y: 0 } } } })
scrollBehavior
方法接收 to
和 from
路由對象。第三個參數 savedPosition
當且僅當 popstate
導航 (經過瀏覽器的 前進/後退 按鈕觸發) 時纔可用
當咱們訪問BookDetails路由的時候,就會回到頂部
固然還有好多,就不一一介紹了,能夠看這裏
懶加載也叫延遲加載,即在須要的時候進行加載,隨用隨載。在單頁應用中,若是沒有應用懶加載,運用webpack打包後的文件將會異常的大,形成進入首頁時,須要加載的內容過多,延時過長,不利於用戶體驗,而運用懶加載則能夠將頁面進行劃分,須要的時候加載頁面,能夠有效的分擔首頁所承擔的加載壓力,減小首頁加載用時。
{ path: '/Fruits', name: 'Fruits', component: require('@/components/Fruits') // 非按需加載 } { path: '/Fruits', name: 'Fruits', component: require(['@/components/Fruits'], resolve) // 按需加載 }
按需加載會在頁面第一次請求的時候,把相關路由組件塊的js添加上;非按需加載則會把全部的路由組件塊的js包打在一塊兒
const Fruits = () => import('@/components/Fruits') { path: '/Fruits', name: 'Fruits', component: Fruits } 或者 { path: '/Fruits', name: 'Fruits', component: () => import('@/components/Fruits') }
有時候咱們想把某個路由下的全部組件都打包在同個異步塊 (chunk) 中。只須要使用 命名 chunk,一個特殊的註釋語法來提供 chunk name (須要 Webpack > 2.4)
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
Webpack 會將任何一個異步模塊與相同的塊名稱組合到相同的異步塊中