Зміст
Коротко
Vue 3 з Proxy, Composition API і підтримкою TypeScript виглядає простішим за Vue 2, але на практиці «вміти користуватися» і «користуватися правильно» — різні рівні. На Dev.to зібрали типові пастки реактивності, вибір між ref і reactive, спостерігачі та нові компоненти на кшталт Teleport і Suspense.
Що сталося
Реактивність переписали з Object.defineProperty на Proxy: зникли класичні болі Vue 2 — нові поля об'єкта та індекси масиву без реакції. Натомість з'явився новий ментальний податок: де обривається зв'язок із оновленням DOM, якщо ви деструктурували об'єкт або підмінили посилання цілком.
Просте правило: ref — для примітивів і об'єктів, які можуть повністю замінитися; reactive — для вкладених структур на кшталт форм. Пастка: reactive повертає проксі — при let { count } = state ви отримуєте звичайне число, і інкремент не тригерить перемальовку. Вихід — toRefs.
Окрема проблема — авторозпакування ref. У шаблоні .value не потрібен, але ref у звичайному масиві не розпаковується, а в reactive-масиві — так. Помилка «замінив увесь об'єкт reactive-змінної» лікується або переходом на ref з data.value = …, або Object.assign.
У Composition API порівнюють watch і watchEffect: другий одразу виконується і сам збирає залежності — зручно для логів, але небезпечно, якщо всередині міняти ті самі ref (ризик нескінченного циклу). Для контрольованих реакцій з «старим/новим» — watch.
Чому це важливо
Vue 3 часто обирають як «легший за React», але половина багів у проді — у розриві реактивного ланцюга: composable повернув .value замість ref, lifecycle-хук зареєстрували в setTimeout, scoped-стилі не доходять до Teleport. Лінтер це рідко ловить; SSR проявляє пізно.
Потрібен явний контракт composable — назовні лише ref/reactive — і code review на деструктуризацію state. TypeScript допомагає, якщо props оголошувати через defineProps<{…}>() і withDefaults.
На практиці
- Деструктуруєте
reactive— обгорніть уtoRefs. - Дані можуть повністю замінитися — беріть
ref, неreactive. - У
watchEffectне мутуйте залежності без guard; для old/new —watch. - Composable
useXxxповертає ref, не голі значення. - Хуки
onMountedвикликайте синхронно в setup. - Teleport переносить DOM, але контекст лишається у батька — для стилів потрібен
:deep(). - Suspense обережно в SSR і критичних маршрутах.
Підсумок
Vue 3 складніший не за синтаксисом, а за моделлю реактивності. Стаття на Dev.to — чеклист перед рефакторингом на Composition API. Деталі та приклади коду — в оригіналі.