CodeReady
Quay lại kiến thức

Ban biên tập CodeReady

Chuyên Sâu Vue.js Cho Lập Trình Viên Frontend: Kiến Trúc, Quản Lý Trạng Thái Và Tối Ưu Hiệu Năng

Phân tích toàn diện về Vue.js từ hệ thống phản ứng (Reactivity System), Composition API, chiến lược quản lý trạng thái đến các kỹ thuật tối ưu hóa hiệu năng thực chiến cho ứng dụng Frontend quy mô lớn.

Vue.js đã trở thành một trong những framework JavaScript hàng đầu nhờ tính linh hoạt, hệ sinh thái mạnh mẽ và đường cong học tập thân thiện. Tuy nhiên, để vượt qua mức độ sử dụng cơ bản và đáp ứng các tiêu chuẩn phỏng vấn kỹ thuật cao cấp cho vị trí Frontend, lập trình viên cần nắm vững bản chất cốt lõi của kiến trúc bên trong, cách thức hoạt động của hệ thống phản ứng và các best practice khi xây dựng ứng dụng lớn.

1. Hệ Thống Phản Ứng (Reactivity System) Bản Chất Hoạt Động

Khác biệt lớn nhất của Vue 3 so với Vue 2 nằm ở việc chuyển đổi từ cơ chế Object.defineProperty sang Proxy của JavaScript hiện đại. Điều này khắc phục triệt để các hạn chế cũ như không thể phát hiện thêm thuộc tính mới hoặc xóa phần tử mảng.

Proxy và Reflect

Khi bạn khởi tạo một reactive object, Vue sẽ bọc nó trong một Proxy. Proxy cho phép framework chặn (intercept) các thao tác đọc (get) và ghi (set) trên object đó.

const state = reactive({ count: 0 });

// Khi đọc state.count, hàm get() sẽ ghi nhận dependency (track)
console.log(state.count);

// Khi gán state.count = 1, hàm set() sẽ kích hoạt lại các hiệu ứng phụ (trigger)
state.count = 1;

Việc hiểu rõ cơ chế track và trigger giúp bạn tránh được các lỗi mất tính phản ứng (loss of reactivity) khi destructuring dữ liệu từ reactive object.

2. Composition API và Thiết Kế Logic Tái Sử Dụng

Composition API không chỉ là một cách viết code thay thế cho Options API, mà là một mô hình thiết kế giúp gom nhóm logic liên quan lại với nhau thay vì phân tán theo các option (data, methods, computed).

Xây Dựng Custom Hook / Composable

Khi tách logic thành các composable, quy tắc vàng là luôn sử dụng toRef hoặc toRefs nếu bạn cần destructuring các reactive object mà không làm mất tính phản ứng.

import { ref, onMounted, onUnmounted } from 'vue';

export function useWindowSize() {
  const width = ref(window.innerWidth);
  const height = ref(window.innerHeight);

  const update = () => {
    width.value = window.innerWidth;
    height.value = window.innerHeight;
  };

  onMounted(() => window.addEventListener('resize', update));
  onUnmounted(() => window.removeEventListener('resize', update));

  return { width, height };
}

3. Quản Lý Trạng Thái: Pinia vs Vuex

Trong Vue 3, Pinia đã chính thức thay thế Vuex làm thư viện quản lý trạng thái mặc định. Pinia mang lại trải nghiệm tuyệt vời với:

  • Hỗ trợ TypeScript tự nhiên mà không cần định nghĩa kiểu phức tạp.
  • Loại bỏ hoàn toàn các khái niệm mutations cồng kềnh, chỉ còn state, getters và actions.
  • Mô hình module dạng phẳng (flat stores) giúp code dễ chia nhỏ và bảo trì.

4. Các Lỗi Thường Gặp Khi Làm Việc Với Vue.js

Trong quá trình phỏng vấn và thực chiến, các lỗi sau thường xuyên xuất hiện và dễ bị trừ điểm:

  • Mất tính phản ứng khi destructuring: Sử dụng const { foo } = reactive({ foo: 'bar' }) sẽ làm biến mất kết nối phản ứng. Hãy dùng toRefs.
  • Quên cleanup side effects: Không hủy các event listener hoặc interval trong onUnmounted dẫn đến rò rỉ bộ nhớ (memory leak).
  • Lạm dụng computed properties: Viết các logic xử lý bất đồng bộ hoặc gây side effect bên trong computed thay vì dùng watch hoặc methods.

5. Checklist Tối Ưu Hiệu Năng Frontend Vue.js

Để đảm bảo ứng dụng đạt điểm số cao về Performance trên Lighthouse, hãy áp dụng checklist sau:

  1. Sử dụng Async Components và defineAsyncComponent để chia nhỏ bundle (Code Splitting).
  2. Tận dụng v-memo cho các danh sách lớn (large lists) ít thay đổi để bỏ qua quá trình diff VDOM không cần thiết.
  3. Tránh gán reactive cho các dữ liệu lớn đọc tĩnh (không đổi) bằng cách sử dụng markRaw hoặc shallowRef.
  4. Tối ưu hóa các câu lệnh v-for đi kèm với v-if (tránh dùng chung trên một thẻ vì v-for có độ ưu tiên cao hơn trong Vue 3, gây lãng phí tài nguyên).

6. FAQ Phỏng Vấn Vue.js Thường Gặp

Q: Sự khác biệt cốt lõi giữa ref() và reactive() là gì?
A: ref() có thể chứa bất kỳ kiểu dữ liệu nào (nguyên thủy hoặc object) và truy cập qua thuộc tính .value. reactive() chỉ nhận vào object/array, giữ nguyên giá trị không cần .value nhưng không thể gán lại toàn bộ object mới mà không làm mất tính phản ứng.

Ôn tiếp theo chủ đề này

Chuyển sang câu hỏi hoặc case study để luyện cách trả lời.

Xem câu hỏi