PassFront
  1. PassFront
  2. База знаний
  3. Реактивность

Следит ли watch во Vue за вложенными свойствами объекта?

Реактивность

Зависит от того, что именно отслеживается. В Vue 3 watch по реактивному объекту (reactive) глубокий по умолчанию, а по `ref` с объектом или геттеру — поверхностный, пока не включён deep.

reactive-объект — глубоко по умолчанию

const state = reactive({ user: { name: 'Anna' } });

watch(state, () => console.log('changed')); // срабатывает и на state.user.name
state.user.name = 'Ivan';                   // коллбэк вызван

При передаче реактивного объекта Vue неявно включает deep.

ref и геттер — поверхностно

const user = ref({ name: 'Anna' });

watch(user, () => console.log('changed'));
user.value.name = 'Ivan';   // НЕ сработает: ссылка осталась той же
user.value = { name: 'Ivan' }; // сработает: значение заменено

Чтобы отслеживать вложенные изменения, указывают deep: true:

watch(user, cb, { deep: true });

Отслеживание конкретного поля

Эффективнее следить за одним свойством через геттер, а не за всем объектом:

watch(() => state.user.name, (name) => { /* ... */ });

Цена глубокого слежения

deep обходит все свойства при каждом изменении, что дорого для больших структур. В Vue 3.5 можно указать числовую глубину: deep: 2.

В Vue 2

Глубокое слежение нужно было включать явно через deep: true для любого объекта.

watchEffect

watchEffect автоматически отслеживает только те реактивные значения, которые прочитаны в его теле.

Коротко для собеседования

watch по reactive-объекту следит за вложенными полями сам, а для ref и геттеров вложенные изменения не видит без deep: true. Для точности и скорости лучше наблюдать конкретное поле через геттер.

Другие вопросы раздела