vue vue2.x 路由學習筆記Vue Router 是 Vue.js 官方的路由管理器。嵌套路由命名視圖(router-view複用)重定向和别名路由導航守衛3、路由獨享的守衛4、元件内的守衛過渡動效 單個路由的過渡滾動行為路由選中樣式2中實作方式

Vue Router 是 Vue.js 官方的路由管理器。
1、安裝
npm install vue-router
vue-cli 安裝vue-router後自動生成router檔案夾,裡面的index.js檔案就是路由檔案
在index.js路由檔案中
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
在main.js中引入并挂在到執行個體上
import router from './router'
2、使用
<p>
<!-- 使用 router-link 元件來導航. -->
<!-- 通過傳入 `to` 屬性指定連結. -->
<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由比對到的元件将渲染在這裡 -->
<router-view></router-view>
動态路由比對
const router = new VueRouter({
routes: [
// 動态路徑參數 以冒号開頭
{ path: '/user/:id', component: User }
]
})
一個“路徑參數”使用冒号
:
标記。當比對到一個路由時,參數值會被設定到
this.$route.params
,可以在每個元件内使用。
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
嵌套路由
<div id="app">
<router-view></router-view>
</div>
這裡的
<router-view>
是最頂層的出口,渲染最進階路由比對到的元件。同樣地,一個被渲染元件同樣可以包含自己的嵌套
<router-view>
const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
要在嵌套的出口中渲染元件,需要在
VueRouter
的參數中使用
children
配置:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// 當 /user/:id/profile 比對成功,
// UserProfile 會被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 當 /user/:id/posts 比對成功
// UserPosts 會被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
例如:
程式設計式的導航
this.$router.push(“/home”);
// 字元串
router.push('home')
// 對象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 帶查詢參數,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
es6 ` `符号 中間可放變量參數
router.push({ path: `/user/${userId}` }) // -> /user/123
router.replace({name:"home"}), router.replace('/'), router.replace({path:"/home"}),
// 在浏覽器記錄中前進一步,等同于 history.forward()
router.go(1)
// 後退一步記錄,等同于 history.back()
router.go(-1)
命名路由
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 }})
命名視圖(router-view複用)
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
重定向和别名
重定向也是通過
routes
配置來完成,下面例子是從
/a
重定向到
/b
:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
路由元件傳參
父傳子
在父級data中聲明屬性 message:“父傳子”
父級綁定屬性<father :msg="message"></father>
在子元件中data同級聲明props:[ "msg" ],在子元件中就可以調用 <h1>{{ msg }}</h1> ==> 父傳子顯示
- 子元件在props中建立一個屬性,用以接收父元件傳過來的值
- 父元件中注冊子元件
- 在子元件标簽中添加子元件props中建立的屬性
- 把需要傳給子元件的值賦給該屬性
子傳父
- 子元件中需要以某種方式例如點選事件的方法來觸發一個自定義事件
- 将需要傳的值作為$emit的第二個參數,該值将作為實參傳給響應自定義事件的方法
- 在父元件中注冊子元件并在子元件标簽上綁定對自定義事件的監聽
路由設定mode的兩個值
- histroy:當你使用 history 模式時,URL 就像正常的 url,去除#
-
vue vue2.x 路由學習筆記Vue Router 是 Vue.js 官方的路由管理器。嵌套路由命名視圖(router-view複用)重定向和别名路由導航守衛3、路由獨享的守衛4、元件内的守衛過渡動效 單個路由的過渡滾動行為路由選中樣式2中實作方式 - hash:預設’hash’值,但是hash看起來就像無意義的字元排列,不太好看也不符合我們一般的網址浏覽習慣。
-
vue vue2.x 路由學習筆記Vue Router 是 Vue.js 官方的路由管理器。嵌套路由命名視圖(router-view複用)重定向和别名路由導航守衛3、路由獨享的守衛4、元件内的守衛過渡動效 單個路由的過渡滾動行為路由選中樣式2中實作方式
路由導航守衛
1、全局守衛
在main.js中
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
每個守衛方法接收三個參數:
-
: 即将要進入的目标 路由對象to: Route
-
: 目前導航正要離開的路由from: Route
-
: 一定要調用該方法來 resolve 這個鈎子。執行效果依賴next: Function
方法的調用參數。next
-
: 進行管道中的下一個鈎子。如果全部鈎子執行完了,則導航的狀态就是 confirmed (确認的)。next()
-
: 中斷目前的導航。如果浏覽器的 URL 改變了 (可能是使用者手動或者浏覽器後退按鈕),那麼 URL 位址會重置到next(false)
路由對應的位址。from
-
或者next('/')
: 跳轉到一個不同的位址。目前的導航被中斷,然後進行一個新的導航。你可以向next({ path: '/' })
傳遞任意位置對象,且允許設定諸如next
、replace: true
之類的選項以及任何用在name: 'home'
的router-link
prop 或to
中的選項。router.push
-
: (2.4.0+) 如果傳入next(error)
的參數是一個next
執行個體,則導航會被終止且該錯誤會被傳遞給Error
注冊過的回調。router.onError()
-
2、全局後置鈎子
你也可以注冊全局後置鈎子,然而和守衛不同的是,這些鈎子不會接受
next
函數也不會改變導航本身
router.afterEach((to, from) => {
// ...
})
3、路由獨享的守衛
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
4、元件内的守衛
最後,你可以在路由元件内直接定義以下路由導航守衛:
-
beforeRouteEnter
-
(2.2 新增)beforeRouteUpdate
-
beforeRouteLeave
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`
}
}
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()
}
完整的導航解析流程
- 導航被觸發。
- 在失活的元件裡調用離開守衛。
- 調用全局的
守衛。beforeEach
- 在重用的元件裡調用
守衛 (2.2+)。beforeRouteUpdate
- 在路由配置裡調用
。beforeEnter
- 解析異步路由元件。
- 在被激活的元件裡調用
。beforeRouteEnter
- 調用全局的
守衛 (2.5+)。beforeResolve
- 導航被确認。
- 調用全局的
鈎子。afterEach
- 觸發 DOM 更新。
- 用建立好的執行個體調用
守衛中傳給beforeRouteEnter
的回調函數。next
過渡動效
<router-view>
是基本的動态元件,是以我們可以用
<transition>
元件給它添加一些過渡效果:
<transition>
<router-view></router-view>
</transition>
<transition>标簽
想讓路由有過渡動畫,需要在<router-view>标簽的外部添加<transition>标簽,标簽還需要一個name屬性。
1 2 3 | <transition name="fade"> <router-view ></router-view> </transition> |
我們在/src/App.vue檔案裡添加了<transition>标簽,并給标簽起了一個名字叫fade。
css過渡類名:
元件過渡過程中,會有四個CSS類名進行切換,這四個類名與transition的name屬性有關,比如name=”fade”,會有如下四個CSS類名:
- fade-enter:進入過渡的開始狀态,元素被插入時生效,隻應用一幀後立刻删除。
- fade-enter-active:進入過渡的結束狀态,元素被插入時就生效,在過渡過程完成後移除。
- fade-leave:離開過渡的開始狀态,元素被删除時觸發,隻應用一幀後立刻删除。
- fade-leave-active:離開過渡的結束狀态,元素被删除時生效,離開過渡完成後被删除。
從上面四個類名可以看出,fade-enter-active和fade-leave-active在整個進入或離開過程中都有效,是以CSS的transition屬性在這兩個類下進行設定。
那我們就在App.vue頁面裡加入四種CSS樣式效果,并利用CSS3的transition屬性控制動畫的具體效果。代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | .fade-enter { opacity:0; } .fade-leave{ opacity:1; } .fade-enter-active{ transition:opacity .5s; } .fade-leave-active{ opacity:0; transition:opacity .5s; } |
上邊的代碼設定了改變透明度的動畫過渡效果,但是預設的mode模式in-out模式,這并不是我們想要的。下面我們學一下mode模式。
過渡模式mode:
- in-out:新元素先進入過渡,完成之後目前元素過渡離開。
- out-in:目前元素先進行過渡離開,離開完成後新元素過渡進入。
單個路由的過渡
如果你想讓每個路由元件有各自的過渡效果,可以在各路由元件内使用
<transition>
并設定不同的 name。
const Foo = {
template: `
<transition name="slide">
<div class="foo">...</div>
</transition>
`
}
const Bar = {
template: `
<transition name="fade">
<div class="bar">...</div>
</transition>
`
}
基于路由的動态過渡
還可以基于目前路由與目标路由的變化關系,動态設定過渡效果:
<!-- 使用動态的 transition name -->
<transition :name="transitionName">
<router-view></router-view>
</transition>
// 接着在父元件内
// watch $route 決定使用哪種過渡
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
滾動行為
使用前端路由,當切換到新路由時,想要頁面滾到頂部,或者是保持原先的滾動位置,就像重新加載頁面那樣。
vue-router
能做到,而且更好,它讓你可以自定義路由切換時頁面如何滾動。
注意: 這個功能隻在支援
history.pushState
的浏覽器中可用。
當建立一個 Router 執行個體,你可以提供一個
scrollBehavior
方法:
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滾動到哪個的位置
}
})
scrollBehavior
方法接收
to
和
from
路由對象。第三個參數
savedPosition
當且僅當
popstate
導航 (通過浏覽器的 前進/後退 按鈕觸發) 時才可用。
這個方法返復原動位置的對象資訊,長這樣:
-
{ x: number, y: number }
-
(offset 隻在 2.6.0+ 支援){ selector: string, offset? : { x: number, y: number }}
如果傳回一個 falsy (譯者注:falsy 不是
false
,參考這裡)的值,或者是一個空對象,那麼不會發生滾動。
舉例:
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
對于所有路由導航,簡單地讓頁面滾動到頂部。
傳回
savedPosition
,在按下 後退/前進 按鈕時,就會像浏覽器的原生表現那樣:
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
如果你要模拟“滾動到錨點”的行為:
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash
}
}
}
異步滾動
scrollBehavior (to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 500)
})
}
路由選中樣式2中實作方式
1.
2、在router.js中配置