Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Функция reactive

reactive — второй способ объявить состояние. Он делает реактивным сам объект, поэтому к его полям обращаются напрямую, без .value. Подходит для группы связанных значений, например настроек фильтра.

Объявление

<!-- src/App.vue -->
<script setup>
import { reactive } from 'vue'
 
const filter = reactive({
  query: '',
  onlyActive: false,
})
 
function toggle() {
  filter.onlyActive = !filter.onlyActive
}
</script>
 
<template>
  <button @click="toggle">
    {{ filter.onlyActive ? 'Показать все' : 'Только активные' }}
  </button>
</template>

Каждый клик меняет надпись на кнопке. Поле filter.onlyActive меняется в скрипте без .value, и Vue всё равно перерисовывает шаблон.

Ограничения

reactive работает только с объектами, массивами, Map и Set. Строку или число передать нельзя — для них есть только ref.

Второе ограничение важнее: реактивность теряется, если заменить объект целиком или разобрать его деструктуризацией.

<script setup>
import { reactive } from 'vue'
 
let filter = reactive({ query: '', onlyActive: false })
 
// Связь потеряна: шаблон по-прежнему видит старый объект
filter = reactive({ query: 'хлеб', onlyActive: true })
 
// query — обычная строка, её изменения Vue не увидит
const { query } = filter
</script>

Деструктуризация из урока учебника про объекты здесь копирует значения в обычные переменные, и они перестают быть реактивными.

Сравнение

refreactive
ТипыЛюбыеТолько объекты и коллекции
Доступ в скриптеcount.valuefilter.query
Замена целикомtodos.value = []Нельзя
ДеструктуризацияНе нужнаЛомает реактивность

Что выбрать

Документация Vue советует использовать ref по умолчанию: он работает с любыми значениями, его можно целиком заменить, например, данными из API, и по .value в коде сразу видно, где реактивная переменная. В курсе дальше используется ref. reactive удобен для небольших объектов-групп вроде формы, которые не заменяются целиком.

<script setup>
import { ref } from 'vue'
 
const filter = ref({ query: '', onlyActive: false })
 
function reset() {
  filter.value = { query: '', onlyActive: false }
}
</script>

С ref сброс к начальным значениям — одно присваивание.

Частая ошибка

Загрузить данные и присвоить их переменной reactive:

<script setup>
import { reactive } from 'vue'
 
let todos = reactive([])
 
async function load() {
  const response = await fetch('/todos.json')
  todos = await response.json() // Список на странице не обновится
}
</script>

Объявите список через ref([]) и пишите todos.value = await response.json() — тогда новая ссылка на массив будет замечена.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.