###### <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 出一個電商網站")