最近在重溫vue全家桶,再看一遍感覺記憶更深刻,所以專門記錄一下(本文vue-router版本為v3.x)。
1,router-view
<router-view>
是一個功能性元件,用於渲染路徑匹配到的檢視元件。可以配合<transition>
和<keep-alive>
使用。如果兩個一起用,要確保在內層使用<keep-alive>
。
<router-view></router-view>
<!--或-->
<router-view name="footer"></router-view>
如果 <router-view>
設定了名稱,則會渲染對應的路由配置中 components
下的相應元件。
2,router-link
<router-link>
標籤支援使用者在具有路由功能的應用中(點選)導航。
屬性 | 型別 | 說明 |
---|---|---|
to | String/Object | 目標路由/目標位置的物件 |
replace | Boolean | 不留下導航記錄 |
append | Boolean | 在當前路徑後加路徑 /a => /a/b |
tag | String | 指定渲染成何種標籤 |
active-class | String | 啟用時使用的Class |
<router-link :to="{ path: '/login'}" replace tag="span"></router-link>
3,重定向redirect
根路由重定向到login
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' }
]
})
動態返回重定向目標
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目標路由 作為引數
// return 重定向的 字串路徑/路徑物件
}}
]
})
4,路由別名
路由訪問/b
時,URL
會保持為/b
,但是路由匹配則為/a
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
5,路由傳參props
使用props
,避免和$route
過度耦合,這樣就可以直接在元件中使用props
接收引數
5.1,布林模式
在路由後面寫上引數,並設定props
為true
{
path: '/vuex/:id',
name: 'Vuex',
component: () => import('@/view/vuex'),
props: true,
mate: {
title: 'vuex'
}
}
設定跳轉需要傳遞的引數params
<router-link :to="{name:'Vuex', params: {id: '99999'}}" tag="h1">跳轉</router-link>
<!--或者-->
toNext() {
this.$router.push({
name: 'Vuex',
params: {
id: '99999'
}
})
}
在跳轉過去的頁面,通過props
或者this.$params
取參
props: {
id: {
type: String,
default: ''
}
}
<!--或者-->
this.$params.id
5.2,物件模式
在路由中設定props
為物件,攜帶靜態資料
{
path: '/vuex',
name: 'Vuex',
component: () => import('@/view/vuex'),
props: {
id: '99999'
},
mate: {
title: 'vuex'
}
}
跳轉
<router-link :to="{name:'Vuex'}" tag="h1">跳轉</router-link>
<!--或者-->
toNext() {
this.$router.push({
name: 'Vuex'
})
}
在跳轉過去的頁面,通過props
或者this.$params
取參
props: {
id: {
type: String,
default: ''
}
}
<!--或者-->
this.$params.id
注意:只適用於靜態資料
5.3,函式模式
先在路由中設定props
為Function
,return
一個物件,不管是query
傳參還是params
傳參,都可以轉為props
{
path: '/vuex',
name: 'Vuex',
component: () => import('@/view/vuex'),
props: route => ({
<!--query-->
id: route.query.id,
<!--params-->
age: route.params.age
}),
mate: {
title: 'vuex'
}
}
跳轉
<router-link :to="{name:'Vuex',query: {id: '99999'}, params:{age:'20'}}" tag="h1">跳轉</router-link>
<!--或者-->
toNext() {
this.$router.push({
name: 'Vuex',
query: {
id: '999999'
},
params: {
age: '20'
}
})
}
在跳轉過去的頁面,通過props
或者this.$route.params / this.$route.query
取參
props: {
id: {
type: String,
default: ''
},
age: {
type: String,
default: ''
}
}
<!--或者-->
this.$route.query
this.$route.params
6,路由守衛
路由守衛主要用來通過跳轉或取消的方式守衛導航。
6.1,全域性前置守衛beforeEach
當一個導航觸發時,全域性前置守衛按照建立順序呼叫。守衛是非同步解析執行,此時導航在所有守衛解析完之前一直處於等待中。
引數 | 說明 |
---|---|
to | 即將要進入的目標路由物件 |
from | 當前導航正要離開的路由 |
next | 回撥方法 |
next用法如下
語法 | 說明 |
---|---|
next() | 進行下一個鉤子 |
next(false) | 中斷導航,URL如已改,則重置到from的地址 |
next('/') | 中斷當前跳轉併到其他地址,可設定路由物件 |
next(error) | 導航終止並傳遞錯誤給onError() |
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
6.2,全域性解析守衛beforeResolve
2.5.0新增,和beforeEach
類似,區別是在導航被確認之前,同時在所有元件內守衛和非同步路由元件被解析之後,解析守衛就被呼叫。
router.eforeResolve((to, from, next) => {
// ...
})
6.3,全域性後置鉤子afterEach
後置守衛不會接受next
函式也不會改變導航本身
router.afterEach((to, from) => {
// ...
})
6.4,路由獨享守衛beforeEnter
可以在路由配置上直接定義專屬的beforeEnter
守衛,與全域性前置守衛的方法引數是一樣的。
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
6.5,元件內的守衛
- beforeRouteEnter
該守衛不能訪問this
,因為守衛在導航確認前被呼叫,因此即將登場的新元件還沒被建立。可以通過傳一個回撥給next
來訪問元件例項。在導航被確認的時候執行回撥,並且把元件例項作為回撥方法的引數。
const Footer = {
template: `...`,
beforeRouteEnter(to, from, next) {
next(vm => {
// 通過 `vm` 訪問元件例項
})
}
}
- beforeRouteUpdate (2.2 新增)
在當前路由改變,但是該元件被複用時呼叫,可以訪問元件例項this
。
const Foo = {
template: `...`,
beforeRouteUpdate(to, from, next) {
this.name = to.params.name
next()
}
}
- beforeRouteLeave
導航離開該元件的對應路由時呼叫,通常用來禁止使用者在還未儲存修改前突然離開。可以通過next(false)
來取消。
const Foo = {
template: `...`,
beforeRouteLeave(to, from, next) {
const answer = window.confirm('確認要離開嗎')
if (answer) {
next()
} else {
next(false)
}
}
}
6.6,完整的導航解析流程
- 導航被觸發。
- 在失活的元件裡呼叫
beforeRouteLeave
守衛。 - 呼叫全域性的
beforeEach
守衛。 - 在重用的元件裡呼叫
beforeRouteUpdate
守衛 (2.2+)。 - 在路由配置裡呼叫
beforeEnter
。 - 解析非同步路由元件。
- 在被啟用的元件裡呼叫
beforeRouteEnter
。 - 呼叫全域性的
beforeResolve
守衛(2.5+)。 - 導航被確認。
- 呼叫全域性的
afterEach
鉤子。 - 觸發
DOM
更新。 - 呼叫
beforeRouteEnter
守衛中傳給next
的回撥函式,建立好的元件例項會作為回撥函式的引數傳入。
7,路由元資訊
定義路由的時候可以配置meta物件欄位,用來儲存每個路由對應的資訊。通過this.$route.meta
來訪問,或者在路由守衛中通過to.meta
和from.meta
訪問。
const router = new VueRouter({
routes: [
{
path: '/index',
name: 'Index',
component: () => import('@/view/index'),
meta: {
title: '首頁',
rolu: ['admin', 'boss']
}
}
]
})
8,過渡動效
只需要使用transition
標籤包裹住router-view
標籤即可,動畫效果可以自己定義,參考transition
元件的用法。也可以在父元件或者app.js
中使用watch
監聽$route
變化,根據不同路由替換transition
元件的name
屬性,實現不同的動畫效。
<transition :name="transitionName">
<router-view></router-view>
</transition>
監聽
watch: {
'$route' (to, from) {
const toD = to.path.split('/').length
const fromD = from.path.split('/').length
this.transitionName = toD < fromD ? 'slide-right' : 'slide-left'
}
}
9,滾動行為
當建立Router
例項時,可以提供一個scrollBehavior
方法,並接收to
和from
路由物件。第三個引數savedPosition
只有通過瀏覽器的前進/後退按鈕觸發時才可用。
const router = new VueRouter({
mode: 'hash',
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(savedPosition)
}, 1000)
})
} else {
return { x: 0, y: 0 }
}
}
})
10,完整路由配置
首先匯入Vue
和vue-router
,然後使用router
,定義路由資訊集合,每個路由都是一個物件,物件擁有如下屬性
屬性 | 型別 | 值 |
---|---|---|
path | String | 元件路徑資訊 |
name | String | 元件命名 |
component | Function | 元件 |
mate | Object | 元資訊 |
children | Object | 子路由 |
redirect | String | 重定向 |
props | Boolean/Object/Function | 引數傳遞 |
具體程式碼如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect: '/index'
},
{
path: '/index',
name: 'Index',
component: () => import(/* webpackChunkName: "index" */ '@/view/index'),
mate: {
title: '首頁',
auth: false
}
},
{
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '@/view/login'),
meta: {
title: '登入',
auth: false
},
children: [
{
path: 'children',
name: 'Children',
component: () => import(/* webpackChunkName: "children" */ '@/view/children'),
mate: {
title: '巢狀的子路由',
auth: false
}
}
]
}
]
const router = new VueRouter({
mode: 'hash',
routes
})
export default router
注意:巢狀子路由必須在被巢狀的頁面放置<router-view>
標籤。
如果看了覺得有幫助的,我是@鵬多多,歡迎 點贊 關注 評論;END
公眾號
往期文章
- 使用nvm管理node.js版本以及更換npm淘寶映象源
- 細數JS中實用且強大的操作符&運算子
- vue中利用.env檔案儲存全域性環境變數,以及配置vue啟動和打包命令
- 微信小程式實現搜尋關鍵詞高亮
- 超詳細!Vuex手把手教程
個人主頁