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