Bài 4: Routing với Vue Router 4

Bài 4: Routing với Vue Router 4

Một ứng dụng SPA (Single Page Application) thường có nhiều “trang” như: Home, About, Products… Thay vì tải lại HTML, Vue sử dụng Vue Router để quản lý điều hướng.

1. Cài đặt Vue Router

Trong project Vue 3 (Vite), cài:

npm install vue-router@4

2. Cấu hình Router cơ bản

📂 Cấu trúc:

src/
 ┣ router/
 ┃ ┗ index.js
 ┣ views/
 ┃ ┣ Home.vue
 ┃ ┗ About.vue
 ┣ App.vue
 ┣ main.js

router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

export const router = createRouter({
  history: createWebHistory(),
  routes
})

main.js

import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')

App.vue

<template>
  <nav>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view />
</template>

👉 router-link: tạo link.
👉 router-view: nơi hiển thị component tương ứng.

3. Dynamic Routes

Khi cần hiển thị nội dung dựa vào tham số URL (ví dụ: /user/123).

router/index.js

import User from '../views/User.vue'

const routes = [
  { path: '/', component: () => import('../views/Home.vue') },
  { path: '/user/:id', component: User }
]

views/User.vue

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

const route = useRoute()
</script>

<template>
  <h2>Thông tin user có ID: {{ route.params.id }}</h2>
</template>

4. Nested Routes

Ví dụ /user/123/profile/user/123/posts.

router/index.js

import User from '../views/User.vue'
import UserProfile from '../views/UserProfile.vue'
import UserPosts from '../views/UserPosts.vue'

const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      { path: 'profile', component: UserProfile },
      { path: 'posts', component: UserPosts }
    ]
  }
]

views/User.vue

<template>
  <h2>Trang User</h2>
  <router-link :to="`${$route.params.id}/profile`">Profile</router-link> |
  <router-link :to="`${$route.params.id}/posts`">Posts</router-link>
  <router-view /> <!-- render nested -->
</template>

5. Navigation Guards

Dùng để bảo vệ route (ví dụ: chỉ cho login mới vào được).

router/index.js

const routes = [
  { path: '/login', component: () => import('../views/Login.vue') },
  { path: '/dashboard', component: () => import('../views/Dashboard.vue') }
]

export const router = createRouter({
  history: createWebHistory(),
  routes
})

// Guard toàn cục
router.beforeEach((to, from, next) => {
  const isAuth = false // giả sử chưa login
  if (to.path === '/dashboard' && !isAuth) {
    next('/login')
  } else {
    next()
  }
})

6. Lazy Loading (Code Splitting)

Thay vì import trực tiếp, có thể import động để giảm dung lượng ban đầu.

const routes = [
  { path: '/', component: () => import('../views/Home.vue') },
  { path: '/about', component: () => import('../views/About.vue') }
]

👉 Khi user truy cập /about, Vue mới load file About.vue.

7. Điều hướng bằng JS

Ngoài <router-link>, có thể dùng router.push().

Home.vue

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

const router = useRouter()

function goAbout() {
  router.push('/about')
}
</script>

<template>
  <button @click="goAbout">Đi đến About</button>
</template>

🎯 Kết luận

Trong bài này, bạn đã học:

  • Cài đặt Vue Router 4

  • Router cơ bản với router-linkrouter-view

  • Dynamic route (/user/:id)

  • Nested routes (route lồng nhau)

  • Navigation Guards (bảo vệ route)

  • Lazy loading routes

  • Điều hướng bằng router.push()

👉 Đây là nền tảng quan trọng để làm ứng dụng nhiều trang. Tiếp theo, chúng ta sẽ học Bài 5 – State Management với Pinia (Vuex thay thế).