Watchers cho phép bạn theo dõi sự thay đổi của các biến ref, reactive, hoặc bất kỳ biểu thức tính toán nào – từ đó thực hiện các hành động như gọi API, cập nhật UI, hoặc đồng bộ dữ liệu.
Watchers là gì?
Watchers trong Vue.js là một phương pháp để theo dõi và phản ứng với sự thay đổi của giá trị reactive. Bạn có thể coi nó như một “tai nghe” dữ liệu: khi giá trị được “nghe” thay đổi, callback sẽ được gọi.
Vue 3 cung cấp hai dạng watchers chính:
watch: Dùng để theo dõi một hoặc nhiều source cụ thể, chẳng hạn như một biếnref, một property trongreactive, hoặc một getter trả về giá trị cần theo dõi.watchEffect: Tự động theo dõi tất cả các biến được sử dụng trong một hàm callback. Khi bất kỳ biến nào trong hàm thay đổi, toàn bộ callback sẽ được chạy lại. Đây là dạng watcher đơn giản nhưng cũng mạnh mẽ.
Cú pháp và cách sử dụng watch
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newVal, oldVal) => {
console.log(`Count thay đổi từ ${oldVal} → ${newVal}`);
});
Các tham số chính:
watch(source, callback, options?)
- source: Biến
ref, objectreactive, getter hoặc array chứa nhiều source. - callback: Hàm chạy khi source thay đổi. Có dạng
(newValue, oldValue) => { ... } - options (tùy chọn): Thêm cấu hình như
deep,immediate.
Các loại source trong watch
Vue hỗ trợ nhiều kiểu source cho watcher, tùy vào mục đích của bạn:
Ref
const name = ref('Vue');
watch(name, (newVal) => {
console.log('Tên mới:', newVal);
});
Getter function
const user = reactive({ first: 'Vue', last: 'JS' });
watch(() => user.first, (newFirst) => {
console.log('First name:', newFirst);
});
Mảng nhiều source
watch([count, () => user.first], ([newCount, newFirst]) => {
console.log('Count:', newCount, '| First:', newFirst);
});
Mảng rất hữu ích khi bạn muốn theo dõi nhiều biến một lúc mà không cần viết nhiều watch.
deep và immediate trong watch
deep: Theo dõi sâu cho object/phức hợp
Mặc định, watch không phát hiện thay đổi sâu bên trong object. Dùng deep: true nếu bạn muốn theo dõi cả thay đổi lồng nhau.
const profile = reactive({
name: 'Vue',
address: {
city: 'Quy Nhơn'
}
});
watch(profile, () => {
console.log('Profile thay đổi');
}, { deep: true });
Nếu không có deep: true, thay đổi profile.address.city sẽ không kích hoạt watcher.
immediate: Gọi ngay lần đầu
Khi immediate: true, callback sẽ được gọi ngay lập tức khi watcher được đăng ký, thay vì chờ đến khi giá trị thay đổi.
watch(count, (newVal) => {
console.log('Count mới (ngay lập tức):', newVal);
}, { immediate: true });
Điều này hữu ích khi bạn muốn khởi tạo dữ liệu từ đầu (ví dụ: gọi API với giá trị ban đầu).
watchEffect trong Vue 3
watchEffect là gì?
watchEffect tự động chạy một hàm và theo dõi tất cả các biến reactive được sử dụng trong hàm đó. Khi bất kỳ biến nào thay đổi, hàm sẽ được chạy lại.
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`Giá trị mới: ${count.value}`);
});
Ưu điểm:
- Không cần chỉ rõ source.
- Gọn gàng, ngắn hơn
watch.
Lưu ý:
watchEffectcó thể chạy nhiều lần hơn bạn nghĩ, đặc biệt nếu bạn sử dụng nhiều biến hoặc dependency phức tạp.- Không dùng khi bạn cần so sánh
newVal,oldVal– vìwatchEffectkhông cung cấp chúng.
Khi nào dùng watch vs watchEffect?
| Tình huống | Dùng watch | Dùng watchEffect |
|---|---|---|
Cần truy cập oldValue | Có thể | Không hỗ trợ |
| Theo dõi nhiều biến cụ thể | Có thể | Phải truy cập trong hàm |
| Code đơn giản, nhanh gọn | Dài dòng hơn | Ngắn gọn |
| Xử lý side effects như API | Chính xác | Nhanh (nhưng cần cẩn trọng) |
Tổng kết
Watchers trong Vue.js là công cụ mạnh mẽ giúp bạn:
- Theo dõi giá trị thay đổi và phản hồi kịp thời.
- Đồng bộ dữ liệu giữa component hoặc với server.
- Tối ưu UI dựa trên trạng thái reactive.
Ghi nhớ:
- Dùng
watchkhi cần chi tiết, rõ ràng, có thể lấyoldValue. - Dùng
watchEffectkhi bạn muốn code ngắn, tự động, đơn giản hóa logic. - Kết hợp
deep,immediateđể kiểm soát behavior phù hợp với nhu cầu.
