API de Reactividad: Avanzado
shallowRef()
Versión superficial de ref().
Tipo
tsfunction shallowRef<T>(value: T): ShallowRef<T> interface ShallowRef<T> { value: T }Detalles
A diferencia de
ref(), el valor interno de unshallow refse almacena y expone tal cual, y no se hará profundamente reactivo. Solo el acceso a.valuees reactivo.shallowRef()se utiliza típicamente para optimizaciones de rendimiento de grandes estructuras de datos, o integración con sistemas de gestión de estado externos.Ejemplo
jsconst state = shallowRef({ count: 1 }) // does NOT trigger change state.value.count = 2 // does trigger change state.value = { count: 2 }Ver también
triggerRef()
Fuerza el disparo de efectos que dependen de un shallow ref. Esto se utiliza típicamente después de realizar mutaciones profundas al valor interno de un shallow ref.
Tipo
tsfunction triggerRef(ref: ShallowRef): voidEjemplo
jsconst shallow = shallowRef({ greet: 'Hello, world' }) // Logs "Hello, world" once for the first run-through watchEffect(() => { console.log(shallow.value.greet) }) // This won't trigger the effect because the ref is shallow shallow.value.greet = 'Hello, universe' // Logs "Hello, universe" triggerRef(shallow)
customRef()
Crea un ref personalizado con control explícito sobre su seguimiento de dependencias y el disparo de actualizaciones.
Tipo
tsfunction customRef<T>(factory: CustomRefFactory<T>): Ref<T> type CustomRefFactory<T> = ( track: () => void, trigger: () => void ) => { get: () => T set: (value: T) => void }Detalles
customRef()espera una función de fábrica, la cual recibe las funcionestrackytriggercomo argumentos y debe devolver un objeto con los métodosgetyset.En general,
track()debe llamarse dentro deget(), ytrigger()debe llamarse dentro deset(). Sin embargo, tienes control total sobre cuándo deben llamarse, o si deben llamarse en absoluto.Ejemplo
Creando un
refcon retardo (debounced) que solo actualiza el valor después de un cierto tiempo de espera tras la última llamada aset: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 en componente:
vue<script setup> import { useDebouncedRef } from './debouncedRef' const text = useDebouncedRef('hello') </script> <template> <input v-model="text" /> </template>Uso con precaución
Al usar
customRef, debemos ser cautelosos con el valor de retorno de sugetter, particularmente al generar nuevos tipos de datos de objeto cada vez que se ejecuta elgetter. Esto afecta la relación entre componentes padre e hijo, donde uncustomRefde este tipo ha sido pasado como unaprop.La función de renderizado del componente padre podría dispararse por cambios en un estado reactivo diferente. Durante el redibujado, el valor de nuestro
customRefse reevalúa, devolviendo un nuevo tipo de dato de objeto como unapropa un componente hijo. Estapropse compara con su último valor en el componente hijo, y como son diferentes, las dependencias reactivas delcustomRefse disparan en el componente hijo. Mientras tanto, las dependencias reactivas en el componente padre no se ejecutan porque elsetterdecustomRefno fue llamado, y sus dependencias no se dispararon como resultado.
shallowReactive()
Versión superficial de reactive().
Tipo
tsfunction shallowReactive<T extends object>(target: T): TDetalles
A diferencia de
reactive(), no hay conversión profunda: solo las propiedades de nivel raíz son reactivas para un objetoshallow reactive. Los valores de las propiedades se almacenan y exponen tal cual; esto también significa que las propiedades con valoresrefno se desenvolverán automáticamente.Uso con Precaución
Las estructuras de datos superficiales solo deben usarse para el estado de nivel raíz en un componente. Evita anidarlas dentro de un objeto reactivo profundo, ya que crea un árbol con un comportamiento de reactividad inconsistente que puede ser difícil de entender y depurar.
Ejemplo
jsconst state = shallowReactive({ foo: 1, nested: { bar: 2 } }) // mutating state's own properties is reactive state.foo++ // ...but does not convert nested objects isReactive(state.nested) // false // NOT reactive state.nested.bar++
shallowReadonly()
Versión superficial de readonly().
Tipo
tsfunction shallowReadonly<T extends object>(target: T): Readonly<T>Detalles
A diferencia de
readonly(), no hay conversión profunda: solo las propiedades de nivel raíz se hacen de solo lectura. Los valores de las propiedades se almacenan y exponen tal cual; esto también significa que las propiedades con valoresrefno se desenvolverán automáticamente.Uso con Precaución
Las estructuras de datos superficiales solo deben usarse para el estado de nivel raíz en un componente. Evita anidarlas dentro de un objeto reactivo profundo, ya que crea un árbol con un comportamiento de reactividad inconsistente que puede ser difícil de entender y depurar.
Ejemplo
jsconst state = shallowReadonly({ foo: 1, nested: { bar: 2 } }) // mutating state's own properties will fail state.foo++ // ...but works on nested objects isReadonly(state.nested) // false // works state.nested.bar++
toRaw()
Devuelve el objeto crudo y original de un proxy creado por Vue.
Tipo
tsfunction toRaw<T>(proxy: T): TDetalles
toRaw()puede devolver el objeto original de proxies creados porreactive(),readonly(),shallowReactive()oshallowReadonly().Esta es una vía de escape que se puede usar para leer temporalmente sin incurrir en la sobrecarga de acceso/seguimiento del proxy o escribir sin disparar cambios. No se recomienda mantener una referencia persistente al objeto original. Úsalo con precaución.
Ejemplo
jsconst foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
markRaw()
Marca un objeto para que nunca se convierta en un proxy. Devuelve el objeto mismo.
Tipo
tsfunction markRaw<T extends object>(value: T): TEjemplo
jsconst foo = markRaw({}) console.log(isReactive(reactive(foo))) // false // also works when nested inside other reactive objects const bar = reactive({ foo }) console.log(isReactive(bar.foo)) // falseUso con Precaución
markRaw()y APIs superficiales comoshallowReactive()te permiten excluirte selectivamente de la conversión reactiva/de solo lectura profunda predeterminada e incrustar objetos crudos, no proxy, en tu grafo de estado. Se pueden usar por varias razones:Algunos valores simplemente no deberían hacerse reactivos, por ejemplo, una instancia de clase compleja de terceros, o un objeto de componente Vue.
Omitir la conversión de proxy puede proporcionar mejoras de rendimiento al renderizar grandes listas con fuentes de datos inmutables.
Se consideran avanzados porque la exclusión de "crudo" es solo a nivel de raíz, por lo tanto, si estableces un objeto crudo anidado y no marcado en un objeto reactivo y luego lo accedes de nuevo, obtienes la versión con proxy. Esto puede llevar a riesgos de identidad - es decir, realizar una operación que depende de la identidad del objeto pero usando tanto la versión cruda como la versión proxy del mismo objeto:
jsconst foo = markRaw({ nested: {} }) const bar = reactive({ // although `foo` is marked as raw, foo.nested is not. nested: foo.nested }) console.log(foo.nested === bar.nested) // falseLos riesgos de identidad son, en general, raros. Sin embargo, para utilizar correctamente estas APIs mientras se evitan de forma segura los riesgos de identidad se requiere una comprensión sólida de cómo funciona el sistema de reactividad.
effectScope()
Crea un objeto de alcance de efecto (effect scope) el cual puede capturar los efectos reactivos (es decir, computed y watchers) creados dentro de él para que estos efectos puedan eliminarse juntos. Para casos de uso detallados de esta API, consulta su RFC correspondiente.
Tipo
tsfunction effectScope(detached?: boolean): EffectScope interface EffectScope { run<T>(fn: () => T): T | undefined // undefined if scope is inactive stop(): void }Ejemplo
jsconst scope = effectScope() scope.run(() => { const doubled = computed(() => counter.value * 2) watch(doubled, () => console.log(doubled.value)) watchEffect(() => console.log('Count: ', doubled.value)) }) // to dispose all effects in the scope scope.stop()
getCurrentScope()
Devuelve el effect scope activo actual si existe uno.
Tipo
tsfunction getCurrentScope(): EffectScope | undefined
onScopeDispose()
Registra una función de dispose (callback) en el effect scope activo actual. La función de callback se invocará cuando el effect scope asociado se detenga.
Este método puede usarse como un reemplazo de onUnmounted no acoplado a componentes en funciones de composición reutilizables, ya que la función setup() de cada componente Vue también se invoca en un effect scope.
Se lanzará una advertencia si esta función se llama sin un effect scope activo. En la versión 3.5+, esta advertencia se puede suprimir pasando true como segundo argumento.
Tipo
tsfunction onScopeDispose(fn: () => void, failSilently?: boolean): void








