Aunque gracias a la reactividad de Vue puedes centrarte en el modelo (la información) de tu aplicación y dejar que él se encargue de mantener todo actualizado, en ocasiones necesitarás acceder al DOM para manipularlo. Para logarlo, tienes dos opciones: crear una directiva o acceder a través de referencias de plantilla (template refs).
Hoy exploraremos la segunda opción utilizando la Composition API, ya que el proceso es sensiblemente diferente a la Options API.
Crear un template ref
Para acceder a un elemento del DOM y manipularlo desde la instancia Vue, debes de crear una referencia reactiva con
valor nulo, y luego asociarla al elemento que necesites con el atributo ref
.
<script setup>
import { ref, onMounted } from "vue"
const formRef = ref(null)
</script>
<template>
<form ref="formRef">...</form>
</template>
Acceder a un template ref
Con la referencia creada y asociada, podemos esperar a que el componente esté montado para acceder al interior del elemento DOM que tiene la referencia.
<script setup>
...
onMounted(()=> {
formRef.value.submit() // Enviamos el formulario
})
</script>
Template refs y v-for
Un caso especial puede darse si quieres crear un template ref dentro de v-for
. En esta situación debes crear una
referencia reactiva con un array vacío (en lugar de null
) y dejar que Vue actualice cada elemento con el valor del DOM
adecuado.
<script setup>
import { ref } from "vue"
const items = ref([...])
const itemsRef = ref([])
</script>
<template>
<ul>
<li ref="itemsRef" v-for="item in items">...</li>
</ul>
</template>
¿Para qué puedo necesitar algo así?, quizás te estés preguntando. Un escenario sería el uso de
la Intersection Observer API: imagina que
quieres ser notificado cuando el último item
hace intersección con el viewport.
<script setup>
...
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting()) {
console.log("👋")
}
})
})
// Observamos el último item
observer.observe(itemsRef[itemsRef.length - 1])
</script>
Resumiendo
Cuando necesites manipular directamente el DOM, crea una referencia reactiva y asóciala al elemento al que quieras acceder. Una vez se haya cargado tendrás todo lo que necesitas dentro de la nueva template ref.