Skip to content

Reactivity API: Pokročilé ​

shallowRef() ​

„Mělká“ verze ref().

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

    ts
    function triggerRef(ref: ShallowRef): void
  • Příklad

    js
    const 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

    ts
    function 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á funkce track a trigger jako parametry a měla by vrátit objekt s metodami get a set.

    Obecně by mělo být voláno track() uvnitř get() a trigger() 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:

    js
    import { 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>

    Vyzkoušejte si to

    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.

    Vyzkoušejte si to

shallowReactive() ​

„Mělká“ verze reactive().

  • Typ

    ts
    function 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

    js
    const 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

    ts
    function 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

    js
    const 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

    ts
    function toRaw<T>(proxy: T): T
  • Detaily

    toRaw() může vrátit původní objekt z proxy vytvořeného pomocí reactive(), readonly(), shallowReactive() nebo shallowReadonly().

    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

    js
    const 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

    ts
    function markRaw<T extends object>(value: T): T
  • Příklad

    js
    const 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 je shallowReactive(), 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:

    js
    const 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

    ts
    function effectScope(detached?: boolean): EffectScope
    
    interface EffectScope {
      run<T>(fn: () => T): T | undefined // undefined, pokud je rozsah neaktivní
      stop(): void
    }
  • Příklad

    js
    const 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

    ts
    function 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

    ts
    function onScopeDispose(fn: () => void, failSilently?: boolean): void
Reactivity API: Pokročilé has loaded