Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить toRefs()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`toRef()` створює реактивне посилання (**ref**) на конкретну властивість реактивного об'єкта: воно не копіює значення, а прив'язує `.value` напряму до вихідної властивості. `toRefs()` робить те саме одразу для всіх властивостей об'єкта, повертаючи об'єкт із `ref`-ів. **Ключове:** обидві функції потрібні, щоб не втратити реактивність при деструктуризації або передачі даних між компонентами.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `toRef()` Функція `toRef()` створює **реактивне посилання (**`ref`**) на конкретну властивість реактивного об'єкта**. Вона не копіює значення - вона **зв'язує** `.value` **напряму** з вихідною властивістю. Тобто зміни в оригінальному об'єкті відображаються в `ref`, і навпаки. ### Приклад: ```javascript import { reactive, toRef } from 'vue' const state = reactive({ count: 0 }) const countRef = toRef(state, 'count') console.log(countRef.value) // 0 countRef.value++ // збільшили через ref console.log(state.count) // → 1 (змінився і вихідний об'єкт) state.count = 5 console.log(countRef.value) // → 5 (змінився і ref) ``` **Важливо:** `toRef()` не створює нову реактивність - це просто "вказівник" на вже реактивну властивість. --- ## 2. Що робить `toRefs()` Функція `toRefs()` робить те саме, але **одразу для всіх властивостей об'єкта**. Вона повертає **об'єкт з** `ref`**-ів**, де кожне поле зв'язане з відповідною властивістю оригіналу. ### Приклад: ```javascript import { reactive, toRefs } from 'vue' const state = reactive({ count: 0, name: 'Tim' }) const { count, name } = toRefs(state) count.value++ // змінили через ref console.log(state.count) // → 1 state.name = 'Alex' console.log(name.value) // → 'Alex' ``` Тепер `count` і `name` - це `ref`-обгортки, зв'язані з `state`. --- ## 3. Навіщо вони потрібні Найчастіший випадок - **деструктуризація реактивних об'єктів.** Якщо зробити ось так: ```javascript const state = reactive({ count: 0, name: 'Tim' }) const { count, name } = state ``` Ти **втратиш реактивність**, тому що `count` і `name` стануть просто копіями значень (числом і рядком). Рішення - використовувати `toRefs()`: ```javascript const { count, name } = toRefs(state) ``` Тепер `count` і `name` - це реактивні `ref`-посилання, які **залишаються синхронізованими** зі `state`. --- ## 4. Різниця між `toRef()` і `toRefs()` | Критерій | `toRef()` | `toRefs()` | |---|---|---| | Що робить | Створює `ref` для **однієї властивості** реактивного об'єкта | Створює `ref` для **всіх властивостей** об'єкта | | Повертає | Один `ref` | Об'єкт, де кожне поле - `ref` | | Використовується коли | Потрібно зробити посилання на одне поле | Потрібно деструктурувати весь об'єкт | | Синтаксис | `toRef(obj, 'key')` | `toRefs(obj)` | | Втрата реактивності при деструктуризації | Немає | Немає (для всіх властивостей) | --- ## 5. Як це працює під капотом Спрощено (у вихідному коді Vue): ```javascript function toRef(object, key) { return { get value() { return object[key] }, set value(newVal) { object[key] = newVal } } } ``` А `toRefs()` просто викликає `toRef()` для кожного ключа: ```javascript function toRefs(obj) { const result = {} for (const key in obj) { result[key] = toRef(obj, key) } return result } ``` Тобто це не нові `reactive()` чи `ref()`, а **"тонкі мости"** між полями об'єкта та їхніми значеннями. --- ## 6. Приклад реального використання (у `setup()`) ```javascript import { reactive, toRefs } from 'vue' export default { setup() { const state = reactive({ count: 0, name: 'Tim' }) // щоб можна було повернути деструктуровано в template: return { ...toRefs(state) } } } ``` Тепер у шаблоні можна писати: ```javascript <template> <p>{{ count }}</p> <!-- автоматично count.value --> <button @click="count++">+</button> </template> ``` Без `toRefs()` це б не працювало - `count` втратив би реактивність після деструктуризації. --- ## 7. Нюанс: можна використовувати `toRef()` окремо Наприклад, щоб передати **одну реактивну властивість** у дочірній компонент: ```javascript const user = reactive({ name: 'Tim', age: 25 }) const nameRef = toRef(user, 'name') // передаємо лише nameRef - але воно все ще зв'язане з user.name ``` Якби ти передав просто `user.name`, реактивність би втратилася. --- ## 8. Що буде, якщо викликати `toRef()` для неіснуючої властивості Vue створить **порожній** `ref(undefined)`, і при записі в `.value` - додасть нову властивість у вихідний об'єкт: ```javascript const state = reactive({}) const age = toRef(state, 'age') console.log(age.value) // undefined age.value = 30 console.log(state.age) // 30 ``` --- ## 9. Підсумок | Функція | Що робить | Коли використовувати | |---|---|---| | `toRef(obj, key)` | Створює `ref`, зв'язаний з `obj[key]` | Коли потрібно реактивно працювати з **однією властивістю** | | `toRefs(obj)` | Перетворює **всі властивості** об'єкта на `ref` | Коли потрібно **деструктурувати реактивний об'єкт** і зберегти реактивність | --- **Коротко:** > `toRef()` - робить *одне* реактивне "посилання" на властивість. > `toRefs()` - робить *набір* таких посилань. > > Обидві потрібні, щоб **не втрачати реактивність** при деструктуризації або передачі даних між компонентами.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.