Nested Routes và Dynamic Routes

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 16 tháng 4, 2025

Trong Nuxt 3, hệ thống file-based routing không chỉ đơn giản với các route tĩnh, mà còn cực kỳ mạnh mẽ khi bạn muốn xây dựng các route động (dynamic routes) và route lồng nhau (nested routes). Những kỹ thuật này đặc biệt hữu ích trong các ứng dụng blog, e-commerce, dashboard… Bài học này sẽ giúp bạn nắm vững cách tạo nested route, dynamic route với tham số, sử dụng useRoute() để truy cập dữ liệu động, và xử lý các tình huống đặc biệt như catch-all route.

Nested Routes và Dynamic Routes

1. Nested Pages và Nested Layouts

Nested Pages: Bạn có thể tạo route lồng nhau bằng cách đặt .vue file trong thư mục con của pages/.

Ví dụ:

pages/
  user/
    index.vue      → /user
    profile.vue    → /user/profile

Nested Layouts: Bên cạnh nested pages, bạn cũng có thể sử dụng layout lồng nhau bằng cách dùng definePageMeta({ layout: '...' }) cho các trang con để áp dụng layout phù hợp.

2. Dynamic Route: [id].vue, [slug].vue

Bạn có thể tạo route động bằng cách đặt tên file với dấu ngoặc vuông:

  • pages/products/[id].vue → route /products/:id
  • pages/blog/[slug].vue → route /blog/:slug

Ví dụ:

<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute()
</script>

<template>
  <div>
    <h1>Chi tiết bài viết: {{ route.params.slug }}</h1>
  </div>
</template>

3. Route Params và useRoute()

Nuxt cung cấp composable useRoute() để bạn có thể truy cập các thông tin của route hiện tại, bao gồm tham số động.

Ví dụ:

const route = useRoute()
const slug = route.params.slug

Bạn có thể sử dụng slug này để gọi API, lấy dữ liệu tương ứng từ server hoặc file tĩnh.

4. Catch-all Route: [...all].vue

Để xử lý các route động có thể bao gồm nhiều phần, dùng catch-all route:

  • pages/[...all].vue → khớp với /a, /a/b, /a/b/c,...
<script setup>
const route = useRoute()
</script>

<template>
  <div>
    <h1>Bạn đang ở: /{{ route.params.all }}</h1>
  </div>
</template>

Đây là kỹ thuật tốt cho việc custom 404, hoặc tạo cấu trúc đường dẫn động nhiều cấp.

5. Thực hành: Tạo route blog chi tiết theo slug

Cấu trúc thư mục:

pages/
  blog/
    index.vue         → Danh sách bài viết
    [slug].vue        → Chi tiết bài viết theo slug

pages/blog/index.vue:

<template>
  <div>
    <h1>Blog</h1>
    <ul>
      <li><NuxtLink to="/blog/nuxt-3-tutorial">Nuxt 3 Tutorial</NuxtLink></li>
      <li><NuxtLink to="/blog/vue-eco-system">Vue Ecosystem</NuxtLink></li>
    </ul>
  </div>
</template>

pages/blog/[slug].vue:

<script setup>
const route = useRoute()
const slug = route.params.slug
</script>

<template>
  <div>
    <h1>Chi tiết bài viết</h1>
    <p>Đây là bài viết với slug: <strong>{{ slug }}</strong></p>
  </div>
</template>

Sau đó truy cập /blog/nuxt-3-tutorial để kiểm tra.

Kết luận

Trong bài học này, bạn đã nắm vững cách tạo route lồng nhau, route động bằng cách sử dụng [param].vueuseRoute() để truy cập dữ liệu. Bạn cũng đã học cách tạo catch-all route để xử lý đường dẫn linh hoạt. Đây là một trong những kỹ năng quan trọng để xây dựng các ứng dụng Nuxt quy mô lớn như blog, CMS hay admin dashboard với khả năng điều hướng động mạnh mẽ và rõ ràng.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ