effectScope, markRaw, readonly, customRef
↑ 7.1 Vue под капотом · ← Предыдущая · → Следующая
Зачем это на собесе
Продвинутые API показывают глубину знаний и умение контролировать память и реактивность.
effectScope
Группирует эффекты, чтобы остановить их одной командой. Основа для composables вне компонентов и для Pinia.
const scope = effectScope()
scope.run(() => {
const doubled = computed(() => count.value * 2)
watch(doubled, () => {})
})
scope.stop() // остановит computed и watchonScopeDispose(fn) — аналог onUnmounted для scope; getCurrentScope() — текущий scope.
markRaw и shallow API
const map = markRaw(new MapboxMap(...)) // никогда не станет реактивным
const state = shallowRef(bigObject) // реактивна только замена .value
const list = shallowReactive({ items }) // реактивен только первый уровеньИспользовать для: сторонних экземпляров (карты, графики, Monaco), больших неизменяемых данных (десятки тысяч записей). Триггер вручную: triggerRef(state).
readonly
const config = readonly(reactive({ theme: 'dark' }))
config.theme = 'light' // предупреждение, изменение запрещеноДаёт безопасный публичный API стора: наружу отдаём readonly-состояние, меняем через действия.
customRef
Создание ref с контролем track и trigger, например debounce:
function useDebouncedRef<T>(value: T, delay = 300) {
let timer: number
return customRef<T>((track, trigger) => ({
get() { track(); return value },
set(v) {
clearTimeout(timer)
timer = window.setTimeout(() => { value = v; trigger() }, delay)
},
}))
}Вопросы с ответами
Зачем markRaw?
Чтобы Vue не оборачивал в Proxy экземпляры сторонних библиотек и большие объекты: экономит память и избавляет от багов из-за прокси.
Когда shallowRef лучше ref?
Когда данные большие и заменяются целиком, а глубокая реактивность не нужна.