Vue 雖然由 Component 所構成,為了模擬出不同頁面有不同網址,Vue 官方也提供了 Vue Router,這是前端自己的 Route,有別於後端的 Route。
Version
macOS Mojave 10.14.5
Node 12.4.0
Vue CLI 3.8.4
Vue 2.6.10
Vue-router 3.0.3
Add Vue-Router
Vue CLI 已經整合 Vue Router,可以直接建立含有 Vue Router 的 project。
$ vue create vue-router-basic
使用 Vue CLI 的 vue create
建立 vue-router-basic
。
Vue Router 雖然為官方 package,但預設並沒有包含在 Vue 內,因此需要選擇 Manually select features
另外安裝。
除了預設的 Babel
與 Linter / Formatter
外,使用 space bar 選擇 Router
。
History Mode
選擇 n
。
至於什麼是 History Mode ? 在 Vue Router 之 History Mode 有詳細討論
選擇 ESLint with error prevention only
。
選擇 Lint on save
。
選擇 In dedicated config files
,也就是 Babel、PostCSS、ESLint … 等工具都有自己的 config 檔,而不會全部集中在 package.json
。
Save this as a preset for future projects
選擇 n
,也就是預設不使用 Vue Router。
成功建立含有 Vue Router 的 project。
在 package.json
可以看到 "vue-router" : "^3.0.3"
,表示 vue-router
已經安裝成功。
$ yarn serve
在專案目錄下輸入 yarn serve
啟動 Vue CLI 內建的 web server。
Vue 內建 web server 預設啟動在 http://localhost:8080
。
Home
的 route 為/
- 與 Vue 預設專案不同,已經多了
Home
與About
- 點
About
,則進入了About
page About
的 route 為/about
Architecture
rounter.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
Vue.use(Router);
export default new Router({
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')
}
]
});
與一般 Vue 專案不同,在 src
目錄下多了route.js
,為統一設定 route 之處。
第 2 行
import Router from 'vue-router';
import
進 vue-router
的 class,並自己取名為 Router
。
此為 ES6 的 default export,因此可自行命名
第 5 行
Vue.use(Router);
Vue 規定若 package 要供 Vue 使用,則可使用 Vue.use()
傳進 package 的 class、object 或 function。
第 7 行
export default new Router({
這相當於
let router = new Router();
export default router;
只是 Vue 將兩行寫成一行,將 Router
object 使用 defaul export。
第 8 行
routes: [
以 routes
為 property,將 route 以陣列設定。
第 9 行
{
path: '/',
name: 'home',
component: Home,
},
- path : 設定 route path
- name : 設定 route 的名稱
- component : 設定 route 所使用的 component
由於 Vue 是基於 component 與 SPA 架構,換 route 只是換 component 而已
14 行
{
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'),
},
若要使 component 有 lazy loading 效果,也就是不要將該 component 包在 chunk-vendors.[hash].js
內,而是另外獨立的 .js
,只有當該 route 真正被執行時,才會下載 route.[hash].js
。
/* webpackChunkName: "about" */
並非註解,而是給 Webpack 看的,可以省略,會自動以hash
值作為檔名,實務上建議與 route 名稱相同,可藉此觀察 Webpack 是否正確啟動 lazy loading
main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
第 3 行
import router from './router';
將自己 router.js
import 進來,不是 vue-router
。
第 7 行
new Vue({
router,
render: h => h(App),
}).$mount('#app');
將 router
傳進 Vue instance。
App.vue
<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>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
第 4 行
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
若要使用 Vue Router 所定義的 route,不能再使用 <a/>
,而要改用 Vue 所提供的 <router-link/>
component,並使用 to
directive 指定 route。
第 7 行
<router-view/>
<routr-view/>
為 component 的 place holder,將來改變 route,component 的切換就是在 <router-view/>
。
Build Target
實際執行 yarn build
,看看 Vue Route 如何支援 lazy loading。
$ yarn build
在專案目錄下輸入 yarn build
將整個專案編譯打包到 dist
目錄下。
chunk-vendors.*.js
:在 node_modules
所使用的 package,如 Vue、Vue Router、Axios 會被編譯在此。
app.*.js
:Root component app.vue
被編譯在此。
about.*.js
:About.vue
被編譯在此。
也就是當執行首頁時,只會載
chunk-vendors.*.js
與app.*.js
,只有當 about 被點擊時,才會下載about.*.js
,如此可加速首頁下載速度
yarn build
所產生的檔案皆放在 dist
目錄下,將這些檔案全部搬到 web server 即可。
Deployment
Vue CLI 預設沒有提供 dist
目錄下的 web server,需另外安裝 package。
$ yarn global add serve
安裝 serve
package 於 global。
安裝 serve
package 完成。
$ serve dist
在專案目錄下輸入 serve dist
,其中 dist
為目錄名稱,因為 yarn build
所產生的檔案皆放在 dist
目錄下。
serve
將 dist
目錄啟動在 http://localhost:5000
。
在 http://localhost:5000
成功執行 Vue。
Conclusion
- Vue CLI 已經將 Vue Router 整進來,讓我們可快速建立 route
- Vue Router 支援 lazy loading,可將 component 分別打包在個別的
.js
,增加首頁下載速度 - 若要執行
dist
目錄下的檔案,要另外安裝serve
套件 yarn serve
與serve dist
雖然都能執行,但原理不同;yarn serve
是執行src
目錄下的 JavaScript,而serve dist
是執行dist
目錄下的 JavaScript
Sample Code
完整範例可在我的 GitHub 上找到