> Что такое reactive и ref во Vue Composition API, для чего они нужны и чем отличаются? (Vue.js)

Уровень: junior · Роль: frontend · Категория: Технические вопросы

Компании: The Tribe, ЛОЦИЯ

Стек: Vue.js

> Пример ответа

Короткий ответ

reactive и ref - это функции Composition API для создания реактивных данных. ref принимает примитив или объект и возвращает объект с .value, обеспечивая реактивность. reactive принимает только объект и делает его глубоко реактивным, без необходимости в .value. ref удобен для примитивов и передачи в props, reactive - для сложных структур.

Подробное объяснение

Во Vue 3 Composition API реактивность строится на Proxy. ref создаёт реактивную ссылку: для примитивов (числа, строки, булевы) он оборачивает значение в объект с единственным свойством value, а для объектов - дополнительно передаёт их в reactive. Доступ к значению всегда через .value в JavaScript, но в шаблоне Vue автоматически разворачивает ref.

reactive работает только с объектами (включая массивы и Map/Set). Он возвращает Proxy, который отслеживает изменения на любом уровне вложенности. При этом доступ к свойствам идёт напрямую, без .value. Однако reactive нельзя переприсвоить целиком - это сломает реактивность. Также он не работает с примитивами.

Основные отличия:

  • ref подходит для любых типов, reactive - только для объектов.
  • ref требует .value в JS, reactive - нет.
  • ref можно переприсвоить (например, count.value = 5), reactive - только мутировать свойства.
  • При деструктуризации reactive теряет реактивность, для ref нужно использовать toRefs.

На практике

Для простых счётчиков, строк, булевых флагов используйте ref - он лаконичнее и безопаснее при передаче в функции. Для форм, сложных объектов с вложенностью (например, данные пользователя или настройки) удобнее reactive, так как не нужно писать .value на каждом уровне.

ref автоматически разворачивается в шаблонах, поэтому {{ count }} работает, а {{ count.value }} - ошибка. Внутри setup или <script setup> всегда используйте .value для ref.

При передаче реактивных данных в дочерние компоненты через props лучше использовать ref, так как он сохраняет реактивность при передаче по ссылке. reactive может привести к неожиданному поведению, если передать его целиком.

Пример кода

<script setup>
import { ref, reactive } from 'vue'

// ref для примитивов
const count = ref(0)
const name = ref('Vue')

// reactive для объектов
const user = reactive({
  firstName: 'Иван',
  lastName: 'Петров',
  address: {
    city: 'Москва',
    street: 'Тверская'
  }
})

// Использование в функциях
function increment() {
  count.value++  // обязательно .value
}

function updateCity(newCity) {
  user.address.city = newCity  // без .value
}

// Переприсвоение ref
function reset() {
  count.value = 0
}

// reactive нельзя переприсвоить - это сломает реактивность
// user = { firstName: 'Новый' } // ❌ ошибка
</script>

<template>
  <div>
    <p>Счётчик: {{ count }}</p>
    <p>Имя: {{ name }}</p>
    <p>Пользователь: {{ user.firstName }} {{ user.lastName }}</p>
    <p>Город: {{ user.address.city }}</p>
    <button @click="increment">+1</button>
    <button @click="updateCity('Санкт-Петербург')">Сменить город</button>
  </div>
</template>

Как отвечать на собеседовании

Начните с определения: обе функции создают реактивные данные, но ref универсален (работает с примитивами и объектами), а reactive - только с объектами. Подчеркните ключевое различие в доступе: .value у ref против прямого доступа у reactive. Приведите простой пример: счётчик через ref, форму через reactive. Упомяните, что в шаблоне ref разворачивается автоматически. Если спросят про внутреннее устройство, скажите, что ref для примитивов использует getter/setter, а для объектов - Proxy (тот же reactive).

Что проверяет интервьюер

Интервьюер оценивает понимание основ реактивности Vue 3, отличие примитивов от объектов в контексте Proxy, умение выбирать правильный инструмент под задачу. Также проверяется знание ограничений: reactive нельзя переприсваивать, теряет реактивность при деструктуризации. Для junior достаточно базового понимания, без углубления в детали реализации.

Типичные ошибки

  • Использование reactive с примитивами - это не сработает, нужно ref.
  • Забывание .value при работе с ref в JavaScript (в шаблоне это не нужно).
  • Попытка переприсвоить reactive целиком - реактивность теряется.
  • Деструктуризация reactive без toRefs - переменные становятся обычными.
  • Путаница: думать, что ref всегда требует .value в шаблоне - это неверно.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью