Следит ли 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. Для точности и скорости лучше наблюдать конкретное поле через геттер.