Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Наблюдатели: watch и watchEffect

Наблюдатель — функция, которую Vue вызывает, когда меняются определённые данные. computed возвращает новое значение, а наблюдатель выполняет действие: сохраняет данные, отправляет запрос, пишет в консоль. Такие действия называют побочными эффектами.

Функция watch

Первый аргумент — что отслеживать, второй — что сделать при изменении:

<!-- src/App.vue -->
<script setup>
import { ref, watch } from 'vue'
 
const query = ref('')
 
watch(query, (newValue, oldValue) => {
  console.log(`Поиск: было «${oldValue}», стало «${newValue}»`)
})
</script>
 
<template>
  <input v-model="query" placeholder="Найти задачу">
</template>

Наберите в поле «хл» — в консоли браузера появятся две строки: сначала Поиск: было «», стало «х», затем Поиск: было «х», стало «хл». Директива v-model связывает поле с переменной, подробно она разобрана в уроке про формы.

Сохранение задач

Типичная задача для watch — сохранить список в localStorage после каждого изменения:

<script setup>
import { ref, watch } from 'vue'
 
const saved = localStorage.getItem('todos')
const todos = ref(saved ? JSON.parse(saved) : [])
 
watch(todos, (value) => {
  localStorage.setItem('todos', JSON.stringify(value))
}, { deep: true })
</script>

После перезагрузки страницы задачи остаются на месте. Опция deep: true нужна, чтобы наблюдатель срабатывал и при изменении полей внутри задач, например done, а не только при замене всего массива.

Опции

ОпцияЧто делает
deep: trueСледит за изменениями вложенных полей
immediate: trueВызывает функцию сразу при создании, а не только при изменении
once: trueСрабатывает только один раз

Отслеживание части объекта

Чтобы следить за одним полем, передайте функцию-геттер, которая его возвращает:

<script setup>
import { ref, watch } from 'vue'
 
const filter = ref({ query: '', onlyActive: false })
 
watch(() => filter.value.onlyActive, (value) => {
  console.log('Только активные:', value)
})
</script>

Наблюдатель сработает при переключении onlyActive, а изменения query проигнорирует.

Функция watchEffect

watchEffect сам определяет зависимости: он выполняет функцию сразу и запоминает, какие реактивные данные она прочитала.

<script setup>
import { ref, watchEffect } from 'vue'
 
const todos = ref([])
 
watchEffect(() => {
  document.title = `Задач: ${todos.value.length}`
})
</script>

Заголовок вкладки браузера сразу станет «Задач: 0» и будет меняться при каждом добавлении или удалении задачи.

watchwatchEffect
ИсточникУказывается явноОпределяется сам
Первый запускПри измененииСразу
Старое значениеЕстьНет

Частая ошибка

Передать в watch значение вместо источника:

<script setup>
watch(filter.value.query, (value) => { /* ... */ })
</script>

filter.value.query — это просто строка на момент вызова, Vue выведет предупреждение и не будет следить за ней. Передавайте сам ref или функцию: watch(() => filter.value.query, ...).

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.