使用Vue Cli 建立Vue Router 專案
在上一篇「Vue Router頁面路由初次體驗 — 安裝與使用」中,使用了CDN的方式來說明各種 Vue Router 基本的建立與使用方式。在這篇裡面要使用 Vue Cli (Vue.js Command-Line Interface)來實際的建立具備Vue Router 功能的專案。至於為什麼要使用 Vue Cli建立專案以及要如何在開發的環境中安裝Vue CLI,可以參考這一篇「Vue.js 使用Vue CLI安裝 Vue3」。
有鑒於目前Vue有兩個版本,Vue2.x與Vue3.x,且這兩個版本目前在實務上都被人使用(如讀者沒有支援 IE 的需求,就不需要兩者都理解),秉持著實驗的精神,在這裡將實作兩種狀況。
建立的步驟
不論是選擇建立Vue2.x或者是Vue3的專案,透過Vue Cli建立的方式基本上並沒有什麼差異,整個專案的建立過程不到2分鐘,非常的迅速。
步驟 1
首先要使用vue create 指令建立專案:
$ vue create my-project
步驟 2
接著要選擇手動設定(Manually select features)自訂各種選項。
步驟 3
在手動設定中可以選擇想要調整的各種選項。此時為要在專案中加上Vue Router,需使用鍵盤的「上」、「下」鍵選到Router的位置,並以「Space空白鍵」,選擇該項目。這裡我們要增加的Router選項,在選擇成功後,選項Router前面的圈圈,就會從空心變實心。(見下圖,此時選項Route尚未被選取成功,而Choose Vue version與Babel則是已經被選取的項目)
步驟 4
這個步驟要選擇Vue的版本,方法同上一步驟,請使用上、下鍵調整到想要安裝的Vue版本。這裡我們先選擇2.x版,之後會再建立另外一個3.x的專案。
步驟 5
這個步驟會問你:
Use history mode for router?
也就是說,是否要在專案中使用history模式?那到底「選」與「不選」之間有什麼差異?
如果選擇Y,表示專案會採用history API來管理。由於Vue Router預設的模式為hash 模式,這表示網址會使用URL 的 hash ( #
)來模擬一個完整的URL,在URL裡面會出現像是井號「 #
」的hash符號。如果您跟我一樣覺得網址裡面出現井號很醜,而不希望出現hash的話,可以採用 history 模式。因此,我在這問題後面輸入「Y」。
步驟 6
由於我們選了Babel選項,因此在這裡會問我們希望把相關套件的設定放在何處?
一般都會放在package.json檔案裡面來統一管理,但是也可以選擇『In dedicated config files』來各自獨立。
步驟 7
最後的問題是,是否要儲存先前自訂選項的設定,以便於下次專案使用?
你可以輸入『 y 』儲存,或輸入『 N 』不儲存,這裡選擇 N不儲存。接下來只需要等待 VueCLI 幫我們安裝專案所需的相關套件。
走過上面的步驟後,就可以完成一個具備Vue Router的Vue專案,使用七個步驟就完成設定,很方便吧。
比較2.x與3.x 的Vue專案
為了理解不同版本的Vue建立出來的專案有沒有差異,我們會使用同樣流程,但使用不同Vue版本建立兩個專案。因此,走過七個步驟建立完Vue 2.x的專案後,我們要再走一次,來建立另一個Vue 3.x的專案。
當建立完成兩專案後,就可以來比較看看二者間有什麼差異。
資料結構:無異
我們將沿著由外而內的方式來比較兩個專案。先從資料結構來看,Vue 2.x的專案產生的目錄與檔案與Vue 3.x產生的專案並沒有不同,都像下圖顯示的一一樣。因此,從資料結構上尚看不出目前拿到的是Vue2還是Vue3的專案。
套件相依設定檔package.json
接著從根目錄裡面的檔案開始看。我們發現 Vue 2.x專案裡面的 package.json(套件相依設定)檔,在部分安裝的套件上(在dependencies與 devDependencies 的地方)與 Vue 3.x專案的不同。
先前曾經提過,使用Vue Router時,要注意選用的版本:
由於Vue3.0的底層已經改寫過,而 Vue Router v3.x 以前的版本無法支援新版的 Vue.js ,需要使用Vue Router v4.x 的版本。
於是如果建立的專案是使用 Vue 2.x 版本的話,就要選用 Vue Router v3.x 來搭配;若使用的是 Vue 3.x 版本的話,則要選用 Vue Router v4.x 。
由實測可以得到應證,在安裝套件dependencies的部分,Vue2使用的是 2.6.11版的 vue與3.2.0版的vue-router,而在 Vue3 則使用3.0.0版本與4.0.0–0版的vue-router。以下是Vue3的package.json檔。
另外,在devDependencies的部分,二者的差異在於Vue2 使用 "vue-template-compiler": "^2.6.11"
;而Vue3 使用 "@vue/compiler-sfc": "^3.0.0"
。由於 SFC(單一元件檔,即一個元件代表一個檔案) 中副檔名為vue的檔案並非網頁標準,所以在使用時必須透過 Vue CLI 的 vue-loader
或@vue/compiler-sfc
來轉譯,才能使其成為瀏覽器能看懂的js程式碼。
router/index.js檔
接下來,要比較 router資料夾裡面的 index.js 檔的差異。首先映入眼簾的是Vue2的 index.js 檔。
接下來的這張圖顯示的是Vue3的index.js檔。
從程式碼的行數來看,Vue 3.x 的index.js檔使用的行數(26行)比Vue 2.x的行數(29行)較。
在從建立Vue Router所需的步驟(1到4)來檢視這兩個檔案:
- 定義個頁面的Vue元件;
- 定義路徑與前面Vue元件的關係;
- 初始化並建立Vue Router物件;
- 將Vue Router物件添加入Vue實例中。
定義個頁面的Vue元件的地方,可以發現引入vue router 的地方,Vue2.x 採用的import
方式如下:
import VueRouter from 'vue-router'
而 Vue3.x 採用的import
方式則變成下面的樣子:
import { createRouter, createWebHistory } from 'vue-router'
因為我們在Vue Cli 裡面選擇了 history 模式的關係,Vue3.x 引入的地方多了 createWebHistory
。
而在Vue2.x需要加上.use()
來使用VueRouter,Vue3.x 則不需要。
Vue.use(VueRouter)
這是因為Vue 3.0 開始不再提供功能的全域性註冊,必須註冊在根元件實體上。所以,我們在Vue3.x的index.js裡面不會看到上面的.use()
使用方式。但卻會出現在後面提到的Vue3.x的main.js 檔裡面。
在「定義路徑與前面Vue元件的關係」的地方兩者一樣,可以略過不討論。而在步驟3「初始化並建立Vue Router物件」的階段,Vue 2.x採用VueRouter()
建立實體:
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
而Vue 3.x則採用 createRouter()
建立:
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
至於history模式,Vue 2.x 使用 mode: 'history',
表示,而Vue 3.x 則是改用 history: createWebHistory(process.env.BASE_URL),
的方式處理。
main.js檔
下圖是Vue 2.x 的main.js檔:
而Vue 3.x 的main.js檔則如下圖:
前面提到過,因Vue 3.x不再提供功能的全域性註冊,必須註冊在根元件實體上。所以,.use(router)
會出現在這個檔案中。
以上是在Vue2.x與Vue3.x上面安裝vue-router的比較。
開始使用Vue Router
當我們使用Vue Cli 建立專案,並且在建立的時候選擇了Router的選項,一旦專案建立完畢,啟動(使用npm run serve
指令)開發伺服器後,就可以馬上獲得一個範例。如下圖:
這個頁面的最上面,會自動給我們一組連結,讓我們可以在 Home 與 About間進行頁面的切換。
在此狀態下,只需要執行「定義各頁面的Vue元件」與「定義路徑與前面Vue元件的關係」兩個步驟,就可以建立其他的頁面。
定義各頁面的Vue元件
假設我們需要一個「會員專區」的單元,可以採取下面的方式定義會員專區的元件:在專案的views資料夾裡面,新增一個Users.vue檔案。這是個單一元件檔(SFC),也就是一個.vue檔案代表一個元件,一般來說檔案命的名稱(Users.vue)即是元件的名稱(Users元件)。這個檔案裡面包含<template>
、<script>
與<style>
三個部分。
// Users元件
<template>
<div>
<h1>會員專區</h1>
<p>歡迎來到會員專區。</p>
<p>請選擇會員名稱進入</p>
</div>
</template><script>
export default {};
</script><style></style>
Users元件建立完畢之後,應該會類似上面的程式碼。由於目前<script>與<style>並沒有任何的值,可以省略之。
定義路徑與前面Vue元件的關係
接著我們要在routes陣列中,定義路徑與Users元件的關係。實際上,Vue Cli 已經替我們建立了routes陣列,它位於router資料夾裡面的index.js檔案中。
下面的程式碼就是位於index.js檔案中的routes陣列。其中,非粗體字的部分是Vue Cli幫我們建立的,我們可以依樣畫葫蘆的依照同樣方式定義users頁面與Users元件的關聯(粗體字部分)。
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
},
{
path: '/users',
name: 'Users',
component: () => import('../views/Users.vue')
}
]
在定義關係時,每個route物件可以有三組key-value值。包括name、path與component。其中,
- path:URL位置;
- name:路由的名稱,可以使用名稱指定路由;
- component:當到達指定URL時,需要對應的元件,在這裡採用的是import的方式將元件對應到路由(非同步載入元件)。
將標籤加入HTML
#加入 <router-link>
定義完路徑與前面Vue元件的關係後,可以打開App.vue檔案,這個檔案裡面含有<router-view>
,是用來渲染內容的地方。我們要在template裡面添加<router-link>
來產生對應的連結。<router-link>
在經過編譯之後,會變成HTML超連結<a>
標籤。
<template>
<div id="app">
<div id="nav">
<router-link :to="{name:'Home'}">Home</router-link> |
<router-link :to="{name:'About'}">About</router-link> |
<router-link :to="{name:'Users'}">Users</router-link>
</div>
<router-view/>
</div>
</template>
粗體字的部分,是嗣後加上的連結。該連結可以連到users頁面。
在<router-link>
中使用to屬性用來處理目標URL,使用時可以在to的地方直接指定route path:
<router-link to="/users">Users</router-link>
除此之外,也可以指定route name。我們在這裡就以route name來對應。不過,使用上需要注意:在這裡 to
需要採用 v-bind 的方式( :to="{name:'About'}"
)。
<router-link :to="{name:'Users'}">Users</router-link>
#加入 <router-view>
在Vue2.x專案,<router-view>
要放在class id 為 app 的div標籤裡面。#app 為Vue實例掛載的位置( el:'#app'
)。在Vue3.x 時,則無此限制。
<div id="app">
略...
<router-view></router-view>
略...
</div>
設定後,使用者只要點選<router-link>
,就會透過router將對應結果顯示在<router-view>
的地方。
不同Vue版本,使用上不同
前面提到在Vue2.x的時候,<router-view>
要放在 #app 的裡面,然而在Vue3.x ,則無此限制。原因是Vue2.x 要求每個元件的template只能有一個 root 。因此在template裡面必須有一組根<div>,並且將所有html都要放在這個root <div>裡面,不然是無法繪製出畫面。而Vue3.x則可以不限一個根<div>。
下面的寫法在Vue 3.x專案下面,仍可以運行。但是若將同樣的template移到Vue2.x專案裡面時,就會出現錯誤。
結語
使用Vue Cli建立Vue專案非常的迅速,整個建立過程不到2分鐘。在實務上使用的機會也會比CDN的方式來的高。比較困難的部分,應該是決定到底應該替專案選哪些項目吧。本篇僅對於安裝與開始使用的初期階段進行討論。未來將會繼續討論關於動態路由(dynamic Route)、巢狀路由(nested Routes)等其他的使用方式。