Ref проти reactive у Vue.js
ref vs reactive
Vue 3 Composition API надає два основні способи створення реактивного стану: ref та reactive. Розуміння їх відмінностей є важливим для написання коректного коду Vue.
ref
ref обгортає значення в реактивний об'єкт з властивістю .value:
<script setup>
import { ref } from 'vue'
const count = ref(0)
const name = ref('Alice')
const user = ref({ name: 'Alice', age: 25 })
// Доступ/зміна через .value в скрипті
count.value++
name.value = 'Bob'
user.value.age = 26
// Можна переназначити все значення
user.value = { name: 'Charlie', age: 30 }
</script>
<template>
<!-- .value автоматично розпаковується в шаблонах -->
<p>{{ count }}</p>
<p>{{ name }}</p>
</template>reactive
reactive створює глибоко реактивний проксі об'єкта:
<script setup>
import { reactive } from 'vue'
const state = reactive({
count: 0,
user: { name: 'Alice', age: 25 },
items: ['a', 'b', 'c']
})
// Доступ безпосередньо — .value не потрібен
state.count++
state.user.name = 'Bob'
state.items.push('d')
// ❌ Не можна переназначити весь об'єкт!
// state = { count: 1 } // Це порушує реактивність!
</script>
<template>
<p>{{ state.count }}</p>
<p>{{ state.user.name }}</p>
</template>Основні Відмінності
| Особливість | ref | reactive |
|---|---|---|
| Працює з | Будь-яким типом (примітиви + об'єкти) | Тільки об'єктами (без примітивів) |
| Доступ у скрипті | Потрібно .value | Прямий доступ |
| Доступ у шаблоні | Авто-розпакування | Прямий доступ |
| Переназначення | ✅ Можна переназначити .value | ❌ Не можна переназначити весь об'єкт |
| Деструктуризація | ✅ Працює (зберігає реактивність) | ❌ Втрачає реактивність |
| TypeScript | Тип Ref<T> | Оригінальний тип |
Проблема Деструктуризації
<script setup>
import { reactive, toRefs } from 'vue'
const state = reactive({ name: 'Alice', age: 25 })
// ❌ Деструктуризація втрачає реактивність!
let { name, age } = state
name = 'Bob' // НЕ реактивно — не оновить шаблон
// ✅ Використовуйте toRefs, щоб зберегти реактивність
const { name: nameRef, age: ageRef } = toRefs(state)
nameRef.value = 'Bob' // ✅ Реактивно!
</script>Коли Використовувати Що
Примітивне значення (рядок, число, булеве)?
→ ref
Хочете замінити все значення?
→ ref
Об'єкт/масив, в якому ви тільки змінюєте властивості?
→ reactive (або ref — обидва працюють)
Простий стан компонента?
→ ref (найбільш поширений, рекомендований командою Vue)Загальний Шаблон: ref для Усього
Команда Vue рекомендує використовувати ref як стандарт:
<script setup>
import { ref } from 'vue'
// ✅ Узгоджено — завжди використовуйте ref
const count = ref(0)
const name = ref('Alice')
const users = ref([{ name: 'Alice' }, { name: 'Bob' }])
const form = ref({ email: '', password: '' })
</script>Важливо:
ref працює з будь-яким типом і вимагає .value в скрипті. reactive працює тільки з об'єктами і надає прямий доступ. Команда Vue рекомендує ref як стандарт, оскільки він більш гнучкий (підтримує примітиви, дозволяє переназначення). Використовуйте reactive, коли ви віддаєте перевагу крапковій нотації для складних об'єктів стану.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.