###### <p style="text-align: right"> 建立日期:2020-12-19 / 更新日期:2020-12-21</p>
# Vue Router
###### tags: `Vue.js` `Vue Router`
## 簡介
* 由前端所模擬的路由管理器
## 配置檔
### /router/index.js
```javascript=
// 官方元件
import Vue from 'vue'
import Router from 'vue-router'
// 自訂的分頁元件
import Home from '@/views/Home'
Vue.use(Router)
// export default new Router({ // 另一種寫法,就不需要最後一行的 export default router
const router = new Router({
routes: [
{
path: '/',
redirect: '/home'
},
{
path: '',
redirect: '/home'
},
{
// path: '*',
path: "/:catchAll(.*)",
redirect: '/home'
},
{
path: '/home', // 對應的虛擬路徑
component: Home, // 對應的元件
name: 'home', // 命名路由
},
{
path: '/stores',
component: () => import('./views/stores.vue'), // Vue cli 3.x 版本後可以這樣寫,不用事先 import component
children: [ // 巢狀路由頁面
{
path: '/overseas',
component: () => import('./views/overseas.vue'),
},
{
path: '/taiwan',
component: () => import('./views/taiwan.vue'),
children: [
{
path: '/north',
component: () => import('./views/north.vue'),
},
{
path: '/south',
component: () => import('./views/south.vue'),
},
]
}
]
}
]
})
export default router
```
### main.js
```javascript=
import Router from './router' // 增加此行
new Vue({
el: '#app',
router // 增加此行
})
```
### 頁面
```htmlembedded=
<!-- 連結 -->
<router-link to="/">Home</router-link>
<router-link to="/store">Store</router-link>
<!-- 連結另一種寫法,命名的路由 -->
<router-link :to="{ name: 'home' }">Home</router-link>
<!-- 路由的 component 要渲染的位置 -->
<router-view></router-view>
```
## 動態路由,以 : 開頭
```javascript=
const router = new Router({
routes: [
{
path: '/product/:id',
component: Product
}
]
})
```
在頁面可以透過 `this.$route.params.id` 取得 id 的值
## 命名視圖
* 想同時載入多個 `<router-view></router-view>` 時使用
### /router/index.js
```javascript=
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: componentA,
menu: componentB,
section: componentC
}
}
]
})
```
### 頁面
```htmlembedded=
<router-view></router-view> <!-- 載入componentA -->
<router-view name="menu"></router-view> <!-- 載入componentB -->
<router-view name="section"></router-view> <!-- 載入componentC -->
```
## 其他參數
### mode
配置路由模式
* hash:預設值(瀏覽器環境),會有 #
* history:不會有 #,使用的是後端伺服器的路由,必須與後端搭配
* abstract:預設值(Node.js 環境)
### base
* /:預設值
* 若專案是掛載在其他目錄下,而非根目錄下時,需修改值
### linkActiveClass
設定 `<router-link>` active 時的 class 名稱
* 模糊比對
* 觸發路徑時會在標籤上加上特定 class 名稱,預設是 `"router-link-active"`
### linkExactActiveClass
設定 `<router-link>` active 時的 class 名稱
* 絕對比對
* 觸發路徑時會在標籤上加上特定 class 名稱,預設是 `"router-link-active"`
### meta
存放自訂參數
```javascript=
const router = new Router({
mode: 'history',
base: '/app/',
linkActiveClass: 'active',
linkExactActiveClass: 'exactActive',
routes: [
{
path: '/member',
component: Member,
meta: { // 存放自訂參數
requiresAuth: true, // 是否有成功登入取得授權
title: '會員專區' // 頁面的標題
}
}
]
})
/**
* 跳轉頁面前先判斷
* 1. 是否要登入,若要是否已取得授權
* 2. 置換頁面標題
**/
router.beforeEach((to, from, next) => {
if (to.meta.hasOwnProperty('requiresAuth') {
if (to.meta.requiresAuth) {
if (to.meta.title) {
document.title = to.meta.title
}
next()
} else { // 沒有登入,轉到登入頁
next({ path: '/login' })
}
} else {
if (to.meta.title) {
document.title = to.meta.title
}
next()
}
})
```
## 切換路由的方法
### router.push
* 會向 history 添加紀錄
```javascript=
// 在 Vue instance 裡可以使用 $router -> this.$router.push
router.push('home')
router.push({ path: 'home' })
router.push({ path: 'register', query: { plan: 'private' }}) // -> /register?plan=private
const userId = '123'
router.push({ name: 'user', params: { userId: '123' }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
router.push({ path: '/user', params: { userId }}) // -> /user,使用 path 時,會忽略 params
```
### router.replace
* 直接取代目前頁面,不會向 history 添加紀錄
### router.go
* 基於目前的位置,往前或往後
### router.back
* 回到前頁
### router.forward
* 下一頁
## 資料來源
* [Vue Router](https://router.vuejs.org/zh/ "Vue Router")
* [Vue 出一個電商網站](https://www.udemy.com/course/vue-hexschool/ "Vue 出一個電商網站")