Vue3 - Router 基礎

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

cover image


回到 手把手開始寫 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>

然後到你的瀏覽器上,就可以去戳那兩個連結 HomeAbout,下面則會呈現出不同的畫面,且網址也會跟著做更新。

再來看這些路由是怎麼定義的,怎麼知道哪個網址應該呈現哪個內容,可以找到 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 的部分通常會使用兩種模式,分別是:

  • Hash
  • History

Hash

用這個方式網址會呈現 /#/ 為開頭,也就是說到 /about 實際上他是去 /#/about

另外用這個方式的 URL 永遠不會發到 Server,所以使用這種方式對 Server 不需要做任何設定,然後也會影響 SEO,如果對 SEO 有需求,請使用下一種方式。

然後這種方式是監聽瀏覽器的 hashchange 事件做到的,有興趣可以自己玩玩。

官方也有教你怎麼自己做一個簡易版的來玩玩,有興趣可以看這裡


History

我自己也比較喜歡這種方式,用這種方式的網址看起來乾淨漂亮,也就是說你到 /about,他的網址就是 /about!

不過這種方式需要你的伺服器支援,如果你沒做任何處理他就會跳到 404 頁面,因為那個路徑真的不存在!

基本上處理方式就是當你發現 Request 的資源不存在,就通通把他導向到 index 就可以了,因為他會在觸發 javascript 去做處理。

官方也很佛心的有給範例設定

另外這種方式叫做 History 是因為使用的底層是 HTML5History 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 的組件,也就是上面的 HomeViewAboutView

然後因為可能會有多個,所以他有個 name 屬性可以下,可以在路由定義的時候決定哪個 component 要渲染到哪個 RouterView 上,而這個在之後幾篇會再提到。




最後更新時間: 2022年07月24日.