iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
JavaScript

歡迎參加我的原生JS畢業典禮系列 第 22

【Day21】Vue Router幫我開路!

  • 分享至 

  • xImage
  •  

起初建立專案的時候,系統有詢問我們是否要導入Vue Router。用了是用了,不過它實質做了什麼改變呢?今天就來一探究竟吧!

特色

  • Client端路由:客端將SPA(單頁應用)中的URL和內容進行綁定。切換頁面的過程會自動更新URL,但不需要透過伺服器重新加載。
  • 以Vue組件系統為基礎:透過配置告訴Vue Router,URL所對應的組件。

實際運作

打開App.vue來瞧瞧,當我們先前實作新增nav分頁的時候,就是透過Vue Router來幫我做事:

//App.vue
  <header>
      <div class="wrapper">
          <HelloWorld msg="歡迎參加我的原生JS畢業典禮" />
          <nav>
              <RouterLink to="/">Home</RouterLink>
              <RouterLink to="/todolist">ToDoList</RouterLink>
              <RouterLink to="/shoppingcart">ShoppingCart</RouterLink>
          </nav>
      </div>
  </header>

<RouterView />
  • <RouterLink>:Vue Router中用來創建連結的組件,處理了URL的生成和編碼
  • <RouterView>:Vue Router中指定渲染位置的組件,用於專案的任何位置

創建Router

router資料夾中index.js設定相關資料:

//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: '/todolist',
      name: 'todolist',
      component: () => import('../views/ToDoListView.vue')
    },
    {
      path: '/shoppingcart',
      name: 'shoppingcart',
      component: () => import('../views/ShoppingCartView.vue')
    }
  ]
})

export default router
  • createRouter():創建Router實例
  • history:設定Route模式
    1. Hash模式:利用#創造錨點,在 同頁中不同節點 上轉跳,不需要重新刷新頁面;透過createWebHashHistory()啟動Hash模式。
    2. HTML5(History API)模式:Vue Router的預設模式,以createWebHistory()啟動,能用pushState()replaceState()來更新URL。
  • routes:定義Route的選項
  • path:組件對應的路徑設定
  • component:指定渲染組件的參數,可以由上方import以物件使用,或是直接引入絕對路徑

註冊Router

創建完之後,到main.js全域註冊路由器,一樣要在整個應用mount之前:

//main.js
import router from './router'

const app = createApp(App)

app.use(router)
app.mount('#app')

註冊完之後,就能在專案中使用:

  1. <RouterLink><RouterView>:和一般組件引用一樣,有分為PascalCase或kebab-case;使用於DOM內的模板,要透過kebab-case方式引入,如:<router-view></router-view>
  2. $router$route屬性:選項式API使用
  3. useRouter()useRoute()組合式函數:組合式API使用
  4. 觸發路由器解析初始路由

動態Route

在Router的使用上,也會碰到類似後端Route的功能,透過不同的URL(不同參數)指定到同一實體(組件):

import User from './User.vue'

//定義傳遞給`createRouter`
const routes = [
  //:id為動態字段,都會指定給User實體
  { path: '/users/:id', component: User },
]

畢竟是前端Router,終究是共用在一個已渲染完的實體,也意味著:組件的生命週期鉤子不會重新調用,這時候就會使用watch來監聽路由參數的變化並做出對應的處理:

<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
//取得route中的參數
watch(() => route.params.id, (newId, oldId) => {
  // 針對路由變化做出響應
})
</script>

在路由變化前,也提供beforeRouteUpdate的鉤子函數可以做出響應的處理或是取消轉跳:

<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...

onBeforeRouteUpdate(async (to, from) => {
  // 針對路由變化做出響應
  userData.value = await fetchUser(to.params.id)
})
</script>

變化用法

  • 自訂正則參數
    當有需要透過參數來區分不同路由的時候,就能使用正則([^/]+)
const routes = [
  //加入(\\d+),:orderId僅匹配數字
  { path: '/:orderId(\\d+)' },
  //:productName匹配其他任何内容
  { path: '/:productName' },
]
  • 特殊路由:/:pathMatch(.*)*
    用來將所有路由導向同一個實體,可以透過此方法實作errorPage;但使用*時,應把該路由放置最後,避免提前被轉跳至錯誤提示頁面:
const routes = [
  ...
  //應放置最後的errorPage
  { path: '/:pathMatch(.*)*',name:'errorPage',component:errorPage },
]

小結

初步了解Vue Router後才對前後端Router的運作模式有了基礎的概念,雖然這篇僅說明了Vue Router的設定相關和執行邏輯,不過還有很多應用層面的功能需要繼續鑽研,官方也提供了免費的影音教學帶我們入門:Vue Router教學影片


參考資料
Vue Router
重新認識Vue.js


上一篇
【Day20】Vue的分組報告—實作購物車(下)
下一篇
【Day22】Vue-SSR:這專案我還要嗎?ft.淺淺談Nuxt.js
系列文
歡迎參加我的原生JS畢業典禮31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言