Incluir JavaScript nativo en Vue

Video thumbnail

Como te he comentado en varias oportunidades, la aplicación de Academia (disponible en https://academy.desarrollolibre.net/) está construida con Laravel para el backend (API) y Vue para el frontend (SPA).

Quiero mostrarte una funcionalidad curiosa: el visor de libros.

Quiero mostrarte una funcionalidad curiosa: el visor de libros.

En el visor, la barra lateral muestra los subtítulos (encabezados H2) de un capítulo. Al hacer clic en uno, la página se desplaza automáticamente hasta esa sección.

Aquí te lanzo una pregunta: Si estás implementando una aplicación completamente en Vue, ¿cómo resolverías esta navegación interna? Me gustaría que dejaras tu idea en los comentarios.

Vue vs. JavaScript Nativo para la Manipulación del DOM

Vue es excelente para la manipulación de la página (DOM) y para crear Aplicaciones de Página Única (SPA). Es ideal para manejar eventos de usuario, mostrar elementos animados y gestionar la navegación reactiva. Lo mismo aplica a Angular y React.

Sin embargo, a veces, la presentación de datos (como la navegación interna basada en contenido ya renderizado) puede ser menos sencilla si intentas resolverlo únicamente con las herramientas reactivas del framework.

No digo que no se pueda hacer en Vue; seguramente hay plugins o formas de buscar las referencias. Pero en este caso, opté por una solución más simple y robusta: JavaScript nativo.

️ Implementación con JavaScript Nativo y Vue

La dificultad principal aquí es que Vue no tiene una referencia directa al contenido del libro. El texto completo del capítulo se carga como una cadena HTML desde la base de datos y se vuelca directamente en la página mediante un div:

<div v-html="html_desde_la_db"></div>

Dado que Vue no gestiona este contenido directamente, es el escenario perfecto para usar JavaScript nativo para obtener las referencias del DOM y luego usar Vue para iterar y gestionar el evento de clic.

1. Obtención de los Encabezados (H2)

La clave es usar document.querySelectorAll() para seleccionar los encabezados H2 dentro del contenedor principal del contenido (.post):

getHxs() {
  this.hxs = []
  setTimeout(() => {
    // JS nativo para obtener todos los H2 en el DOM
    this.hxs = document.querySelectorAll(".post h2")
  }, 500) // Se usa setTimeout para asegurar que el contenido se haya renderizado
}

Esta función almacena los elementos H2 reales del DOM en la variable hxs.

2. Iteración en Vue y el Evento de Clic

Una vez que hxs contiene el array de elementos DOM, Vue lo utiliza para construir la barra lateral:

<p v-for="h in hxs" :key="h" class="cursor-pointer m-0 hover:text-white"
 @click="h.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' })">
 {{ h.innerText }}
</p>

Utilizamos v-for para iterar el array hxs (construido con JS nativo).

Usamos h.innerText (JS puro) para obtener el texto del encabezado como título en la barra lateral.

3. Función scrollIntoView()

Para la parte del scroll, empleamos el método nativo de JavaScript scrollIntoView(). Este método se llama sobre la referencia del elemento DOM (h) y mueve la vista de la página hacia él.

  • h.scrollIntoView(...): Mueve el scroll a la posición del elemento.
  • behavior: 'smooth': Hace que el desplazamiento sea animado.
  • block: 'start': Coloca el elemento al inicio (parte superior) del área visible.

Esto demuestra que puedes integrar cápsulas de JavaScript nativo dentro de tus aplicaciones Vue, React o Angular para resolver funcionalidades del DOM que de otra forma serían complicadas o requerirían la búsqueda de un plugin externo.

Acepto recibir anuncios de interes sobre este Blog.

Aprende a combinar Vue.js con JavaScript nativo para una manipulación del DOM eficiente. Descubre cómo crear una navegación interna con scroll suave usando scrollIntoView() para mejorar tus aplicaciones, ¡sin necesidad de plugins externos!

| 👤 Andrés Cruz

🇺🇸 In english