Navigation Guards và Lazy Loading Components trong Vue Router

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

Trong bài học này, bạn sẽ học về:

  • Navigation Guards – Kiểm soát điều hướng với beforeEach, afterEach.
  • Lazy Loading Components – Tải component theo yêu cầu để tối ưu hiệu suất.
  • Thực hành: Tích hợp Lazy Loading vào Vue Router và kiểm soát quyền truy cập bằng Navigation Guards.

Navigation Guards và Lazy Loading Components

1 Navigation Guards – Kiểm soát điều hướng trong Vue Router

Vue Router cung cấp Navigation Guards giúp kiểm soát quyền truy cập khi người dùng điều hướng giữa các trang.

Các loại Navigation Guards chính:

Navigation Guard Mô tả
beforeEach Chạy trước khi điều hướng đến bất kỳ route nào
beforeResolve Chạy ngay trước khi route được render
afterEach Chạy sau khi đã điều hướng thành công

Ví dụ: Kiểm tra quyền truy cập với beforeEach

Chúng ta sẽ yêu cầu người dùng phải đăng nhập mới có thể truy cập trang /dashboard.

Cấu hình Navigation Guards trong router.js

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

const isAuthenticated = false // Giả định người dùng chưa đăng nhập

const routes = [
  { path: '/', component: Home },
  { path: '/login', component: Login },
  {
    path: '/dashboard',
    component: Dashboard,
    meta: { requiresAuth: true }
  }
]

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

// Navigation Guard kiểm tra quyền truy cập
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login') // Chuyển hướng về trang đăng nhập nếu chưa đăng nhập
  } else {
    next() // Tiếp tục điều hướng nếu đã đăng nhập
  }
})

export default router

Giải thích:

  • Nếu trang có meta.requiresAuthngười dùng chưa đăng nhập → Chuyển hướng về /login.
  • Nếu không, cho phép điều hướng bình thường.

Sử dụng afterEach để ghi log sau khi điều hướng

router.afterEach((to, from) => {
  console.log(`Chuyển từ ${from.path} đến ${to.path}`)
})

Ứng dụng thực tế:

  • Ghi log analytics (Google Analytics, Mixpanel).
  • Theo dõi hành trình người dùng trong ứng dụng.

2 Lazy Loading Components – Tải Component theo yêu cầu

Khi ứng dụng lớn dần, tải tất cả component ngay từ đầu sẽ làm chậm hiệu suất. Lazy Loading giúp tải component chỉ khi cần thiết, giảm thời gian tải trang ban đầu.

Cách sử dụng Lazy Loading trong Vue Router

Thay vì import component trực tiếp:

import Dashboard from '../views/Dashboard.vue'

Bạn có thể Lazy Load bằng cách dùng defineAsyncComponent hoặc import():

const Dashboard = () => import('../views/Dashboard.vue')

Cập nhật router.js với Lazy Loading

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

Lợi ích:

  • Giảm kích thước file JavaScript ban đầu.
  • Tăng tốc độ tải trang với chiến lược “chỉ tải khi cần thiết”.

Lazy Loading kết hợp với Dynamic Imports Vue hỗ trợ Lazy Loading component nội bộ bằng defineAsyncComponent().

import { defineAsyncComponent } from 'vue'

export default {
  components: {
    AsyncComponent: defineAsyncComponent(() => import('./MyComponent.vue'))
  }
}

Ứng dụng thực tế:

  • Tải component nặng khi cần thiết (ví dụ: đồ thị, biểu đồ).
  • Cải thiện trải nghiệm người dùng trên ứng dụng lớn.

Thực hành: Kết hợp Navigation Guards & Lazy Loading

Yêu cầu:

  • Người dùng phải đăng nhập mới vào được /dashboard.
  • Nếu chưa đăng nhập → Chuyển hướng về /login.
  • Sử dụng Lazy Loading để tải trang /dashboard.

Bước 1: Cập nhật router.js

const isAuthenticated = false // Giả định người dùng chưa đăng nhập

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

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

// Navigation Guard kiểm tra đăng nhập
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login')
  } else {
    next()
  }
})

export default router

Bước 2: Tạo Dashboard.vue

<template>
  <div>
    <h1>Trang Dashboard</h1>
    <p>Chào mừng đến với trang quản lý!</p>
    <router-link to="/">Quay lại trang chủ</router-link>
  </div>
</template>

Bước 3: Chạy thử nghiệm

  1. Truy cập /dashboard khi chưa đăng nhập → Tự động chuyển về /login.
  2. Sau khi đăng nhập (giả lập isAuthenticated = true), truy cập /dashboard thành công.
  3. Quan sát việc Lazy Load Dashboard.vue (kiểm tra trong tab “Network” của DevTools).

Kết luận

  • Navigation Guards giúp kiểm soát quyền truy cập bằng beforeEach, afterEach.
  • Lazy Loading giúp tối ưu hiệu suất bằng cách tải component theo yêu cầu.
  • Thực hành: Xây dựng trang /dashboard với Navigation Guards và Lazy Loading.
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ệ