0Pricing
Vue Academy · Урок

Продвинутая реактивность: shallowRef и triggerRef

shallowRef для производительности, markRaw для исключения из реактивности и triggerRef для ручного запуска

«Продвинутая реактивность: shallowRef и triggerRef» — бесплатный урок Vue Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.

За пределами ref и reactive

Глубокая реактивность Vue удобна, но не всегда нужна. Для больших объектов или внешних экземпляров глубокое отслеживание неэффективно. Vue предлагает shallowRef, triggerRef и markRaw для точного управления.

Как ref отслеживает изменения на глубоком уровне

Обычный ref, содержащий объект, делает весь объект глубоко реактивным — изменение любого вложенного свойства вызывает обновления. Это отлично подходит для небольшого state, но дорого обходится для крупных структур.

import { ref } from "vue"

const user = ref({ name: "Ada", prefs: { theme: "dark" } })
user.value.prefs.theme = "light" // triggers update (deep)

shallowRef: реактивен только .value

shallowRef отслеживает переназначение .value, но не отслеживает изменения внутри содержащегося значения. Внутренние изменения не вызывают повторную отрисовку.

import { shallowRef } from "vue"

const state = shallowRef({ count: 0 })
state.value.count++        // does NOT trigger update
state.value = { count: 1 } // DOES trigger (new .value)

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

Используйте его для больших почти неизменяемых данных, которые заменяются целиком, или для оборачивания внешних объектов (экземпляр chart, большой набор данных), когда глубокое отслеживание создает дополнительные затраты без пользы.

const chart = shallowRef(null)
// chart.value = new Chart(...) replaces wholesale

Проблема глубокой мутации

Иногда Вы всё же выполняете DO-мутации внутри shallowRef (ради производительности), но при этом Вам нужен повторный рендер в контролируемый момент. Vue не видит это изменение, и интерфейс перестаёт обновляться.

const list = shallowRef([1, 2, 3])
list.value.push(4) // mutated, but no update fires

triggerRef: принудительное обновление

triggerRef вручную заставляет эффекты, зависящие от поверхностной ссылки, повторно выполняться после изменения её содержимого. Вы объединяете множество изменений, а затем вызываете его один раз.

import { shallowRef, triggerRef } from "vue"

const list = shallowRef([1, 2, 3])
list.value.push(4)
list.value.push(5)
triggerRef(list) // now the UI updates

Приём для повышения производительности

Суть приёма такова: храните большую структуру в shallowRef, свободно изменяйте её без затрат на реактивность при каждом изменении, а затем один раз вызывайте triggerRef, когда хотите отобразить всю серию изменений.

function bulkUpdate(rows) {
  for (const r of rows) data.value.push(r) // cheap
  triggerRef(data)                         // one update
}

markRaw: полный отказ от реактивности

markRaw помечает объект так, чтобы Vue никогда не делал его реактивным, даже если он находится внутри reactive или обычного ref. Используйте его для экземпляров классов сторонних библиотек, которые не следует оборачивать в прокси.

import { markRaw, reactive } from "vue"

const state = reactive({
  map: markRaw(new ThirdPartyMap()),
})
// state.map is the raw instance, never a proxy

Почему важен markRaw

Оборачивание сложных экземпляров классов (карт, редакторов, веб-сокетов) в реактивный прокси может нарушить их внутренние ссылки или вызвать трудноуловимые ошибки. markRaw оставляет их нетронутыми, при этом они по-прежнему могут находиться внутри реактивного состояния.

Объединение инструментов

Эти инструменты хорошо сочетаются: shallowRef, содержащий экземпляр, помеченный с помощью markRaw, даёт Вам слот, который можно реактивно заменить, а внутренний объект Vue никогда не оборачивает в прокси. Это идеально подходит для внешних интеграций.

const editor = shallowRef(null)
function init(el) {
  editor.value = markRaw(new CodeEditor(el))
}

Затраты на реактивность и контроль

Компромисс заключается в следующем: глубокая реактивность не требует дополнительных усилий, но обходится дороже; поверхностные API дают контроль и производительность ценой необходимости самостоятельно запускать обновления. Используйте их только тогда, когда профилирование показывает такую необходимость.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете расширенные возможности реактивности.

Повторение

Вы изучили расширенные средства управления реактивностью:

  • shallowRef реагирует только на переназначение .value, но не на изменения внутри значения — это удобно для больших или внешних данных.
  • triggerRef вручную запускает обновления после изменения содержимого поверхностной ссылки (сначала объедините изменения, затем вызовите его один раз).
  • markRaw навсегда исключает объект из реактивности и идеально подходит для экземпляров классов сторонних библиотек.
  • Эти средства повышают производительность и дают контроль, но обновления приходится запускать самостоятельно.

Часто задаваемые вопросы

Урок «Продвинутая реактивность: shallowRef и triggerRef» бесплатный?

Да — полный текст урока «Продвинутая реактивность: shallowRef и triggerRef» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.

Чему я научусь в уроке «Продвинутая реактивность: shallowRef и triggerRef»?

shallowRef для производительности, markRaw для исключения из реактивности и triggerRef для ручного запуска Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Vue Academy?

Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Продвинутая реактивность: shallowRef и triggerRef»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Vue Academy?

Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Продвинутая реактивность: shallowRef и triggerRef
  2. Фабрики композируемых модулей и параметризованные композируемые модули
  3. Конечные автоматы с XState во Vue
  4. effectScope для группировки эффектов
← Назад к Vue Academy