watch и watchEffect

↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Когда watch, когда watchEffect, что такое flush и очистка эффектов.

Объяснение

// watch: явные источники, ленивый по умолчанию, даёт старое и новое значение
watch(userId, async (id, oldId, onCleanup) => {
  const ctrl = new AbortController();
  onCleanup(() => ctrl.abort());                       // отмена предыдущего запроса
  user.value = await api.user(id, { signal: ctrl.signal });
}, { immediate: true });
 
watch([a, b], ([na, nb], [oa, ob]) => {});             // несколько источников
watch(() => state.filter.query, search, { deep: false });   // геттер
watch(state, cb, { deep: true });                       // глубокое наблюдение (дорого)
 
// watchEffect: зависимости отслеживаются автоматически, запускается сразу
watchEffect(() => { document.title = `${count.value} — ${title.value}`; });
watchEffect((onCleanup) => { const t = setInterval(tick, 1000); onCleanup(() => clearInterval(t)); });
watchwatchEffect
Источникиявныеавтоматические (всё прочитанное синхронно)
Старое значениеданет
Первый запускнет (immediate: true)да
Когданужен контроль, реакция на конкретное изменениемного зависимостей, эффект «синхронизации»

Опции: immediate, deep, once, flush: "pre" | "post" | "sync" (post — после обновления DOM; watchPostEffect, watchSyncEffect), onWatcherCleanup (3.5).

Остановка: watcher внутри setup останавливается автоматически при размонтировании; созданный асинхронно — вручную (const stop = watch(...), stop()).

Практики: избегайте watch там, где достаточно computed; для загрузки данных при смене параметров лучше Vue Query (кэш, отмена, состояния).

Нюансы и подводные камни

  • watch(state.field, ...) — источник примитив, не реактивный: используйте геттер () => state.field.
  • В watchEffect асинхронные зависимости после await не отслеживаются.
  • deep: true на больших объектах — дорого.
  • Изменение отслеживаемого состояния внутри самого watcher вызывает циклы.
  • Гонки запросов: применяйте отмену (onCleanup).

Практика

  1. Реализуйте поиск при изменении запроса с отменой предыдущего запроса.
  2. Синхронизируйте document.title через watchEffect.
  3. Замените watch на computed там, где это возможно.

Вопросы с ответами

Связанные темы