Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому реактивність губиться при деструктуризації і як цього уникнути?

Реактивність 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.

Докладніше в документації: Обмеження reactive()

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання