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 ý:
watchEffect
có 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ìwatchEffect
khô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
watch
khi cần chi tiết, rõ ràng, có thể lấyoldValue
. - Dùng
watchEffect
khi 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.