一、基礎
1. 介紹
Vue Router 是 Vue.js官方的路由管理器。是我們使用Vue構建的SPA(單頁應用 Single Page Application)的路徑管理器。本質上就是建立頁面Url與元件之間的對映關係。
2. 基本使用
2.1 安裝
npm install vue-router -S
複製程式碼
2.2 在入口檔案中引入並配置
// 專案入口檔案main.js
// 1. 引入vue、vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
// 2. 引入專案元件
import App from './App.vue'
import Home from './components/Home.vue'
import Hello from './components/Hello.vue'
// 3. 呼叫vue-router
Vue.use(VueRouter)
// 4. 建立router例項,定義路由配置
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home
},
{
path: '/hello',
component: Hello
},
{
path: '/',
// 根目錄重定向至 /home
redirect: '/home'
}
]
})
// 5. 建立、掛載根例項並注入路由
new Vue({
render: h => h(App),
router
}).$mount('#app')
複製程式碼
2.3 在App.vue
中插入導航及檢視渲染標籤
<!-- App.vue -->
<template>
<div>
<div class="nav">
<router-link to="/home">Home</router-link>
<router-link to="/hello">Hello</router-link>
</div>
<!-- 路由渲染出口 -->
<router-view></router-view>
</div>
</template>
複製程式碼
二、動態路由匹配(相當於路由傳參)
使用場景
某個模式下匹配到的所有路由,都對映到同一元件。例如不同使用者的個人資訊頁面,或者不同文章頁面等。
要點概括
- 定義路由路徑時使用動態引數(以冒號開頭):
path: '/ComponentA/:xxx'
- 在
ComponentA
中通過this.$route.params.xxx
獲取引數
// Main.js
// 定義路由配置時路徑使用動態引數(以冒號開頭即可)
const router = new VueRouter({
routes: [
{
path: '/user/:id',
component: User
}
]
})
// User.vue
// 路由匹配成功時,引數會被設定到this.$route.params中
export default {
...
// 元件內的路由導航守衛
beforeRouteEnter (to, from, next) {
// 在渲染該元件的對應路由被 confirm 前呼叫
// 不!能!獲取元件例項 `this`,通過傳回撥給 next並把元件例項作為回撥方法的引數來訪問元件例項
next(vm => {
vm.getUserInfo(vm.$route.params.id)
})
},
// 元件內的路由導航守衛
beforeRouteUpdate(to, from, next) {
// 在當前路由改變,但是該元件被複用時呼叫
this.getUserInfo(this.$route.params.id)
}
}
// User.vue
// 在模板插值語法中,通過 $route.params.id 獲取路徑引數
<template>
<div>
<p>使用者ID:{{$route.params.id}}</p>
<p>使用者名稱:{{userInfo.name}}</p>
</div>
</template>
複製程式碼
三、巢狀路由(多級路由)
使用場景
應用中元件存在多層巢狀組合的關係。
要點概括
- 路由配置時使用
children
欄位,配置類似routes
- 在渲染元件中插入巢狀的導航
<router-link>
及渲染出口<router-view>
標籤
// Main.js
// 定義路由配置時路徑使用children欄位,配置類似routes
const router = new VueRouter({
routes: [
{
path: '/user',
component: User,
children: [
{path: 'info', component: UserInfo},
{path: 'posts', component: UserPosts}
]
}
]
})
// User.vue
// 在模板中,插入巢狀的<router-link>及<router-view>
<template>
<div>
<p>使用者User元件</p>
<p>
<router-link to="/user/info">使用者資訊</router-link>
<router-link to="/user/posts">使用者文章</router-link>
</p>
<router-view></router-view>
</div>
</template>
複製程式碼
四、命名檢視(多個路由渲染出口)
使用場景
- 同時 (同級) 展示多個檢視
- 巢狀檢視的複雜佈局。(將巢狀元件視為根元件,則等同於場景1,不過是在
routes
內配置或children
內配置的區別)
要點概括
- 配置多個路由渲染出口
<router-view>
並設定name
屬性 - 路由配置時使用
components
欄位代替component
欄位 多個s components
物件內,key為<router-view>
標籤的name
屬性(沒設定時,預設為default
),value為要渲染的元件
// App.vue
// 在模板中,配置多個路由渲染出口`<router-view>`並設定`name`屬性
<template>
<div>
<p>命名檢視</p>
<p>
<router-link to="/">主頁</router-link>
</p>
<router-view></router-view>
<router-view name="view1"></router-view>
<router-view name="view2"></router-view>
</div>
</template>
// Main.js
// 配置路由時使用components欄位代替component欄位,key為<router-view>標籤的`name`屬性(沒設定時,預設為`default`),value為要渲染的元件
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Index,
view1: View1,
view2: View2
}
}
]
})
複製程式碼
五、路由導航跳轉方法總結
mehtods: {
routerMethodsCollection() {
// router.push
// 類似 window.history.pushState,會在history中產生新紀錄,回退按鈕可退回
// 點選 <router-link> 內部呼叫router.push,故<router-link :to="..."> 對應 router.push(...)
this.$router.push('/home') // 傳入路徑字串
this.$router.push({ path: 'home' }) // 傳入路由描述物件
// 路由傳參,如果指定了path則會傳參失敗
this.$router.push({ name: 'user', params: { userId: 123 }}) // 傳入路由描述物件
// 帶查詢引數,變成 /userlist?sex=male
this.$router.push({ path: '/userlist', query: { sex: 'male' }})
// router.replace
// 類似 window.history.replaceState不會向 history 新增新記錄,而是替換掉當前記錄,其他與router.push無異
// <router-link :to="..." replace> 對應 router.replace(...)
this.$router.replace('/home') // 傳入路徑字串
this.$router.replace({ path: 'home' }) // 傳入路由描述物件
// router.go
// 類似 window.history.go
this.$router.go(1) // 前進一步,等同於 history.forward()
this.$router.go(-1) // 後退一步,等同於 history.back()
this.$router.go(-1) // 後退三步,等同於 history.go(-3)
}
}
複製程式碼
六、路由傳參
動態路由匹配也算是一種路由傳參,詳見第二大點
二、動態路由匹配(相當於路由傳參)
最常用的傳參方式就是通過以下兩種方式:
<router-link>
標籤中的to
屬性的路由物件傳入欄位params
router.push
中的路由物件傳入欄位params
上面兩種方式本質上是相同的,只不過是宣告式和程式設計式兩種表現
這裡需要注意的是,傳入的路由物件中,如果傳入了path
欄位,則params
欄位會被忽略。所以當需要傳參時,一般傳入name
欄位來描述路由地址。
// Main.js
// 配置路由時注意需傳參的路由要進行命名
const router = new VueRouter({
routes : [
{path: '/home',component: Home},
{path: '/param',component: Param, name: 'param'}
]
})
// App.vue
// 在模板中,配置路由渲染出口及傳參
<template>
<div>
<p>路由傳參</p>
<p>
<router-link to="/">主頁</router-link>
<router-link to="{name: 'param', params: {msg: '宣告式路由跳轉傳入的引數'}}">宣告式傳參</router-link>
<button @click="$router.push({name: 'param', params: {msg: '程式設計式路由跳轉傳入的引數'}})">程式設計式傳參</button>
</p>
<router-view></router-view>
</div>
</template>
// Param.vue 中接收引數
<template>
<div>
<p>接收的引數:{{$route.params.msg}}</p>
</div>
</template>
複製程式碼
七、路由重定向和別名
// 路由重定向
// 意味著訪問/a會定向到/b,URL也會變為/b
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' },
{ path: '/c', redirect: {name: 'use'}}
]
})
// 路由別名
// 意味著訪問/b會匹配到/a,URL保持為/b
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
{ path: '/a', component: A, alias: ['/b', '/c'] }
]
})
複製程式碼
八、路由鉤子函式(導航守衛)
- 全域性前置守衛:beforeEach
- 全域性解析守衛:beforeResolve
- 全域性後置鉤子:afterEach
- 路由守衛:beforeEnter
- 元件守衛:beforeRouteEnter
- 元件守衛:beforeRouteUpdate
- 元件守衛:beforeRouteLeave
// Main.js中
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
// 【路由守衛beforeEnter】
beforeEnter(to, from, next) {
console.log('路由守衛:beforeEnter')
// ...
next() // 確保要呼叫 next 方法
}
}
]
})
// 【全域性前置守衛beforeEach】
router.beforeEach((to, from, next) => {
console.log('全域性前置守衛:beforeEach')
// ...
next() // 確保要呼叫 next 方法,否則鉤子就不會被 resolved
})
// 【全域性解析守衛beforeResolve】
router.beforeResolve((to, from, next) => {
console.log('全域性解析守衛:beforeResolve')
// ...
next() // 確保要呼叫 next 方法,否則鉤子就不會被 resolved
})
// 【全域性後置鉤子afterEach】
router.afterEach((to, from) => {
console.log('全域性後置鉤子:afterEach')
// ...
})
// Home.vue中
export default {
// 【元件守衛beforeRouteEnter】
beforeRouteEnter (to, from, next) {
// 在渲染該元件的對應路由被 confirm 前呼叫
// 不!能!獲取元件例項 `this`,可以傳一個回撥給 next,將元件例項作為引數來訪問元件例項
console.log('元件守衛:beforeRouteEnter')
next(vm => {
// vm即為元件例項
})
},
// 【元件守衛beforeRouteUpdate】
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該元件被複用時呼叫,例如動態路由
// 可以訪問元件例項 `this`
console.log('元件守衛:beforeRouteUpdate')
next() // 確保要呼叫 next 方法
},
// 【元件守衛beforeRouteLeave】
beforeRouteLeave (to, from, next) {
// 導航離開該元件的對應路由時呼叫
// 可以訪問元件例項 `this`
console.log('元件守衛:beforeRouteLeave')
next() // 確保要呼叫 next 方法
},
created() {
console.log('元件生命週期:created')
},
mounted() {
console.log('元件生命週期:mounted')
}
}
複製程式碼
執行順序
參考文章
這兩天學習vue-router的筆記,後續學習到的地方再做補充,有誤的地方求大神指出