En este post, os daré una breve introducción sobre Nuxt, su funcionamiento y sus funcionalidades más básicas con una pequeña aplicación. Pero, ¿por qué querríamos usar este framework y no Vue directamente?

Logo de Nuxt.js

¿Por qué Nuxt?

Vue utiliza lo que se conoce como CSR o client-side rendering. Esto implica que JavaScript renderizará todo el contenido estático e interactivo de nuestra página. Sin embargo, esto trae dos problemas principales:

  • SEO: como nuestro contenido es renderizado en el cliente, los bots de los motores de búsqueda no podrán indexar nuestra página
  • Rendimiento: si cargamos una gran cantidad de información o la conexión del usuario es lenta, nuestra página cargará lentamente, afectando a la experiencia del usuario

Para solucionar esto tenemos Nuxt, el framework de Vue (es decir, un meta-framework) que nos permitirá crear aplicaciones full-stack más potentes y completas.

Su característica principal se basa en su motor Nitro, que utiliza universal rendering para nuestro proyecto. Es decir, usa tanto client-side rendering como SSR o server-side rendering. El servidor será el que generará el contenido estático (HTML) de nuestra página. Al acabar, le dará el control a JavaScript, que acabará con el renderizado del contenido interactivo restante. A esta última parte también se le conoce como hydration.

Instalación y directorios

Para empezar, ejecutamos el primer comando para crear nuestro proyecto. Tras instalar Nuxt y el resto de dependencias, vamos a la carpeta del proyecto. Ejecutamos npm run dev para iniciar nuestra aplicación (que se abrirá en localhost:3000).

npx nuxi@latest init <nombre-proyecto>
npm run dev

Sin embargo, al entrar en la carpeta del proyecto desde un IDE, veremos bastantes diferencias respecto a una aplicación de Vue. No hay index.html dentro de public, ni hay main.js, ni tenemos la carpeta src…

Sistema de carpetas de una aplicación nueva de Nuxt

Esto se debe a que Nuxt tiene un sistema especial de directorios, y cada uno tiene una funcionalidad distinta. Nos centraremos sólamente en /components y /pages, pero entre los directorios principales se encuentran:

Nombre del directorioFuncionalidad
/componentsComponentes fijos o reutilizables, como pueden ser un header o un botón
/pagesComponentes que dependen de la ruta, también conocidos como páginas
/layoutsComponentes que cambian el diseño de la página
/composablesMétodos que usaremos en el <script> de nuestros componentes
/pluginsPiezas de código que se cargarán automáticamente.
Por ejemplo, yo lo uso para cargar la parte de lógica de Bootstrap.
Para ello, instalamos Bootstrap, creamos un archivo llamado useBootstrap.client.js dentro de plugins y ponemos el siguiente código:
import bootstrap from «bootstrap/dist/js/bootstrap.bundle»;
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.provide(«bootstrap», bootstrap);
});

Como veis en esta tabla, los componentes de toda la vida pasan a dividirse en components, pages o layouts. Además de estos directorios, hay muchos más los cuales podemos consultar en la documentación.

nuxt.config.ts

Pero vamos paso a paso. Aquí tenéis una mini aplicación de prueba que he hecho con Nuxt y que usaremos para guiarnos durante el post. El primer archivo en el que nos fijaremos es nuxt.config.ts. Aquí podremos cambiar la configuración del proyecto o importar archivos CSS o JS/TS o módulos, los cuáles nos ayudan a extender las funcionalidades de nuestra aplicación.

Código del nuxt.config.ts del proyecto

Por ejemplo, yo configuro el proyecto para usar estilos de Bootstrap, para aplicar transiciones y para usar dos módulos: uno para optimizar imágenes y otro para poder usar fuentes de Google Fonts.

app.vue

El otro archivo en el que nos fijaremos será app.vue. Como en Vue, será el componente principal del proyecto. No obstante, vemos algunas diferencias importantes respecto a Vue.

Código del app.vue

Components especiales de Nuxt

También vemos una etiqueta llamada <NuxtPage>. Este framework nos aporta una serie de componentes que tendremos que utilizar en sustitución de otros. Los principales son los siguientes:

VueNuxt
<img><NuxtImg> o <NuxtPicture>
<router-view><NuxtPage>
<router-link><NuxtLink>

Es decir, la etiqueta que vemos es el equivalente a un <router-view>. Esto es debido ya sea por optimización (mejor rendimiento para nuestra página) o por funcionalidad (su alternativa de Vue no está pensada para Nuxt).

Auto-imports

Por último, vemos que importamos un componente llamado <MenuComponent>. Sin embargo, no vemos que éste sea importado en ninguna parte de app.vue. Esto es debido a una de las funcionalidades más importantes del framework: los auto-imports.

No solo cualquier método o variable de Vue o de Nuxt no necesitará de un import sino que, además, los métodos que creemos en /composables o los componentes que creemos en /components también se importarán de manera automática en todo nuestro proyecto.

Componentes

Tenemos un MenuComponent en /components, una barra de navegación, indicándonos que este componente es fijo. Como hemos mencionado antes, cualquier componente del directorio /components podrá ser utilizado en todo el proyecto sin importarlo. Si nos fijamos en la siguiente captura, podemos apreciar más diferencias respecto de Vue.

Componente MenuComponent

Como ya mencionamos anteriormente, en vez de usar la etiqueta <img>, usamos <NuxtImg> que nos proporcionará una optimización automática de las imágenes que usemos. Además, todas nuestras imágenes estáticas tendrán que ir dentro de /public (o en /public/images) para que funcionen correctamente. También cambiamos <router-link> por <NuxtLink> para trabajar directamente con el router de Nuxt.

Composition API

Los componentes en Nuxt usan la Composition API, creada en Vue3 y más parecida al código de un componente de React. Lo normal es que en vez de la Composition API hayas usado la Options API, la forma tradicional de trabajar en Vue basada en zonas como data, mounted, methods o computed.

Con esta API podemos crear una lógica más flexible y simple en nuestros componentes, importando las funciones que necesitemos de la API, como pueden ser ref para variables reactivas, reactive para objetos reactivos, onMouted como equivalente a mounted o useRoute para extraer parámetros de la ruta.

Ejemplo en Options APIEjemplo en Composition API
<script>
export default {
data() {
return {
num: 0
}
},
methods: {
incrementar() {
this.num++
}
}
}
</script>
<script setup>
const num = ref(0)
const incrementar = () => num.value++
</script>

En la anterior tabla vemos la comparación de un contador de un número en ambas APIs. Normalmente tendríamos que importar las funciones de Vue y de Nuxt como puede ser el ref, pero los auto-imports de Nuxt nos ahorramos este paso.

Data fetching

Aunque podríamos usar axios o fetch, Nuxt nos proporciona un composable (es decir, una función que usaremos en Composition API) para manejar nuestras peticiones conocida como useFetch(). Recordemos que al ser una función de Nuxt, no hace falta importarla.

GET con el composable useFetch()

En mi caso, quiero coger todas las armas de una API de Valorant y meterlas en unos <option> para un select. Para ello, solo tendremos que usar useFetch de forma asíncrona con la URL de nuestra petición como parámetro. La respuesta que nos devolverá es la data.

La sintaxis que uso nos permite asignar los datos que nos devuelve la petición a una variable llamada armas sin ni siquiera declararla con ref. De esta forma, tenemos una simple petición GET en una sola línea de código.

El useFetch es muy parecido al fetch en el sentido en el que si queremos hacer un POST o un PUT tenemos que poner un body, un method, etc. En esta aplicación solo hay peticiones GET por como funciona la API que uso, pero si tenemos alguna duda podemos consultar la página de la documentación sobre el useFetch.

Páginas y routing de Nuxt

Aunque podemos crear nuestro propio router como en una aplicación corriente de Vue, Nuxt nos proporciona su propio routing basado en un sistema de ficheros. Los componentes en este sistema se crearán con index.vue y serán denominados páginas.

Sistema de páginas del proyecto

Normalmente, el enrutador de un proyecto en Vue tendrá que tener una lista de rutas. Si yo quisiera mostrar los datos de cada arma, tendría que poner algo en el path como «/arma/:id» y en component el componente correspondiente.

Todo esto podemos ahorrárnoslo con el sistema de Nuxt. Como vemos en la captura, para hacer el mismo ejemplo de las armas, solo tengo que:

  • Crear una carpeta /arma dentro de /pages
  • Crear una carpeta [id] dentro de /arma
  • Crear un fichero index.vue dentro de [id], nuestra página

De esta forma, tendremos nuestra ruta ya creada de manera muy simple (/arma/[id]). Obviamente, también podemos crear páginas con varios parámetros, sin parámetros o incluso con path «/» (creando el index.vue directamente en la carpeta pages)

La captura corresponde al código lógico de la página de armas. Os lo muestro para que veáis que podemos meter parámetros a la URL del useFetch con query, y para que veáis que usaré el composable useRoute en vez de this.$route para sacar la ID del arma y usarla en la URL del useFetch.

Los códigos de las páginas de mapas y de agentes son muy parecidos, así que no hace falta realmente que os lo enseñe. Podéis comprobarlo en el GitHub del proyecto que se encuentra abajo del todo del post.

SEO

Si queremos optimizar el SEO de nuestra página, Nuxt nos proporciona componentes como <Head>, <Title>, <Body> o <Meta>, los cuales nos permiten interactuar no solo directamente con los metadatos de la plantilla de nuestra página, sino además de forma reactiva (uso en los metadatos una variable reactiva titulo declarada en el código de la página de armas y podría cambiar su valor en cualquier momento).

Final

Con todo lo explicado, podemos realizar una aplicación relativamente simple como la mía con la potencia de Nuxt y la interactividad de Vue. Sin embargo, hay otros conceptos más avanzados que no he explicado como pueden ser:

Si tuviéramos alguna otra duda sobre alguna característica o funcionalidad de Nuxt, siempre podemos consultar la documentación, que es probablemente de las mejores documentaciones que os podéis encontrar en la comunidad del desarrollo.

Como veis, las posibilidades que nos ofrece Nuxt son muchísimas, y esto es precisamente lo que hace a este framework una opción a tener en cuenta para realizar nuestras aplicaciones full-stack.

Autor: Alejandro López Labajo

Curso: Desarrollo Web Full Stack + MultiCloud con Azure y AWS

Centro: Tajamar Tech

Año académico: 2023-2024

Recursos: Enlace a Github, Documentación, Aplicación desplegada, LinkedIn

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.