Vue3 - Router 基礎
tags: Vue
category: Front-End
description: Vue3 - Router 基礎
created_at: 2022/07/24 22:00:00

回到 手把手開始寫 Vue3
前言
終於要開始導入 Router 了,在做 SPA(Single Page Application) 其中一個很重要的東西就是 Router,雖然沒有也可以做,但是就沒有辦法在 Url 上記錄一些資訊,導致可能重新整理之後就都跑回首頁。
再來接下來的幾篇文章都會是描述路由的使用方式。
前置作業
在最一開始,可以先回顧到 第一篇 - 開新專案與環境設定 這裡,在開啟專案的時候就將路由的選項打開,讓他幫你裝好。
✔ Add Vue Router for Single Page Application development? … No / Yes
這樣建立好專案之後,他一樣會有一些預設的程式碼和對你的 main.js 做一點手腳(?)(其實就是使用 router)
基本上就是多出兩個資料夾,分別是:
router: 存放路由定義views: 存放路由顯示的畫面(其實也是Component)
這時一樣先把專案整理一下,先把兩個要呈現的畫面簡化一下,也就是修改 views 裡面的兩個檔案。
<!-- src/views/HomeView.vue -->
<template>
<h1>This is an home page</h1>
</template>
<!-- src/views/AboutView.vue -->
<template>
<h1>This is an about page</h1>
</template>
之後再修改 App.vue,變成一個最簡單的路由範例(先不要管他怎麼定義的)。
<script setup>
import { RouterLink, RouterView } from "vue-router";
</script>
<template>
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
<div>
<RouterView />
</div>
</template>
然後到你的瀏覽器上,就可以去戳那兩個連結 Home 與 About,下面則會呈現出不同的畫面,且網址也會跟著做更新。
再來看這些路由是怎麼定義的,怎麼知道哪個網址應該呈現哪個內容,可以找到 router/index.js
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "home",
component: HomeView,
},
{
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("../views/AboutView.vue"),
},
],
});
export default router;
這段程式碼你可以看到那一段註解,他已經示範給你看怎麼在路由定義中使用上一篇所提到的懶加載(lazy-loaded),而路由大部分情況應該都使用懶加載,因為到特定頁面再去發所需的 Request 就好,才不會拖慢首頁的載入速度。
在上面那一段也可以看到,基本的用法基本上就是
{
path: '路徑',
component: 組件
}
那可能會想,那 name 是幹嘛的? (後面會提)
但這邊要先提的是 history 的部分。
History
在 history 的部分通常會使用兩種模式,分別是:
HashHistory
Hash
用這個方式網址會呈現 /#/ 為開頭,也就是說到 /about 實際上他是去 /#/about。
另外用這個方式的 URL 永遠不會發到 Server,所以使用這種方式對 Server 不需要做任何設定,然後也會影響 SEO,如果對 SEO 有需求,請使用下一種方式。
然後這種方式是監聽瀏覽器的 hashchange 事件做到的,有興趣可以自己玩玩。
官方也有教你怎麼自己做一個簡易版的來玩玩,有興趣可以看這裡
History
我自己也比較喜歡這種方式,用這種方式的網址看起來乾淨漂亮,也就是說你到 /about,他的網址就是 /about!
不過這種方式需要你的伺服器支援,如果你沒做任何處理他就會跳到 404 頁面,因為那個路徑真的不存在!
基本上處理方式就是當你發現 Request 的資源不存在,就通通把他導向到 index 就可以了,因為他會在觸發 javascript 去做處理。
官方也很佛心的有給範例設定
另外這種方式叫做 History 是因為使用的底層是 HTML5 的 History API
以上大概就是通常會選擇的兩種方式,然後去看官方才發現 Vue 有提供第三種,之前還真的沒想過(雖然偶爾可能真的有需求?)
第三種方式就是 Memory,其實用起來就感覺有點像只是依靠路由這個套件幫你做決定 Render 誰 ,但我又不想影響 URL,所以只存在記憶體中,也沒有歷史紀錄,那使用這個方式就沒辦法使用 上一頁/下一頁 這種功能。
而這三種方式用法都很簡單,只要替換掉 history 的值就可以了,下面列出對應:
hash:createWebHashHistory()history:createWebHistory()memory:createMemoryHistory()
name 的用途
如果定義的時候有 name 這個屬性,那你在使用 RouterLink 導向過去的時候,就可以使用 name,像這樣:
<RouterLink :to="{ name: 'home' }">Home</RouterLink>
<RouterLink :to="{ name: 'about' }">About</RouterLink>
那可能會想說,那我何不直接寫 /home 或 /about 就好,要多寫物件傳進去?
其中一個原因是,現在可以先想像未來要加上路由參數,也就是類似 /users/1 的數字 1,如果未來網址變得複雜,你可能需要寫這樣 '/users/' + user.id 之類的語法,那如果使用傳入物件的方式,就可以寫得更乾淨。
RouterView
最後剩下 RouterView 這個組件了,但不用講應該也猜到了,這個就是放路由 Render 的組件,也就是上面的 HomeView 或 AboutView。
然後因為可能會有多個,所以他有個 name 屬性可以下,可以在路由定義的時候決定哪個 component 要渲染到哪個 RouterView 上,而這個在之後幾篇會再提到。