Skip to main content

Що робить watch()?

1. Що робить watch()

watch() стежить за змінами реактивних значень (створених через ref, reactive, computed тощо) і виконує вказану функцію лише тоді, коли ці значення дійсно змінюються.

Синтаксис:

javascript
watch(source, callback, options?)
  • source - за чим стежимо (ref, reactive, функція або масив).
  • callback(newValue, oldValue) - викликається при зміні.
  • options - додаткові налаштування (immediate, deep, flush та ін).

2. Найпростіший приклад

javascript
import { ref, watch } from 'vue' const count = ref(0) watch(count, (newVal, oldVal) => { console.log(`count змінився: ${oldVal}${newVal}`) }) count.value++ // викликає callback

Тут watch() "підписується" на зміну count.value. Коли значення змінюється - викликається callback.


3. Як це працює всередині

Під капотом watch() створює ефект (effect), як і computed, але з поведінкою "лише при зміні".

  1. Vue запам'ятовує, які реактивні дані використовувалися у функції-джерелі (source).
  2. При зміні цих даних Vue викликає callback.
  3. Vue порівнює старе і нове значення (shallow-порівняння).
  4. Якщо значення змінилося - виконується твоя логіка.

4. Приклад з об'єктом reactive

javascript
import { reactive, watch } from 'vue' const user = reactive({ name: 'Tim', age: 25 }) // Стежимо за всім об'єктом watch(user, (newUser, oldUser) => { console.log('user змінився:', newUser) })

Але важливо:

При відстеженні об'єкта reactive зміни всередині об'єкта не спрацюють за замовчуванням, якщо не вказати { deep: true }.

Правильно:

javascript
watch(user, (newVal, oldVal) => { console.log('user змінився глибоко:', newVal) }, { deep: true })

5. Стежити за конкретною властивістю

Замість цілого об'єкта можна передати функцію - "селектор".

javascript
watch( () => user.name, // відстежуємо лише name (newName, oldName) => { console.log(`Ім'я змінилося: ${oldName}${newName}`) } )

Це кращий спосіб - він продуктивний і точковий.


6. Опції watch()

ОпціяОписПриклад
immediate: trueВиконати callback одразу під час ініціалізації (з поточним значенням)watch(count, cb, { immediate: true })
deep: trueСтежити за всіма вкладеними змінами об'єкта/масивуwatch(user, cb, { deep: true })
flushВизначає коли виконується watcher відносно рендера.watch(value, cb, { flush: 'post' })
onCleanup(fn)Дозволяє задати очищення побічного ефекту перед наступним викликомдив. нижче

7. Очищення побічних ефектів

Часто в watch() потрібно очищати таймери, підписки тощо.

Vue передає в callback функцію onCleanup, щоб очистити попередній ефект:

javascript
watch(searchQuery, (newQuery, oldQuery, onCleanup) => { const controller = new AbortController() fetch(`/api?q=${newQuery}`, { signal: controller.signal }) // скасовуємо попередній запит, якщо значення знову змінилося onCleanup(() => controller.abort()) })

8. Спостереження за кількома джерелами

Можна стежити одразу за кількома значеннями, передавши масив:

javascript
const first = ref('Tim') const last = ref('Cook') watch([first, last], ([newFirst, newLast], [oldFirst, oldLast]) => { console.log(`Ім'я: ${oldFirst} ${oldLast}${newFirst} ${newLast}`) })

Vue відстежує всі залежності, і callback викликається, якщо змінилося хоча б одне з них.


9. Різниця між watch() та watchEffect()

Критерійwatch()watchEffect()
Що відстежуєКонкретні реактивні значення або функціїВсе, що використовується всередині ефекту
Коли викликаєтьсяЛише при зміні значеньОдразу під час запуску і при кожній зміні
Є oldValueТакНі
Тонкий контрольТак (можна вказати deep, immediate)Ні, все автоматично
Типовий випадокРеагувати на зміну стануВиконувати побічні ефекти при будь-якій зміні

Приклад:

javascript
// watch() watch(count, (newVal, oldVal) => console.log(newVal)) // watchEffect() watchEffect(() => { console.log(count.value) })

10. Приклад з практики

Наприклад, ти хочеш реагувати на зміну пошукового рядка, але не при кожному рендері:

javascript
const query = ref('') watch(query, async (newQuery) => { results.value = await fetch(`/api?q=${newQuery}`).then(r => r.json()) }, { immediate: true })

Тут immediate: true дає перший запит під час монтування компонента, а потім watch() спрацьовує лише при зміні query.


11. Коротко і просто

watch() - це "реактивний слухач": він відстежує конкретні дані і викликає функцію при їхній зміні.

Ти використовуєш його, коли потрібно виконати дію, а не просто оновити інтерфейс.


Приклад для запам'ятовування

Що робишЩо використовувати
Хочу, щоб інтерфейс сам оновився при зміні данихreactive() / ref() / computed()
Хочу виконати побічний ефект при зміні даних (наприклад, API-запит, лог, таймер, локалстор)watch()

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.