# Refs
Esta sección utiliza la sintaxis de componentes de un solo archivo para ejemplos de código
# ref
Toma un valor interno y retorna un objeto reactivo y mutable de ref. El objeto de ref tiene una sola propiedad .value
que apunta al valore interno.
Ejemplo:
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
2
3
4
5
Si un objeto es asignado como el valor de una ref, el objeto se hace reactivo profundamente por la función reactive.
Tipar:
interface Ref<T> {
value: T
}
function ref<T>(value: T): Ref<T>
2
3
4
5
Algunas veces necesitaríamos especificar tipos complejos para un valor interno de una ref. Podemos hacerlo sucintamente mediante pasar un argumento genérico cuando llame ref
para sobreescribir la inferencia por defecto:
const foo = ref<string | number>('foo') // el tipo de foo: Ref<string | number>
foo.value = 123 // ok!
2
3
Si el tipo del genérico es desconocido, es recomendable fundir ref
a Ref<T>
:
function useState<State extends string>(initial: State) {
const state = ref(initial) as Ref<State> // state.value -> State extiende string
return state
}
2
3
4
# unref
Retorna el valor interno si el argumento es una ref
, de lo contrario retorna el argumento mísmo. Este es una función súgar para val = isRef(val) ? val.value : val
.
function useFoo(x: number | Ref<number>) {
const unwrapped = unref(x) // unwrapped está garantizado para ser un número ahora
}
2
3
# toRef
Puede ser utilizado para crear una ref
para una propiedad en un objeto reactivo original. La ref puede luego ser pasada libremente, reteniendo la conexión a su propiedad original.
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
fooRef.value++
console.log(state.foo) // 2
state.foo++
console.log(fooRef.value) // 3
2
3
4
5
6
7
8
9
10
11
12
toRef
es útil cuando quiere pasar la ref de una prop a una función de composición:
export default {
setup(props) {
useSomeFeature(toRef(props, 'foo'))
}
}
2
3
4
5
toRef
retornará una ref utilizable incluso si la propiedad original no existe en la actualidad. Este lo hace específicamente útil cuando se trabaja con props opcionales, las que no serían recogidas por toRefs
.
# toRefs
Covierte un objeto reactivo a un objeto plano dónde cada propiedad del objeto resultante es una ref
que apunte a la propiedad correspondiente del objeto original.
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
Tipo de stateAsRefs:
{
foo: Ref<number>,
bar: Ref<number>
}
*/
// La ref y la propiedad original son "vinculadas"
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
toRefs
es útil cuando retorna un objeto reactivo desde una función de composición para que el componente que consume las refs pueden desestructurar/extender el objeto retornado sin perder la reactividad:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// operación lógica en _state_
// convertirlo a refs al tiempo de retornarlo
return toRefs(state)
}
export default {
setup() {
// puede desestructurarse sin perder reactividad
const { foo, bar } = useFeatureX()
return {
foo,
bar
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
toRefs
solo generará refs
para propiedades que son incluidas en el objeto original. Para crear una ref para una propiedad específica, utilice toRef
en su lugar.
# isRef
Comprueba si un valor es un objeto de ref.
# customRef
Crea una ref personalizada con control explícito sobre su seguimiento de dependencias y el disparar de actualizaciones. Espera una función de factoría, la que recibe funciones track
y trigger
como argumentos y debe retornar un objeto con get
y set
.
Ejemplo que utiliza una ref personalizada para implementar debounce con
v-model
:<input v-model="text" />
1function 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) } } }) } export default { setup() { return { text: useDebouncedRef('hello') } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tipar:
function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
type CustomRefFactory<T> = (
track: () => void,
trigger: () => void
) => {
get: () => T
set: (value: T) => void
}
2
3
4
5
6
7
8
9
# shallowRef
Crea una ref que rastrea su propia mutación de .value
pero no lo hace reactivo a su valor.
const foo = shallowRef({})
// mutar el valor de la ref es reactivo
foo.value = {}
// pero el valor no será convertido.
isReactive(foo.value) // false
2
3
4
5
Vea también: crear valores reactivos independientes como refs
# triggerRef
Ejecuta cuaqlquieres efectos vinculados a shallowRef
manualmente.
const shallow = shallowRef({
greet: 'Hola, mundo'
})
// registra "Hola, mundo" una vez para la primera ejecución
watchEffect(() => {
console.log(shallow.value.greet)
})
// Este no disparará el efecto porque la ref es _shallow_
shallow.value.greet = 'Hola, universo'
// registra "Hola, universo"
triggerRef(shallow)
2
3
4
5
6
7
8
9
10
11
12
13
14
Vea también: computed y watch - watchEffect