Reactivity API: Pokročilé
shallowRef()
„Mělká“ verze ref()
.
Typ
tsfunction shallowRef<T>(value: T): ShallowRef<T> interface ShallowRef<T> { value: T }
Podrobnosti
Na rozdíl od
ref()
je vnitřní hodnota mělké reference uložena a vystavena tak, jak je, a nebude hluboce (deep) reaktivní. Reaktivní je pouze přístup k.value
.shallowRef()
se obvykle používá pro optimalizaci výkonu velkých datových struktur nebo pro integraci s externími systémy pro správu stavu.Příklad
jsconst state = shallowRef({ count: 1 }) // nezpůsobí změnu state.value.count = 2 // způsobí změnu state.value = { count: 2 }
Viz také:
triggerRef()
Vynutí spuštění efektů, které závisí na shallow ref. To se obvykle používá po provedení hlubokých mutací vnitřní hodnoty mělké reference.
Typ
tsfunction triggerRef(ref: ShallowRef): void
Příklad
jsconst shallow = shallowRef({ greet: 'Ahoj, Vue' }) // 'Ahoj, Vue' se zaloguje jednou při prvním spuštění watchEffect(() => { console.log(shallow.value.greet) }) // Toto nezpůsobí spuštění efektu, protože reference je mělká shallow.value.greet = 'Ahoj, Vue 3' // Zaloguje 'Ahoj, Vue 3' triggerRef(shallow)
customRef()
Vytvoří upravenou referenci s explicitní kontrolou sledování závislostí a spouštění aktualizací.
Typ
tsfunction customRef<T>(factory: CustomRefFactory<T>): Ref<T> type CustomRefFactory<T> = ( track: () => void, trigger: () => void ) => { get: () => T set: (value: T) => void }
Podrobnosti
customRef()
očekává tovární funkci, která přijímá funkcetrack
atrigger
jako parametry a měla by vrátit objekt s metodamiget
aset
.Obecně by mělo být voláno
track()
uvnitřget()
atrigger()
uvnitřset()
. Nicméně máte plnou kontrolu nad tím, kdy by měly být volány nebo zda by vůbec měly být volány.Příklad
Vytvoření „debounced“ ref, který aktualizuje hodnotu až po určitém časovém prodlení po posledním volání
set
:jsimport { customRef } from 'vue' export function useDebouncedRef(value, delay = 200) { let timeout return customRef((track, trigger) => { return { get() { track() return value }, set(newValue) { clearTimeout(timeout) timeout = setTimeout(() => { value = newValue trigger() }, delay) } } }) }
Použití v komponentě:
vue<script setup> import { useDebouncedRef } from './debouncedRef' const text = useDebouncedRef('ahoj') </script> <template> <input v-model="text" /> </template>
Používejte s rozvahou
Při použití
customRef
bychom měli být opatrní při práci s návratovou hodnotou jeho getteru, zejména když se při každém spuštění getteru tvoří nové datové objekty. Pokud je takový customRef předáván jako vlastnost (prop), ovlivňuje to vztah mezi komponentami rodiče a potomka.Funkce pro vykreslení komponenty rodiče může být spuštěna změnami jiného reaktivního stavu. Během nového vykreslení je hodnota našeho customRef znovu vyhodnocena a vrátí nový datový objekt, který je ihned předán jako nová hodnota vlastnosti do komponenty potomka. Uvnitř komponenty potomka je porovnána s poslední hodnotou a jelikož je odlišná, jsou v komponentě potomka spuštěny reaktivní závislosti daného customRef. Reaktivní závislosti v komponentě rodiče se ovšem nespustí, protože pro customRef samotný k volání jeho setteru nedošlo.
shallowReactive()
„Mělká“ verze reactive()
.
Typ
tsfunction shallowReactive<T extends object>(target: T): T
Podrobnosti
Na rozdíl od
reactive()
zde není hluboká konverze: reaktivní jsou pouze vlastnosti na nejvyšší úrovni mělce reaktivního objektu. Hodnoty vlastností jsou uloženy a vystaveny tak, jak jsou - to také znamená, že vlastnosti s hodnotami ref nebudou automaticky rozbaleny.Používejte s rozvahou
Měl byste používat mělké datové struktury pouze pro stav na kořenové úrovni komponenty. Vyhněte se vnořování do hluboké reaktivní struktury, protože to vytváří strom s nekonzistentním chováním reaktivity, což může být obtížné pochopit a ladit.
Příklad
jsconst state = shallowReactive({ foo: 1, nested: { bar: 2 } }) // změna vlastností stavu je reaktivní state.foo++ // ...ale nekonvertuje vnořené objekty isReactive(state.nested) // false // NENÍ reaktivní state.nested.bar++
shallowReadonly()
„Mělká“ verze readonly()
.
Typ
tsfunction shallowReadonly<T extends object>(target: T): Readonly<T>
Detaily
Na rozdíl od
readonly()
zde není hluboká konverze: pouze vlastnosti na nejvyšší úrovni jsou nastaveny jako pouze pro čtení. Hodnoty vlastností jsou uloženy a vystaveny tak, jak jsou - to znamená, že vlastnosti s ref hodnotami nebudou automaticky rozbaleny.Používejte s rozvahou
Měl byste používat mělké datové struktury pouze pro stav na kořenové úrovni komponenty. Vyhněte se vnořování do hluboké reaktivní struktury, protože to vytváří strom s nekonzistentním chováním reaktivity, což může být obtížné pochopit a ladit.
Příklad
jsconst state = shallowReadonly({ foo: 1, nested: { bar: 2 } }) // změna vlastností stavu selže state.foo++ // ...ale funguje na vnořených objektech isReadonly(state.nested) // false // funguje state.nested.bar++
toRaw()
Vrátí původní objekt vytvořený z proxy vytvořené Vue.
Typ
tsfunction toRaw<T>(proxy: T): T
Detaily
toRaw()
může vrátit původní objekt z proxy vytvořeného pomocíreactive()
,readonly()
,shallowReactive()
neboshallowReadonly()
.Toto je únikový mechanismus, který lze použít k dočasnému čtení bez nákladů na přístup / sledování proxy nebo k zápisu bez vyvolání změn. Není doporučeno uchovávat trvalý odkaz na původní objekt. Používejte s rozvahou.
Příklad
jsconst foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
markRaw()
Označuje objekt tak, aby nikdy nebyl převeden na proxy. Vrací samotný (raw) objekt.
Typ
tsfunction markRaw<T extends object>(value: T): T
Příklad
jsconst foo = markRaw({}) console.log(isReactive(reactive(foo))) // false // funguje také v případě, když je vnořený v jiných reaktivních objektech const bar = reactive({ foo }) console.log(isReactive(bar.foo)) // false
Používejte s rozvahou
markRaw()
a mělké API funkce, jako jeshallowReactive()
, vám umožňují selektivně odmítnout výchozí hlubokou reaktivní/readonly konverzi a vložit do vašeho stavového grafu neupravené, neproxyované objekty. Můžete je použít z různých důvodů:Některé hodnoty jednoduše nemají být reaktivní, například složitá instance třetí strany nebo objekt Vue komponenty.
Přeskočení proxy konverze může znamenat vylepšení výkonu při vykreslování velkých seznamů s neměnnými zdroji dat.
Jsou považovány za pokročilé, protože možnost opt-outu z výchozího chování platí pouze na nejvyšší úrovni objektu, takže pokud nastavíte vnořený, neoznačený a neupravený objekt do reaktivního objektu, a poté na něj znovu přistoupíte, dostanete zpět proxy verzi. To může vést k rizikům identity - tj. provádění operace, která se spoléhá na identitu objektu, ale používá jak původní, tak proxy verzi stejného objektu:
jsconst foo = markRaw({ nested: {} }) const bar = reactive({ // i když je `foo` označen jako neupravený (raw), foo.nested není. nested: foo.nested }) console.log(foo.nested === bar.nested) // false
Rizika identity jsou obecně vzácná. Ovšem správné využití těchto API při bezpečném vyhýbání se problémům vyžaduje dobré porozumění tomu, jak systém reaktivity funguje.
effectScope()
Vytváří objekt efektového rozsahu (effect scope), který může zachytit reaktivní efekty (tj. computed proměnné a watchery) vytvořené uvnitř něj, aby bylo možné tyto efekty zrušit společně. Pro podrobné použití tohoto API se prosím obraťte na příslušnou RFC.
Typ
tsfunction effectScope(detached?: boolean): EffectScope interface EffectScope { run<T>(fn: () => T): T | undefined // undefined, pokud je rozsah neaktivní stop(): void }
Příklad
jsconst scope = effectScope() scope.run(() => { const doubled = computed(() => counter.value * 2) watch(doubled, () => console.log(doubled.value)) watchEffect(() => console.log('Počet: ', doubled.value)) }) // zrušení všech efektů v rozsahu scope.stop()
getCurrentScope()
Vrátí aktuálně aktivní effect scope, pokud existuje.
Typ
tsfunction getCurrentScope(): EffectScope | undefined
onScopeDispose()
Zaregistruje callback pro zrušení v aktuálně aktivním effect scope. Callback bude vyvolán při zastavení příslušného rozsahu efektů.
Tato metoda může být použita jako nesouvisející náhrada onUnmounted
v opakovaně použitelných kompozičních funkcích, protože každá funkce setup()
Vue komponenty je také volána v rozsahu efektů.
Pokud je tato funkce volána mimo aktivní rozsah efektů, vyvolá to varování. Od verze 3.5+ lze toto varování potlačit předáním druhého parametru true
.
Typ
tsfunction onScopeDispose(fn: () => void, failSilently?: boolean): void