API de Reatividade: Avançado
shallowRef()
Versão superficial de ref().
Tipo
tsfunction shallowRef<T>(value: T): ShallowRef<T> interface ShallowRef<T> { value: T }Detalhes
Ao contrário de
ref(), o valor interno duma referência superficial é armazenado e exposto como é, e não será profundamente reativa. Apenas o acesso de.valueé reativo.shallowRef()é normalmente usado para otimizações de desempenho de grandes estruturas de dados ou integração com sistemas externos de gestão de estado.Exemplo
jsconst state = shallowRef({ count: 1 }) // NÃO aciona mudança state.value.count = 2 // aciona mudança state.value = { count: 2 }Consulte também:
triggerRef()
Força o acionamento de efeitos que dependem duma referência superficial. Isso é normalmente usado depois de fazer-se mutações profundas no valor interno duma referência superficial.
Tipo
tsfunction triggerRef(ref: ShallowRef): voidExemplo
jsconst shallow = shallowRef({ greet: 'Hello, world' }) // Regista "Hello, world" uma vez para o primeiro ensaio watchEffect(() => { console.log(shallow.value.greet) }) // Isto não acionará o efeito porque a referência é superficial shallow.value.greet = 'Hello, universe' // Regista "Hello, universe" triggerRef(shallow)
customRef()
Cria uma referência personalizada com controlo explícito sobre o rastreio de dependência e acionamento de atualizações.
Tipo
tsfunction customRef<T>(factory: CustomRefFactory<T>): Ref<T> type CustomRefFactory<T> = ( track: () => void, trigger: () => void ) => { get: () => T set: (value: T) => void }Detalhes
customRef()espera uma função de fábrica, que recebe as funçõestracketriggercomo argumentos e deve retornar um objeto com os métodosgeteset.Em geral,
track()deve ser chamado dentro deget(), etrigger()deve ser chamado dentro deset(). No entanto, temos controlo total sobre quando devem ser chamados ou se devem ser chamados.Exemplo
Criação duma referência de velocidade reduzida que apenas atualiza o valor após uma certa pausa após a última chamada definida:
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) } } }) }Uso no componente:
vue<script setup> import { useDebouncedRef } from './debouncedRef' const text = useDebouncedRef('hello') </script> <template> <input v-model="text" /> </template>
shallowReactive()
Versão superficial de reactive().
Tipo
tsfunction shallowReactive<T extends object>(target: T): TDetalhes
Ao contrário de
reactive(), não existe conversão profunda: apenas as propriedades de nível raiz são reativas para um objeto reativo superficial. Os valores de propriedade são armazenados e expostos como são - isto também significa que as propriedades com valores de referência não serão desembrulhados automaticamente.Use com Cautela
Estruturas de dados superficiais devem ser usadas apenas para o estado de nível de raiz num componente. Evite encaixá-lo dentro dum objeto reativo profundo, visto que cria uma árvore com comportamento de reatividade inconsistente que pode ser difícil de entender e depurar.
Exemplo
jsconst state = shallowReactive({ foo: 1, nested: { bar: 2 } }) // a mutação das propriedades do próprio estado é reativa state.foo++ // ...mas não converte objetos encaixados isReactive(state.nested) // false // NÃO é reativo state.nested.bar++
shallowReadonly()
Versão superficial de readonly().
Tipo
tsfunction shallowReadonly<T extends object>(target: T): Readonly<T>Detalhes
Ao contrário de
readonly(), não existe conversão profunda: apenas propriedades de nível de raiz são tornadas de somente leitura. Os valores de propriedade são armazenados e expostos como são - isto também significa que as propriedades com valores de referência não serão desembrulhados automaticamente.Use com Cautela
Estruturas de dados rasas devem ser usadas apenas para o estado de nível de raiz num componente. Evite encaixá-lo dentro dum objeto reativo profundo, visto que cria uma árvore com comportamento de reatividade inconsistente que pode ser difícil de entender e depurar.
Exemplo
jsconst state = shallowReadonly({ foo: 1, nested: { bar: 2 } }) // a mutação das propriedades do próprio estado falhará state.foo++ // ...mas funciona sobre objetos encaixados isReadonly(state.nested) // false // funciona state.nested.bar++
toRaw()
Retorna o puro, objeto original duma delegação criada pela Vue.
Tipo
tsfunction toRaw<T>(proxy: T): TDetalhes
toRaw()pode retornar o objeto original a partir das delegações criadas porreactive(),readonly(),shallowReactive()oushallowReadonly().Isto é uma escotilha de fuga que pode ser usada para ler temporariamente sem ficar sujeito ao acesso da delegação ou custos de rastreio ou escrever sem acionar mudanças. Não é recomendado segurar uma referência persistente ao objeto original. Use com cautela.
Exemplo
jsconst foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
markRaw()
Marca um objeto para nunca ser convertido à uma delegação. Retorna o próprio objeto.
Tipo
tsfunction markRaw<T extends object>(value: T): TExemplo
jsconst foo = markRaw({}) console.log(isReactive(reactive(foo))) // false // também funciona quando encaixado dentro dos outros objetos reativos const bar = reactive({ foo }) console.log(isReactive(bar.foo)) // falseUse com Cautela
markRaw()e as APIs superficiais tais comoshallowReactive()permitem-nos abandonar seletivamente a conversão profunda reativa ou de somente leitura padrão e fixar objetos brutos não delegados no nosso grafo de estado. Eles podem ser usados por várias razões:Alguns valores simplesmente não deveriam ser reativos, por exemplo, uma instância de classe de terceiros complexa ou um objeto de componente Vue.
Ignorar a conversão de delegação pode fornecer melhorias de desempenho quando interpretamos grandes listas com fontes de dados imutáveis.
Eles são considerados avançados porque o puro abandono é apenas ao nível de raiz, então se definirmos um objeto puro não marcado encaixado num objeto reativo e então acessá-lo novamente, recebemos de volta a versão delegada. Isto pode conduzir à riscos de identidade - por exemplo, executar uma operação que depende da identidade do objeto porém usando ambas a pura e versão delegada do mesmo objeto:
jsconst foo = markRaw({ nested: {} }) const bar = reactive({ // apesar de `foo` ser marcada como pura, `foo.nested` não é. nested: foo.nested }) console.log(foo.nested === bar.nested) // falseOs riscos de identidade são em geral raros. No entanto, para usar adequadamente estas APIs enquanto evitar-se riscos de identidade com segurança exige um conhecimento sólido de como o sistema de reatividade funciona.
effectScope()
Cria um objeto de âmbito de efeito que pode capturar os efeitos reativos (por exemplo, propriedades computadas e observadores) criados dentro dela para que estes efeitos possam ser colocados juntos. Para casos de uso detalhados desta API, consulte seu RFC correspondente.
Tipo
tsfunction effectScope(detached?: boolean): EffectScope interface EffectScope { run<T>(fn: () => T): T | undefined // `undefined` se o âmbito estiver inativo stop(): void }Exemplo
jsconst scope = effectScope() scope.run(() => { const doubled = computed(() => counter.value * 2) watch(doubled, () => console.log(doubled.value)) watchEffect(() => console.log('Count: ', doubled.value)) }) // colocar todos efeitos no âmbito scope.stop()
getCurrentScope()
Retorna o âmbito de efeito ativo atual, se existir um.
Tipo
tsfunction getCurrentScope(): EffectScope | undefined
onScopeDispose()
Regista uma função de resposta de despacho no âmbito de efeito ativo atual. A função de resposta será invocada quando o âmbito de efeito associado for parado.
Este método pode ser usado como uma substituição não associada ao componente de onUnmounted nas funções de composição reutilizáveis, uma vez que a função setup() de cada componente da Vue também é invocada num âmbito de efeito.
Tipo
tsfunction onScopeDispose(fn: () => void): void