Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить `reactive()` у Vue 3?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`reactive()`** приймає звичайний об'єкт і повертає його реактивну (проксійовану) версію. **Ключове:** Vue автоматично відстежує зміни властивостей цього об'єкта та оновлює всі ефекти, обчислення чи компоненти, які від них залежать.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `reactive()` Функція `reactive()` приймає **звичайний об'єкт** і повертає **його реактивну (проксійовану) версію**. ```javascript import { reactive } from 'vue' const state = reactive({ count: 0, user: { name: 'Tim' } }) ``` Тепер, коли ти зміниш будь-яку властивість об'єкта: ```javascript state.count++ state.user.name = 'Alex' ``` Vue автоматично відстежить ці зміни та оновить усі ефекти, обчислення чи компоненти, які від них залежать. --- ## 2. Як це працює під капотом Під капотом `reactive()` створює **Proxy-обгортку** над переданим об'єктом. Спрощено: ```javascript function reactive(target) { return new Proxy(target, { get(target, key, receiver) { // при зчитуванні значення реєструємо залежність track(target, key) const res = Reflect.get(target, key, receiver) // якщо значення - об'єкт, робимо його реактивним рекурсивно if (typeof res === 'object' && res !== null) { return reactive(res) } return res }, set(target, key, value, receiver) { const oldValue = target[key] const result = Reflect.set(target, key, value, receiver) // якщо значення справді змінилося - тригеримо оновлення if (oldValue !== value) { trigger(target, key) } return result } }) } ``` `track()` - запам'ятовує, що поточне обчислення (effect/render) залежить від цієї властивості. `trigger()` - оповіщає всі ефекти, що властивість змінилася. --- ## 3. Приклад «у дії» ```javascript import { reactive, effect } from 'vue' const state = reactive({ count: 0 }) effect(() => { console.log(`Кількість: ${state.count}`) }) state.count++ // "Кількість: 1" ``` 1. При першому виклику `effect()` Vue зчитує `state.count` -> викликає `track()`. 2. Vue "запам'ятовує": *ця функція залежить від* `state.count`. 3. Коли `state.count` змінюється -> `trigger()` запускає `effect()` знову. 4. Консоль друкує нове значення. --- ## 4. Що робить `reactive()` внутрішньо | Етап | Що робить Vue | |---|---| | 1. Приймає об'єкт | Перевіряє, чи він уже не є реактивним | | 2. Створює Proxy | Перехоплює `get` і `set` | | 3. При `get` -> `track()` | Реєструє залежність | | 4. При `set` -> `trigger()` | Повідомляє всі залежні ефекти | | 5. Повертає обгортку | Яка поводиться як вихідний об'єкт, але «реагує» на зміни | --- ## 5. Відмінність від `ref()` | Характеристика | `reactive()` | `ref()` | |---|---|---| | Тип даних | Обгортає **об'єкт** | Обгортає **примітив** (число, рядок тощо) | | Звернення | Прямий доступ (`state.count`) | Потрібен `.value` (`count.value`) | | Вкладені об'єкти | Автоматично стають реактивними | Потрібно обгортати вручну | | Коли використовувати | Для складних станів | Для простих значень | Приклад: ```javascript const state = reactive({ count: 0 }) const count = ref(0) state.count++ // реактивно count.value++ // реактивно ``` --- ## 6. Важливі особливості 1. `reactive()` **працює лише з об'єктами** Якщо передати примітив (число, рядок тощо), Vue просто поверне його як є: ```javascript reactive(10) // поверне 10, не реактивно ``` 2. **Реактивність поширюється ліниво (deep reactive)** Вкладені об'єкти стають реактивними лише при першому зверненні до них. 3. **Порівняння за посиланням** Оскільки це Proxy, `state !== rawObject`: ```javascript const raw = { x: 1 } const proxy = reactive(raw) console.log(proxy === raw) // false ``` 4. **Можна отримати оригінал** за допомогою `toRaw()`: ```javascript import { toRaw } from 'vue' const original = toRaw(state) ``` 5. **Можна «заморозити» об'єкт** від реактивності за допомогою `markRaw()`: ```javascript import { markRaw } from 'vue' const nonReactive = markRaw({ foo: 'bar' }) ``` --- ## 7. Коли використовувати `reactive()` - Для **об'єктів стану** компонентів: ```javascript const form = reactive({ name: '', email: '', accepted: false }) ``` - Для **складних структур** (вкладені об'єкти, масиви, колекції): ```javascript const data = reactive({ users: [{ id: 1 }, { id: 2 }], meta: { total: 2 } }) ``` - Для **централізованих сховищ стану** (наприклад, без Vuex / Pinia): ```javascript export const store = reactive({ user: null, isAuth: false }) ``` --- ## 8. Підсумок > `reactive()` робить звичайний об'єкт реактивним за допомогою Proxy. > Vue автоматично відстежує всі читання й записи його властивостей. > Будь-які ефекти, шаблони чи обчислення, що залежать від цих властивостей, > автоматично оновлюються при зміні даних.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.