Реактивність Vue працює через проксі: Vue знає про зміну, бо зміна йде через проксі (state.count = 1). Деструктуризація копіює значення полів у звичайні змінні - зв'язок із проксі втрачається.
const state = reactive({ count: 0, name: 'Оля' });
const { count } = state; // просто число 0
state.count++; // count лишився 0
Як уникнути:
toRefsперетворює кожне поле наref, пов'язаний з початковим об'єктом:
const { count, name } = toRefs(state);
count.value++; // змінює state.count
toRef- для одного поля:const count = toRef(state, 'count').- Повертати з composables
ref-и, а неreactive, - тоді деструктуризація на місці виклику безпечна.
Props: props - теж реактивний об'єкт. До Vue 3.5 const { title } = defineProps(...) давав нереактивну змінну. З Vue 3.5 деструктуризація defineProps у <script setup> реактивна: компілятор сам перетворює title на props.title. Але передати таку змінну у функцію чи watch напряму не вийде - потрібен геттер: watch(() => title, ...).
Ще місця, де реактивність губиться:
- Заміна всього
reactive-об'єкта:state = reactive({...}). - Передача примітиву в функцію:
useSomething(state.count)передає число, а не реактивне джерело. ПередавайтеtoRef(state, 'count')чи геттер() => state.count.