Vue Router
學習Vue Router的12條筆記。官方文檔位址:Vue Router。
- 使用
元件來導航路由,路由比對到的元件内容将顯示在<router-link to="/user">
中。<router-view >
- 通過注入路由器,我們可以在任何元件内通過
通路路由器,也可以通過this.$router
通路目前路由。this.$route
- r o u t e r 是 V u e R o u t e r 的 實 例 , 使 用 router是Vue Router的執行個體,使用 router是VueRouter的執行個體,使用router.push()可以導航到不同的URL;$route是目前router的跳轉對象,裡面可以擷取目前路由的name,path,query,parmas等。
-
和this.$router
使用起來完全一樣。我們使用router
的原因是我們并不想在每個獨立需要封裝路由的元件中都導入路由。this.$router
<div class="page-warrper">
<p>
<!-- 使用 router-link 元件來導航. -->
<!-- 通過傳入 `to` 屬性指定連結. -->
<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
<router-link to="/user">Go to user</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由比對到的元件将渲染在這裡 -->
<router-view></router-view>
</div>
- 把某種模式比對到的所有路徑全部映射到同一個元件内,需要
,動态路徑參數以冒号動态路徑參數
開頭,如:
,當比對到一個路由時,參數會被設定到{path:'/user/:id' ...}
中。this.$routere.params
- 某些與頁面顯示有關的參數也需要加到動态路徑參數中,如
。某頁面顯示相關參數(如type),在頁面重新整理時丢失,導緻頁面顯示不正确的情況
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// 動态路徑參數 以冒号開頭
{ path: '/user/:id/:type', component: User }
]
})
- 嵌套路由,需要在vue router中使用
配置,頁面面包屑展示為children
。如根路徑/子路徑
。活動/優惠券活動
const router = new VueRouter({
routes: [
{
path: '/campaign', // 以 / 開頭的嵌套路徑會被當作根路徑
redirect: '/campaign/coupons',
meta: { title: '活動', icon: 'flag' },
children: [
{
path: '/campaign/coupons', // 子路徑
name: 'campaign.coupons.list',
component: () => import('./pages/coupons/list'),
meta: { title: '優惠券活動' },
},
{
path: '/campaign/normal',
name: 'campaign.normal.list',
component: () => import('./pages/normal/list'),
meta: { title: '普通活動' },
},
],
},
],
})
- 程式設計式的導航。不使用
,而是在 Vue 執行個體内部,借助 router 的執行個體方法,通過編寫代碼來實作。<router-link :to="...">
-
方法,會向 history 棧添加一個新的記錄,是以,當使用者點選浏覽器後退按鈕時,則回到之前的 URL。router.push(...)
- 當你點選
時,這個方法會在内部調用,是以說,點選<router-link>
等同于調用<router-link :to="...">
。router.push(...)
- 該方法的參數可以是一個字元串路徑,或者一個描述位址的對象。
- 如果提供了 path時,params 會被忽略,你需要提供路由的 name 或手寫完整的帶有參數的 path,同樣的規則也适用于 router-link 元件的 to 屬性。
// 該方法的參數可以是一個字元串路徑,或者一個描述位址的對象
// 字元串
router.push('home')
// 對象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 帶查詢參數,變成 /user?userId=123
router.push({ path: '/user', query: { userId: '123' }})
// 如果提供了 path,params 會被忽略,上述例子中的 query 并不屬于這種情況。取而代之的是下面例子的做法,你需要提供路由的 name 或手寫完整的帶有參數的 path. 同樣的規則也适用于 router-link 元件的 to 屬性.
router.push({ name: 'user', params: { userId: '123' }}) // -> /user/123
router.push({ path: `/user/${123}` }) // -> /user/123
// 這裡的 params 不生效: 提供了 path,params 會被忽略
router.push({ path: '/user', params: { userId: '123' }}) // -> /user
-
方法,不會向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉目前的 history 記錄。等同于router.replace(...)
,注意多了個<router-link :to="..." replace>
。replace
-
方法。方法的參數是一個router.go(n)
,意思是在 history 記錄中整數
,類似 window.history.go(n)。向前或者後退多少步
// 在浏覽器記錄中前進一步,等同于 history.forward()
router.go(1)
// 後退一步記錄,等同于 history.back()
router.go(-1)
// 如果 history 記錄不夠用,那就默默地失敗呗
router.go(-100)
router.go(100)
- Vue Router 的導航方法 (push、 replace、 go) 在各類路由模式 (history、 hash 和 abstract) 下表現一緻。
- 命名路由,在routers配置中給某個路由設定名稱
,導航時,可以給的name屬性
。to屬性傳一個對象
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user', // 設定名稱name屬性
component: User
}
]
})
// 給to屬性傳入一個對象
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
// 參數傳入一個對象
router.push({ name: 'user', params: { userId: 123 }})
- 命名視圖,想同級展示多個視圖,而不是嵌套展示,就可以在頁面中命名多個視圖。一個視圖使用一個元件渲染,是以
。確定正确使用對于同個路由,多個視圖就需要多個元件
。components 配置 (帶上 s)
<router-view class="view one"></router-view> // 沒有設定名字,那麼預設為 default
<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: homeView,
a: aView,
b: bView,
}
}
]
})
- 重定向,通過
。routers配置
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' } // 從 /a 重定向到 /b
{ path: '/a', redirect: { name: 'b' }} // 重定向的目标也可以是一個命名的路由
{ path: '/a', redirect: to => { // 重定向的目标可以是一個方法,動态傳回重定向目标
// 方法接收 目标路由 作為參數
// return 重定向的 字元串路徑/路徑對象
}}
{ path: '/user', component: User, alias: '/user/list' } // 設定别名alias
// 路徑'/user'的别名是'/user/list',通路别名'/user/list'時,URL路徑保持為别名'/user/list',但路徑比對為'/user',就像通路'/user'一樣。
]
})
- vue-router的路由模式:
,hash模式
。history模式
-
:hash模式
-
,如https://www.abc.com/index.html/#hello,hash的值為位址欄URL中有#
。#hello
- 特點是hash值雖然出現在URL中,但不會包含在http請求中,對後端沒有影響,
,改變hash不會重新加載頁面
。路徑不比對也不會404
-
:history模式
-
,美觀一點。位址欄URL中沒有#
- 特點是
,如果後端缺少對某一URL的路由處理,将傳回404,前端的URL必須與實際向後端發請求的URL一緻,需要後端支援
。前端需要支援404頁面
- 導航守衛。(導航指路由正在發生改變),通過跳轉或取消的方式守衛導航,
。參數和查詢的改變不會觸發進入/離開的導航守衛
- 每個守衛接受三個參數:
即将進入的路由 ,to
正要離開的路由,from
一定要調用該方法來 resolve 這個鈎子。執行效果依賴 next 方法的調用參數。元件内才有參數vm,因為它不能通路this。next()函數
- 完整的導航解析流程:
1. 導航被觸發(頁面跳轉、取消路由)
2. 在`失活的元件内`調用`beforeRouteLeave`守衛
3. 調用全局的`beforeEach`守衛
4. 在`重用的元件`裡調用`beforeRouteUpdate`守衛
5. 在路由配置裡調用`beforeEnter`
6. 解析異步的路由元件
7. 在被激活的元件裡調用`beforeRouteEnter`
8. 調用全局的`beforeResolve`
9. 導航被确認
10. 調用全局的`afterEach`鈎子
11. 觸發DOM更新
12. 調用`beforeRouteEnter`守衛中傳給next的回調函數,建立好的元件執行個體會作為回調函數的參數傳入
- 路由元資訊,
字段。我們需要周遊meta
來檢查路由記錄中的meta字段。$route.matched
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// 路由元資訊
meta: { requiresAuth: true }
}
]
}
]
})
- 資料擷取:
,導航完成前擷取
。導航完成後擷取
-
:在元件的導航完成前擷取
守衛中擷取資料,當資料擷取成功,調用守衛的next()方法。beforeRouteEnter
-
:馬上進行導航和渲染元件,在元件的導航完成後擷取
鈎子中擷取資料,擷取過程中需要created
。展示loading狀态
- 路由懶加載,
,當路由被通路時菜加載對應的元件。避免當打包建構應用時,JavaScript 包會變得非常大,影響頁面加載的問題。把不同路徑對應的元件分割成不同的代碼塊
- 把某個路徑下的元件打包成同個異步塊(chunk),使用一個特殊的注釋
,通常為一個子產品的增删查改所有頁面。webpackChunkName: ".."
const router = new VueRouter({
routes: [
{ path: '/user',
component: () => import(/* webpackChunkName: "user" */ './pages/user/list'),
}
]
})
const Bar = () => import(/* webpackChunkName: "user" */ './pages/user/create')
const Baz = () => import(/* webpackChunkName: "user" */ './pages/user/edit')