0Pricing
Frontend Academy · Урок

computed() и watch()

Лениво получайте производные значения с computed(), реагируйте на изменения состояния через watch() и watchEffect() и управляйте моментом сброса.

«computed() и watch()» — бесплатный урок Frontend Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

computed() в Composition API

computed(fn) создаёт доступный только для чтения реактивный ref, который получает значение из других реактивных источников. Он кэшируется: функция получения значения выполняется только при изменении зависимостей.

<script setup>
import { ref, computed } from 'vue';

const items = ref([{ price: 10 }, { price: 20 }, { price: 30 }]);
const tax = ref(0.1);

const subtotal = computed(() => items.value.reduce((s, i) => s + i.price, 0));
const total = computed(() => subtotal.value * (1 + tax.value));
</script>

Доступный для записи computed()

Передайте объект с get и set, чтобы создать доступное для записи вычисляемое свойство. Сеттер обрабатывает обновления и обычно отражает изменение в исходном ref.

const firstName = ref('Alice');
const lastName  = ref('Smith');

const fullName = computed({
  get: () => `${firstName.value} ${lastName.value}`,
  set: (val: string) => {
    [firstName.value, lastName.value] = val.split(' ');
  }
});

fullName.value = 'Bob Jones'; // sets both refs

Основы watch()

watch(source, callback) вызывает функцию обратного вызова при изменении источника. Функция обратного вызова получает новое и старое значения.

import { ref, watch } from 'vue';

const query = ref('');

watch(query, (newVal, oldVal) => {
  console.log(`Changed from '${oldVal}' to '${newVal}'`);
  searchAPI(newVal);
});

Наблюдение за ref и reactive

Наблюдайте за ref напрямую. Чтобы наблюдать за свойством реактивного объекта, используйте функцию-геттер () => state.prop.

const count = ref(0);
watch(count, val => console.log('count:', val));

const state = reactive({ count: 0, name: '' });
watch(() => state.count, val => console.log('state.count:', val));

Глубокое наблюдение

Передайте { deep: true }, чтобы отслеживать вложенные изменения в ref, содержащем объект.

const user = ref({ name: 'Alice', address: { city: 'NY' } });

watch(user, (newUser) => {
  console.log('user changed:', newUser);
}, { deep: true });

Немедленное наблюдение

Передайте { immediate: true }, чтобы функция обратного вызова выполнилась сразу при настройке, ещё до первого изменения. Это полезно, когда побочный эффект нужно выполнить с исходным значением.

watch(userId, async (id) => {
  user.value = await fetchUser(id);
}, { immediate: true }); // runs once on setup, then on change

watchEffect()

watchEffect(fn) сразу выполняет функцию обратного вызова и повторно запускает её при изменении любой реактивной зависимости, использованной внутри. Явно указывать источники не нужно.

import { watchEffect } from 'vue';

watchEffect(() => {
  // runs immediately and whenever query or page changes:
  fetchResults(query.value, page.value);
});

watchEffect и watch

watchEffect: выполняется сразу, автоматически отслеживает зависимости и не предоставляет доступ к старому значению. watch: использует явно заданные источники, по умолчанию запускается отложенно и предоставляет доступ к старому и новому значениям. Используйте watchEffect для декларативных побочных эффектов, а watch — когда нужно контролировать время и частоту выполнения.

Остановка наблюдателей

И watch, и watchEffect возвращают функцию stop. Вызовите её, чтобы прекратить наблюдение. В