API reactiva: núcleo
1. referencia()
Toma un valor interno y devuelve un objeto ref mutable reactivo con solo una propiedad que apunta a su valor interno .value
.
-
tipo
function ref<T>(value: T): Ref<UnwrapRef<T>> interface Ref<T> { value: T }
-
detalles
El objeto ref es mutable, lo que significa que puede
.value
asignarle nuevos valores. También es reactivo, es decir, todas.value
las operaciones serán rastreadas y las escrituras desencadenarán efectos secundarios asociados con ellas.Si se asigna un objeto a ref, este objeto se convertirá en un objeto con una capacidad de respuesta profunda a través de reactive() . Esto también significa que si el objeto contiene referencias anidadas, se desenvolverán profundamente.
Para evitar esta conversión profunda, utilice
shallowRef()
en su lugar. -
ejemplo
const count = ref(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
Dos, reactivo ()
Devuelve un proxy reactivo para un objeto .
-
tipo
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
-
detalles
Una transformación reactiva es "profunda": afecta a todas las propiedades anidadas. Un objeto reactivo también desenvolverá profundamente cualquier propiedad de referencia sin dejar de responder.
Vale la pena señalar que al acceder a un elemento ref en una matriz reactiva o
Map
en un tipo de colección nativo, no se realizará el desenvolvimiento de ref.Para evitar transiciones reactivas profundas y solo desea preservar la capacidad de respuesta del acceso de nivel superior a este objeto, use en su lugar, el método de reacción superficial () .
El objeto devuelto y sus objetos anidados serán envueltos por ES Proxy , por lo que no es igual al objeto de origen. Se recomienda usar solo proxies receptivos y evitar usar objetos originales.
-
ejemplo
Crear un objeto reactivo:
const obj = reactive({ count: 0 }) obj.count++
Desembalaje de ref:
const count = ref(1) const obj = reactive({ count }) // ref 会被解包 console.log(obj.count === count.value) // true // 会更新 `obj.count` count.value++ console.log(count.value) // 2 console.log(obj.count) // 2 // 也会更新 `count` ref obj.count++ console.log(obj.count) // 3 console.log(count.value) // 3
Tenga en cuenta que al acceder a un elemento ref en una matriz reactiva o
Map
en un tipo de colección nativo, no se realiza el desenvolvimiento de ref:const books = reactive([ref('Vue 3 Guide')]) // 这里需要 .value console.log(books[0].value) const map = reactive(new Map([['count', ref(0)]])) // 这里需要 .value console.log(map.get('count').value)
Al asignar una referencia a una
reactive
propiedad, la referencia se desenvolverá automáticamente:const count = ref(1) const obj = reactive({ }) obj.count = count console.log(obj.count) // 1 console.log(obj.count === count.value) // true
Tres, calculado ()
Toma una función getter y devuelve un objeto ref reactivo de solo lectura . El ref .value
expone el valor de retorno de la función getter a través de . También puede aceptar un objeto con get
y set
funciones para crear un objeto de referencia de escritura.
-
tipo
// 只读 function computed<T>( getter: () => T, // 查看下方的 "计算属性调试" 链接 debuggerOptions?: DebuggerOptions ): Readonly<Ref<Readonly<T>>> // 可写的 function computed<T>( options: { get: () => T set: (value: T) => void }, debuggerOptions?: DebuggerOptions ): Ref<T>
-
ejemplo
Cree una referencia de propiedad calculada de solo lectura:
const count = ref(1) const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // 2 plusOne.value++ // 错误
Cree una referencia de propiedad calculada de escritura:
const count = ref(1) const plusOne = computed({ get: () => count.value + 1, set: (val) => { count.value = val - 1 } }) plusOne.value = 1 console.log(count.value) // 0
depuración:
const plusOne = computed(() => count.value + 1, { onTrack(e) { debugger }, onTrigger(e) { debugger } })
4. solo lectura()
Toma un objeto (ya sea reactivo o simple) o una referencia y devuelve un proxy de solo lectura del valor original.
-
tipo
function readonly<T extends object>( target: T ): DeepReadonly<UnwrapNestedRefs<T>>
-
detalles
Los proxies de solo lectura son profundos: el acceso a cualquier propiedad anidada será de solo lectura. Su comportamiento de desenvolvimiento de ref es
reactive()
el mismo que , pero el valor desenvuelto es de solo lectura.Para evitar un comportamiento de conversión profundo, utilice en su lugar el método de lectura superficial () .
-
ejemplo
const original = reactive({ count: 0 }) const copy = readonly(original) watchEffect(() => { // 用来做响应性追踪 console.log(copy.count) }) // 更改源属性会触发其依赖的侦听器 original.count++ // 更改该只读副本将会失败,并会得到一个警告 copy.count++ // warning!
Cinco, efecto de reloj ()
Ejecute una función inmediatamente mientras realiza un seguimiento reactivo de sus dependencias y las vuelve a ejecutar cuando cambian las dependencias.
-
tipo
function watchEffect( effect: (onCleanup: OnCleanup) => void, options?: WatchEffectOptions ): StopHandle type OnCleanup = (cleanupFn: () => void) => void interface WatchEffectOptions { flush?: 'pre' | 'post' | 'sync' // default: 'pre' onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void } type StopHandle = () => void
-
detalles
El primer argumento es la función de efectos secundarios a ejecutar. El parámetro de esta función de efecto secundario también es una función que se utiliza para registrar la devolución de llamada de limpieza. La devolución de llamada de limpieza se llamará antes de la próxima ejecución del efecto secundario y se puede usar para limpiar efectos secundarios no válidos, como solicitudes asincrónicas pendientes (consulte el ejemplo a continuación).
El segundo parámetro es una opción opcional que se puede usar para ajustar el tiempo de descarga del efecto secundario o depurar la dependencia del efecto secundario.
El valor de retorno es una función utilizada para detener el efecto secundario.
-
ejemplo
const count = ref(0) watchEffect(() => console.log(count.value)) // -> 输出 0 count.value++ // -> 输出 1
Efectos secundarios eliminados:
watchEffect(async (onCleanup) => { const { response, cancel } = doAsyncWork(id.value) // `cancel` 会在 `id` 更改时调用 // 以便取消之前 // 未完成的请求 onCleanup(cancel) data.value = await response })
Detener al oyente:
const stop = watchEffect(() => { }) // 当不再需要此侦听器时: stop()
opciones:
watchEffect(() => { }, { flush: 'post', onTrack(e) { debugger }, onTrigger(e) { debugger } })
6. verPostEffect()
watchEffect()
flush: 'post'
Alias al usar la opción.
ejemplo, watchSyncEffect()
watchEffect()
flush: 'sync'
Alias al usar la opción.
Ocho, reloj ()
Escucha una o más fuentes de datos reactivas e invoca la función de devolución de llamada dada cuando cambia la fuente de datos.
-
tipo
// 侦听单个来源 function watch<T>( source: WatchSource<T>, callback: WatchCallback<T>, options?: WatchOptions ): StopHandle // 侦听多个来源 function watch<T>( sources: WatchSource<T>[], callback: WatchCallback<T[]>, options?: WatchOptions ): StopHandle type WatchCallback<T> = ( value: T, oldValue: T, onCleanup: (cleanupFn: () => void) => void ) => void type WatchSource<T> = | Ref<T> // ref | (() => T) // getter | T extends object ? T : never // 响应式对象 interface WatchOptions extends WatchEffectOptions { immediate?: boolean // 默认:false deep?: boolean // 默认:false flush?: 'pre' | 'post' | 'sync' // 默认:'pre' onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void }
Los tipos se simplifican para facilitar la lectura.
-
detalles
watch()
El valor predeterminado es la escucha diferida, es decir, la función de devolución de llamada solo se ejecuta cuando cambia la fuente de escucha.El primer parámetro es la fuente del oyente . Esta fuente puede ser cualquiera de las siguientes:
- una función que devuelve un valor
- un árbitro
- un objeto receptivo
- ...o una matriz de valores de los tipos anteriores
El segundo parámetro es una función de devolución de llamada que se llamará cuando se produzca un cambio. Esta función de devolución de llamada toma tres argumentos: el valor nuevo, el valor anterior y una función de devolución de llamada para registrarse para la limpieza de efectos secundarios. Se llamará a esta función de devolución de llamada antes de que el efecto secundario se vuelva a ejecutar la próxima vez y se puede usar para eliminar los efectos secundarios no válidos, como las solicitudes asincrónicas pendientes.
Al escuchar varias fuentes, la función de devolución de llamada acepta dos matrices, una para el valor nuevo y otra para el valor anterior en la matriz de origen.
El tercer argumento opcional es un objeto que admite las siguientes opciones:
immediate
: La devolución de llamada se activa inmediatamente cuando se crea el oyente. El valor anterior es cuando se llama por primera vezundefined
.deep
: si la fuente es un objeto, fuerza un recorrido profundo para que las devoluciones de llamada se activen en cambios de nivel profundo. Consulte la sección Oyentes profundos .flush
: ajuste el tiempo de actualización de la función de devolución de llamada. Consulte la sección sobre el tiempo de actualización de las devoluciones de llamada .onTrack / onTrigger
: Dependencia del detector de depuración. Consulte la sección sobre Depuración de oyentes .
watchEffect()
Comparado conwatch()
nos permite:- ejecutar perezosamente los efectos secundarios;
- Está más claro qué estado debe hacer que el oyente vuelva a ejecutar;
- Puede acceder a los valores anteriores y actuales del estado que se está escuchando.
-
ejemplo
Escuche una función getter:
const state = reactive({ count: 0 }) watch( () => state.count, (count, prevCount) => { /* ... */ } )
Escuche una referencia:
const count = ref(0) watch(count, (count, prevCount) => { /* ... */ })
Al escuchar múltiples fuentes, la función de devolución de llamada acepta dos matrices, correspondientes a los valores nuevos y antiguos en la matriz fuente:
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { /* ... */ })
Cuando se usa una función getter como fuente, la devolución de llamada solo se activará cuando cambie el valor de retorno de la función. Si desea que la devolución de llamada se active incluso en cambios profundos, debe usar
{ deep: true }
forzar al oyente en modo profundo. Cuando está en modo profundo, si la función de devolución de llamada se activa debido a un cambio profundo, entonces el nuevo valor y el valor anterior serán el mismo objeto.const state = reactive({ count: 0 }) watch( () => state, (newValue, oldValue) => { // newValue === oldValue }, { deep: true } )
Al escuchar directamente un objeto reactivo, el oyente habilita automáticamente el modo profundo:
const state = reactive({ count: 0 }) watch(state, () => { /* 深层级变更状态所触发的回调 */ })
watch()
watchEffect()
Tiene el mismo tiempo de actualización y opciones de depuración que :watch(source, callback, { flush: 'post', onTrack(e) { debugger } })