> Что такое shallowRef и shallowReactive и каково их назначение во Vue (Vue.js)

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

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

Стек: Vue.js

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

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

shallowRef и shallowReactive - это поверхностные версии ref и reactive во Vue 3. Они создают реактивность только на первом уровне вложенности объекта, не делая глубокого отслеживания изменений во вложенных свойствах. Это повышает производительность при работе с большими или редко изменяемыми структурами данных, где глубокое отслеживание не требуется.

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

В стандартных ref и reactive Vue рекурсивно оборачивает все вложенные объекты в Proxy, делая их глубоко реактивными. Это удобно, но создаёт накладные расходы при каждом доступе к свойству, особенно для больших данных.

shallowRef создаёт реактивность только для самого значения. Если передать объект, изменение его вложенных свойств не вызовет обновления - нужно заменить весь объект целиком. shallowReactive делает реактивными только свойства первого уровня, не трогая вложенные объекты. Это полезно для:

  • Оптимизации производительности с большими неизменяемыми данными (например, результаты API, которые редко меняются).
  • Интеграции с внешними библиотеками, управляющими собственным состоянием (например, Three.js, Mapbox).
  • Создания структур, где вложенные объекты не должны быть реактивными (например, временные кэши).

shallowRef и shallowReactive не отслеживают изменения внутри вложенных массивов или объектов. Для обновления нужно либо заменить корневой объект, либо вручную вызвать triggerRef для shallowRef.

На практике

Используйте shallowRef, когда у вас есть большой объект, который полностью заменяется, а не мутируется. Например, при получении данных с сервера: const data = shallowRef(null), затем data.value = response. Вложенные изменения не нужны, так как при новом запросе приходит новый объект.

shallowReactive применяйте, когда у вас есть объект с несколькими свойствами первого уровня, которые меняются редко, а вложенные структуры управляются отдельно. Например, конфигурация с вложенными настройками, которые не должны быть реактивными.

Важно: при использовании shallowRef с объектами, Vue не будет отслеживать изменения вложенных свойств. Если нужно обновить UI после мутации вложенного поля, используйте triggerRef(shallowRefVariable).

Пример кода

JAVASCRIPT
import { shallowRef, shallowReactive, triggerRef } from 'vue'
// shallowRef
const user = shallowRef({ name: 'Alice', address: { city: 'Moscow' } })
// Изменение вложенного свойства НЕ вызовет обновление
user.value.address.city = 'SPB' // UI не обновится
// Нужно заменить весь объект
user.value = { name: 'Alice', address: { city: 'SPB' } }
// Или вручную вызвать triggerRef
user.value.address.city = 'SPB'
triggerRef(user) // принудительное обновление
// shallowReactive
const config = shallowReactive({
theme: 'dark',
settings: { fontSize: 14 }
})
// Изменение theme вызовет обновление
config.theme = 'light' // UI обновится
// Изменение вложенного объекта НЕ вызовет обновление
config.settings.fontSize = 16 // UI не обновится

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

Начните с краткого определения, затем объясните разницу с обычными ref/reactive. Подчеркните, что это инструмент оптимизации, а не замена. Приведите пример использования с API-данными. Упомяните triggerRef для ручного обновления. Не углубляйтесь в детали реализации Proxy, если не спросят. Будьте готовы ответить на вопрос "когда это действительно нужно?".

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

  • Понимание концепции реактивности во Vue 3.
  • Умение различать глубокую и поверхностную реактивность.
  • Знание сценариев, где поверхностная реактивность оправдана.
  • Осведомлённость о методах принудительного обновления (triggerRef).
  • Отсутствие путаницы между shallowRef и shallowReactive.

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

  • Думать, что shallowRef делает реактивными только примитивы - на самом деле он работает с любыми значениями, но не отслеживает вложенность.
  • Пытаться мутировать вложенные свойства shallowRef и ожидать обновления UI.
  • Использовать shallowReactive для объектов, где нужна полная реактивность - это приводит к багам.
  • Забывать, что shallowRef требует замены значения целиком для обновления, в отличие от ref.
  • Путать shallowRef с markRaw - последний полностью исключает объект из реактивности.

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

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