← Назад к вопросам

В чем разница между ref и shallowRef?

2.3 Middle🔥 161 комментариев
#Vue.js#Оптимизация и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между ref и shallowRef

Оба инструмента создают реактивные переменные в Vue.js, но они отличаются глубиной отслеживания изменений.

ref — глубокая реактивность

ref создает полностью реактивное значение, отслеживая изменения на всех уровнях вложенности объекта или массива.

import { ref } from 'vue;

const state = ref({ 
  user: { 
    name: 'John', 
    profile: { age: 30 } 
  } 
});

// Изменение глубоко вложенного свойства вызовет обновление
state.value.user.profile.age = 31; // Срабатывает реактивность

Когда вы меняете .value.user.profile.age, Vue отслеживает это изменение на каждом уровне и обновляет компонент. Это мощно, но требует больше памяти и вычислений.

shallowRef — поверхностная реактивность

shallowRef создает реактивное значение, которое отслеживает только самого себя (.value), но НЕ отслеживает изменения внутри объекта.

import { shallowRef } from 'vue;

const state = shallowRef({ 
  user: { 
    name: 'John', 
    profile: { age: 30 } 
  } 
});

// Это НЕ вызовет обновление
state.value.user.profile.age = 31; 

// Это ВЫЗОВЕТ обновление (замена самого .value)
state.value = { 
  user: { name: 'Jane', profile: { age: 25 } } 
};

Изменение .value.user.profile.age не вызовет переренда, потому что shallowRef не отслеживает вложенные свойства. Обновление произойдет только если полностью заменить .value.

Сравнительная таблица

ХарактеристикаrefshallowRef
ОтслеживаниеВсе уровни (глубокое)Только .value (поверхностное)
ПроизводительностьНиже (больше вычислений)Выше (меньше отслеживания)
ПамятьБольшеМеньше
ИспользованиеБольшинство случаевТяжелые объекты, внешние библиотеки
Когда обновляетсяПри изменении любого свойстваПри замене .value

Когда использовать shallowRef

  1. Большие объекты — когда работаете с массивами на 10000+ элементов

    const largeList = shallowRef(generateMillionItems());
    
  2. Внешние библиотеки — при хранении экземпляров сторонних объектов

    const chartInstance = shallowRef(new Chart(ctx));
    
  3. Иммутабельные обновления — когда вы всегда заменяете объект целиком

    const data = shallowRef({ count: 0 });
    const increment = () => {
      data.value = { count: data.value.count + 1 };
    };
    

Практический пример

import { ref, shallowRef, computed } from 'vue;

export default {
  setup() {
    // Глубокая реактивность для состояния формы
    const formData = ref({
      name: '',
      email: '',
      address: { city: '', zip: '', }
    });

    // Поверхностная реактивность для тяжелого объекта
    const canvas = shallowRef(null);

    const handleNameChange = (newName) => {
      formData.value.name = newName; // Работает
    };

    const initCanvas = (element) => {
      canvas.value = element; // Нужна замена .value
    };

    return { formData, canvas, handleNameChange, initCanvas };
  }
};

Важные нюансы

  • ref по дефолту быстрее с примитивами — для строк и чисел используй ref
  • shallowRef не следит за массивами — изменения элементов массива не вызовут обновление
  • Можно комбинировать — используй ref для данных, shallowRef для компонент-специфичных объектов
  • Производительность критична? — профилируй перед оптимизацией
В чем разница между ref и shallowRef? | PrepBro