# Vue 3 Composition API: Hướng Dẫn Đầy Đủ Để Làm Chủ Reactivity > Làm chủ Vue 3 Composition API qua hướng dẫn thực hành này. Tìm hiểu ref, reactive, computed, watch và composables để xây dựng ứng dụng Vue hiệu suất cao. - Published: 2026-01-07 - Updated: 2026-04-06 - Author: SharpSkill - Tags: vue 3, composition api, javascript, frontend, reactivity - Reading time: 12 min --- Vue 3 Composition API là một bước tiến lớn trong cách cấu trúc các component Vue. Cách tiếp cận này tổ chức mã nguồn theo tính năng thay vì theo tùy chọn, giúp việc tái sử dụng logic và bảo trì các ứng dụng phức tạp trở nên dễ dàng hơn. > **Điều kiện tiên quyết** > > Hướng dẫn này giả định bạn đã có kiến thức cơ bản về Vue.js. Các ví dụ sử dụng cú pháp ` ``` Đối với các đối tượng có nhiều thuộc tính liên quan, `reactive` cung cấp cú pháp tự nhiên hơn mà không cần `.value`. ```javascript // UserProfile.vue ``` Quy tắc chung: sử dụng `ref` cho các giá trị nguyên thủy (string, number, boolean) và `reactive` cho các đối tượng có cấu trúc. ## Thuộc tính Computed với computed Thuộc tính computed suy ra giá trị từ state reactive. Chúng được lưu vào cache và chỉ tính toán lại khi các dependency thay đổi, mang lại hiệu suất rất cao. ```javascript // ProductList.vue ``` Thuộc tính computed cũng có thể ghi được (writable) với getter và setter, hữu ích cho các phép biến đổi hai chiều. ```javascript // FullName.vue ``` ## Watcher với watch và watchEffect Watcher thực thi các tác dụng phụ để phản hồi lại các thay đổi dữ liệu. Vue 3 cung cấp hai cách tiếp cận: `watch` để kiểm soát chính xác và `watchEffect` để theo dõi tự động. > **Khi nào nên dùng watch và khi nào nên dùng watchEffect?** > > `watch` cung cấp khả năng kiểm soát chính xác các dependency và cung cấp cả giá trị cũ lẫn giá trị mới. `watchEffect` đơn giản hơn khi tất cả các dependency reactive được sử dụng đều cần kích hoạt hiệu ứng. ```javascript // SearchComponent.vue ``` Để theo dõi các đối tượng hoặc mảng lồng nhau, tùy chọn `deep` là cần thiết với `watch`. ```javascript // DeepWatch.vue ``` ## Tạo Composable tái sử dụng Composable là các hàm đóng gói logic reactive có thể tái sử dụng. Đây là một trong những điểm mạnh lớn nhất của Composition API để chia sẻ mã giữa các component. ```javascript // composables/useFetch.js import { ref, watchEffect, toValue } from 'vue' // Composable for HTTP requests // Automatically handles loading, errors, and refetching export function useFetch(url) { const data = ref(null) const error = ref(null) const isLoading = ref(false) // Reusable fetch function async function fetchData() { isLoading.value = true error.value = null try { // toValue() allows accepting a ref or a value const response = await fetch(toValue(url)) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } data.value = await response.json() } catch (e) { error.value = e.message } finally { isLoading.value = false } } // watchEffect for automatic refetch if url is a ref watchEffect(() => { fetchData() }) // Expose state and methods return { data, error, isLoading, refetch: fetchData } } ``` Composable này sau đó có thể được sử dụng theo cách khai báo trong bất kỳ component nào. ```javascript // UserList.vue ``` Dưới đây là một ví dụ composable khác để quản lý trạng thái form kèm theo validation. ```javascript // composables/useForm.js import { reactive, computed } from 'vue' // Form management composable export function useForm(initialValues, validationRules) { // Form state const form = reactive({ values: { ...initialValues }, errors: {}, touched: {} }) // Validate a specific field const validateField = (field) => { const rules = validationRules[field] if (!rules) return true for (const rule of rules) { const result = rule(form.values[field]) if (result !== true) { form.errors[field] = result return false } } form.errors[field] = null return true } // Validate entire form const validate = () => { let isValid = true for (const field in validationRules) { if (!validateField(field)) { isValid = false } } return isValid } // computed: form is valid if no errors const isValid = computed(() => { return Object.values(form.errors).every(e => !e) }) // Mark a field as touched (to display errors) const touch = (field) => { form.touched[field] = true validateField(field) } // Reset the form const reset = () => { form.values = { ...initialValues } form.errors = {} form.touched = {} } return { form, isValid, validate, validateField, touch, reset } } ``` ## Quản lý Lifecycle Hook Composition API cung cấp các lifecycle hook dưới dạng hàm được gọi bên trong setup. Các hook này thực thi mã tại những thời điểm cụ thể trong vòng đời của component. > **Dọn dẹp quan trọng** > > Luôn dọn dẹp các tác dụng phụ (timer, event listener, subscription) trong `onUnmounted` để tránh rò rỉ bộ nhớ. ```javascript // LifecycleDemo.vue ``` ## Template Ref và truy cập DOM Template ref cung cấp quyền truy cập trực tiếp đến các phần tử DOM hoặc instance của component con. Tính năng này vẫn hữu ích cho các trường hợp cần thao tác trực tiếp. ```javascript // InputFocus.vue ``` ## Giao tiếp Parent-Child với Props và Emits Composition API hiện đại hóa cách khai báo props và event với `defineProps` và `defineEmits`, mang lại khả năng tích hợp TypeScript tốt hơn. ```javascript // ChildComponent.vue ``` ```javascript // ParentComponent.vue ``` ## Provide và Inject cho Dependency Injection Để chia sẻ dữ liệu giữa các component ở xa nhau mà không cần prop drilling, Vue 3 cung cấp `provide` và `inject`. ```javascript // App.vue (or an ancestor component) ``` ```javascript // DeepNestedComponent.vue (anywhere in the tree) ``` ## Kết luận Vue 3 Composition API mang đến cách tiếp cận mạnh mẽ và linh hoạt để tổ chức mã ứng dụng Vue. Các khái niệm chính cần ghi nhớ: - **ref** cho giá trị nguyên thủy, **reactive** cho đối tượng phức tạp - **computed** cho giá trị suy diễn với caching tự động - **watch** và **watchEffect** cho các tác dụng phụ reactive - **Composable** để trích xuất và tái sử dụng logic giữa các component - **Lifecycle hook dạng hàm** (`onMounted`, `onUnmounted`, v.v.) - **provide/inject** cho dependency injection không cần prop drilling Cách tiếp cận này giúp việc tạo các ứng dụng dễ bảo trì và dễ kiểm thử trở nên thuận tiện, đồng thời cung cấp khả năng tích hợp TypeScript tuyệt vời. Bước tiếp theo là khám phá các pattern nâng cao như async composable và tích hợp với Pinia để quản lý state toàn cục. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/vi/blog/vue-nuxt/vue-3-composition-api-complete-guide