# 17. 百頁路由
# 單頁式網頁與路由器
使用單頁式網頁的目的:
- 節省載入時間
- 動畫過場效果
在單頁式網頁中,網址和頁面的切換可透過路由器來實現。
- 使用路由器切換網址、控制顯示哪些組件。
- 在本機的網址中,用
#
可以讓瀏覽器不換頁。
# 加入 vue-router
透過終端機在 Vue CLI 加入 vue-router:
vue add router
執行成功之後,會看到專案資料夾中會有些檔案的變動 (修改、新增)。
# 異動:調整 main.js
加入 vue-router 之後,main.js 檔案的和原本的差異:
- 透過
import
載入 "router.js"。 - 將 router 放到
new Vue
裡面。
import Vue from 'vue'
import App from './App.vue'
import router from './router' // 載入 router.js
Vue.config.productionTip = false
new Vue({
router, // 將 router 放到 Vue
render: h => h(App)
}).$mount('#app')
# 異動:新增 router.js
router.js 用來定義此專案有哪些路徑,這些路徑會對應到哪一個 component。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
// 第一種載入方法
{
path: '/',
name: 'Home',
component: Home
},
// 第二種載入方法
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
在上方預設的程式碼中,展現了兩個路徑 (Home、About),以及路由的兩種載入方法。
# 載入方法一
- 先用
import
載入。 - 然後掛載到 router。
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
]
# 載入方法二
- 直接在 router 裡面透過函式
import
新的 component。
const routes = [
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
# 兩種方法的差異
在預設的程式碼中,"Home" 頁面使用方法一載入,"About" 頁面使用方法二載入。
如果透過方法二載入頁面,會依照 router 把程式碼分割開來。點擊連結進入頁面時,才會真正將那個頁面載入進來,可節省一開始網頁的讀取時間。但相對來說,缺點就是會比方法一多讀取一次網頁。
使用開發人員工具來看 "Network" 的部分,會看到一開始載入 Home
頁面時,使用方法二的 "about.js" 狀態碼會是 304。
- 狀態碼 304 : 未修改。用戶端要求該網頁時,其內容並沒有變更,應該回傳 304 告知網頁未修改。此時用戶端僅需要取得本地快取(Local Cache)的副本即可。
- 來源:The Will Will Web - 網頁開發人員應了解的 HTTP 狀態碼 (opens new window)
等到點擊了畫面中的 "About" 連結時, "about.js" 會再載入一次,而且這次的狀態碼會是 200。
這是因為 Vue 產生 prefetch
預備讀取,所以一開始的 "about.js" 才會是 304 狀態碼,以達到分檔、分別讀取的效果。
至於選擇何種方法載入 component,要看專案大小。如果專案較大,要載入的東西多,則適合使用方法二。
# 異動:修改 App.vue
原本的主畫面中,template
會藉由以下兩個標籤控制畫面:
router-link
用來切換畫面的連結按鈕。router-view
顯示被選擇的router-link
的內容。
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link>|
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
</template>
# 增加新路徑和畫面的步驟
新增步驟:
- 新增畫面 component
- 載入到 "router.js"
- 在主畫面 "App.vue" 加上路徑連結
# 1. 新增畫面 component
- 在 src > views 資料夾中,新增副檔名為 vue 的 component。
- 在此新檔案中撰寫程式碼。
- 要注意 component 的
template
最外面只能有一層 DOM。
//- Hello.vue
<template>
<h1>Hello, this is Hello.vue component.</h1>
</template>
# 2. 載入到 "router.js"
- 將新的 component 載入到 "router.js",並掛載到 router 裡面。
- 如果成功,在網址列後方修改為新 component 的路徑,就會看到 component 的內容。
//- router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Hello from '../views/Hello.vue' // 使用方法一載入新路徑
Vue.use(VueRouter)
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/hello', // 掛載新的 Hello.vue 路徑到 router
name: 'Hello',
component: Hello
},
]
// ...
# 3. 在主畫面 "App.vue" 加上路徑連結
- 到 "App.vue" 增加
router-link
,為主畫面加上通往新 component 的連結。
//- App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link>|
<router-link to="/about">About</router-link>|
<router-link to="/hello">Hello</router-link> // 加入新連結
</div>
<router-view />
</div>
</template>
結果如下:
# 說明:router-link 的 class 用法
Vue 內建了兩個 class ,可以讓我們拿來修改 router-link
的樣式。
router-link-active
:- 表示路由的過程、被經過的路由。較少被使用。
- 如果切換到
/about
,則路徑為/
的首頁也會套用到樣式。
router-link-exact-active
:- 表示目前所在的頁面,較常被使用。