Vue Router(2)
阿新 • • 發佈:2020-08-11
寫在前面
在上一篇部落格 Vue Router(1) 中介紹了 Vue Router 的基本使用方法,在本篇部落格將繼續深入 Vue Router,解鎖更多的功能。
1. 程式設計式導航
Vue Router 裡的程式設計式導航簡單來說,就是,如果我們不用 <a>
標籤來定義導航連結,那該如何跳轉頁面呢?那就需要使用 JavaScript
程式語言來操控介面進行導航。
在原生的 Web API 中,除了 a 標籤外,我們通常使用 window.location.href = "/xxx"
或者 window.open("xxx")
來跳轉頁面。若想改變 url
History
介面新增的跳轉方法。在 前端路由 中有詳細介紹。就是 window.history.pushState() 和 window.history.replaceState()
,在 Vue Router 的內部就是使用了這兩個介面,只不過 Vue Router 進行了封裝,在 Vue Router 例項中留出了對應的介面。就是 router.push()
。
以下小例來自 Vue Router 官網。同樣的規則也適用於 router-link 元件的 to 屬性。
// 字串 router.push('home') // 物件 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 帶查詢引數,變成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }}) const userId = '123' router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: `/user/${userId}` }) // -> /user/123 // 這裡的 params 不生效 router.push({ path: '/user', params: { userId }}) // -> /user
2. 導航守衛
導航守衛主要用來通過跳轉或取消的方式守衛導航,說人話就是,導航守衛就是在路由跳轉的過程中執行的特殊的鉤子函式。路由跳轉看似就是一瞬間的事,但其實被劃分成了各個階段,在各個階段都有提供特殊的函式,當路由跳轉時被自動呼叫。
就好像原生的 Web API 中的 window.onbeforeunload / window.onload / window.onunload
這樣的 API。
2.1 全域性守衛
1. router.beforeEach((to, from, next) => { // ... }) 2. router.beforeResolve(to, from, next) => { // ... }) 3. router.afterEach((to, from) => { // ... })
2.2 路由獨享的守衛
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
2.3 元件內的守衛
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該元件的對應路由被 confirm 前呼叫
// 不!能!獲取元件例項 `this`
// 因為當守衛執行前,元件例項還沒被建立
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該元件被複用時呼叫
// 舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 元件,因此元件例項會被複用。而這個鉤子就會在這個情況下被呼叫。
// 可以訪問元件例項 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該元件的對應路由時呼叫
// 可以訪問元件例項 `this`
}
}
3. 路由懶載入
路由懶載入的意思就說,我們並不在一開始就把所有要用到的元件都 import 進來。而是在路由跳轉至對應的元件時才將該元件載入進來。這樣會更高效。
懶載入前:
import A from './components/A.vue'
import B from './components/B.vue'
const routes = [
{path: '/a', component: A},
{path: '/b', component: B}
]
懶載入後:
const A = () => import('./components/A.vue')
const B = () => import('./components/B.vue')
const routes = [
{path: '/a', component: A},
{path: '/b', component: B}
]
```