В чем разница между ref и shallowRef?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между 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.
Сравнительная таблица
| Характеристика | ref | shallowRef |
|---|---|---|
| Отслеживание | Все уровни (глубокое) | Только .value (поверхностное) |
| Производительность | Ниже (больше вычислений) | Выше (меньше отслеживания) |
| Память | Больше | Меньше |
| Использование | Большинство случаев | Тяжелые объекты, внешние библиотеки |
| Когда обновляется | При изменении любого свойства | При замене .value |
Когда использовать shallowRef
-
Большие объекты — когда работаете с массивами на 10000+ элементов
const largeList = shallowRef(generateMillionItems()); -
Внешние библиотеки — при хранении экземпляров сторонних объектов
const chartInstance = shallowRef(new Chart(ctx)); -
Иммутабельные обновления — когда вы всегда заменяете объект целиком
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 для компонент-специфичных объектов
- Производительность критична? — профилируй перед оптимизацией