Empezando con Nuxt
Los desarrolladores a menudo se preocupan por el SEO de sus SPA (aplicaciones de página única) y qué tan bien les iría en las búsquedas de Google (blogs, sitios web de cartera, sitios web de productos, etc.). A veces, también les preocupa lo complejo que puede ser crear una aplicación renderizada del lado del servidor. En este tutorial, aprenderemos cómo crear aplicaciones renderizadas del lado del servidor usando Nuxt.js, cómo configurar su aplicación para el desarrollo y cómo implementarla en Heroku.
Los desarrolladores web crean muchas aplicaciones de una sola página utilizando marcos de JavaScript (Angular, React, Vue). Los SPA completan dinámicamente el contenido de sus páginas durante la carga, lo que significa que cuando Google rastrea su sitio, el contenido importante aún no se ha inyectado en el sitio. Parte de este problema se puede resolver renderizando previamente el contenido de su aplicación. Aquí es donde entran las aplicaciones del lado del servidor y, para los desarrolladores de Vuejs, podemos crear aplicaciones del lado del servidor utilizando Nuxt.js.
Vamos a asumir que no lo ha usado antes, por lo que comenzará desde cero: le presentará Nuxt.js, su estructura de archivos y cómo funciona el enrutamiento. Al mismo tiempo que menciona cómo puede hacer que funcione con Vuex.
Al final de este tutorial, debería poder continuar con la creación de aplicaciones web básicas en Nuxt.js, y si se pregunta cómo comenzar con Nuxt.js, esto le hará justicia.
Este artículo está dirigido a aquellos que están bastante familiarizados con Vue.js y es un concepto. Para aquellos sin conocimiento de Vue.js, considere comenzar con la documentación oficial de Vuejs y la lista de reproducción Vuejs de The Net Ninja .
¿Qué es Nuxt.js?
Según su página oficial :
“Nuxt es un marco progresivo basado en Vue.js para crear aplicaciones web modernas. Se basa en las bibliotecas oficiales de Vue.js (vue, vue-router y vuex) y potentes herramientas de desarrollo (webpack, Babel y PostCSS). El objetivo de Nuxt es hacer que el desarrollo web sea potente y eficaz teniendo en mente una gran experiencia de desarrollador”.
Permite crear tres tipos de aplicaciones, según la finalidad a la que esté destinada:
-
Páginas generadas estáticas (preprocesamiento)
Las aplicaciones generadas estáticas no requieren solicitudes de API para recuperar el contenido de las páginas, es decir, el contenido ya está incluido en el archivo HTML. Un ejemplo de un sitio estático es un sitio web de cartera o una página de destino para un producto. -
Aplicación de una sola página
La mayoría de los marcos de JavaScript (React, Angular, Emberjs, Vue, etc.) son aplicaciones de una sola página cuyo contenido se completa dinámicamente con transiciones más rápidas. La mayoría de los SPA utilizan la API de historial HTML5 o el Hash de ubicación para el enrutamiento. -
Aplicaciones renderizadas del lado del servidor (SSR)
La renderización del lado del servidor es una técnica utilizada para buscar y mostrar datos del lado del cliente en el servidor para enviar una página completamente renderizada al cliente. Este es un buen enfoque para conseguir un buen SEO para su aplicación.
Creando su primera aplicación Nuxt.js
Puede crear una aplicación Nuxt.js de dos maneras:
- Usando la herramienta de andamio
create-nuxt-app
. - Desde cero.
En caso de que solo desee ver la aplicación terminada que estaríamos creando, aquí tiene un enlace al repositorio de GitHub .
En este tutorial, nos centraremos en el uso, create-nuxt-app
así que comencemos. Si tiene npx instalado, abra su terminal y ejecute este comando:
$ npx create-nuxt-app nuxt-tutorial-app
o
$ yarn create nuxt-app nuxt-tutorial-app
Para los fines de este tutorial, nuxt-tutorial-app
es el nombre de la aplicación, pero siéntete libre de nombrar la tuya de manera diferente.
A esto le seguiría una lista de opciones que le ayudarán a configurar su aplicación con lo que podría necesitar para el desarrollo.
Así es como se ve mi configuración:
Para los fines de este tutorial, no necesitamos configuraciones de axios, linting y Prettier.
Una vez hecho esto, ejecutaremos el siguiente comando en nuestra terminal:
$ cd nuxt-tutorial-app$ npm run dev
Su aplicación ahora debería estar ejecutándose en https://localhost:3000 y esto es lo que debería ver:
En este punto, su aplicación está lista para su desarrollo.
Comprender la estructura de carpetas de Nuxt
Al aplicar scaffolding a la aplicación como lo hicimos nosotros, se crean diferentes archivos y carpetas con los que podemos comenzar a trabajar. Para alguien que no ha trabajado antes con Nuxt, esto podría desequilibrarlo. Así que veremos las carpetas y comprenderemos su importancia.
- Activos
Esta carpeta es para archivos no compilados, como imágenes, archivos de fuentes, archivos SASS, LESS o JavaScript. Agreguemos, creemos unastyles
carpeta y unmain.css
archivo y copiemos y peguemos lo siguiente en él.
a { text-decoration: none; color: inherit; cursor: pointer;}.header { width: 100%; max-width: 500px; margin-left: auto; margin-right: auto; height: 60px; top: 0; position: sticky; background-color: #fff; display: flex; justify-content: space-between; align-items: center;}.logo { width: 40%; max-width: 200px; height: 40px;}.logo .NuxtLogo { max-width: 30px; margin-left: 10px; max-height: 40px;}.nav { width: 60%; height: 40px; display: flex; justify-content: space-between; padding-right: 10px; max-width: 300px;}.nav__link { width: 80px; display: flex; align-items: center; border-radius: 4px; justify-content: center; height: 100%; border: 1px solid #00c58e; cursor: pointer;}.nav__link:active { background-color: #00c58e; border: 1px solid #00c58e; color: #fff; box-shadow: 5px 3px 5px 2px #3f41468c;}.home { padding-top: 30px;}.home__heading { text-align: center;}.directories { display: flex; box-sizing: border-box; padding: 10px; max-width: 1000px; margin: 0 auto; flex-wrap: wrap; justify-content: center;}@media (min-width: 768px) { .directories { justify-content: space-between; }}.directory__container { width: 100%; max-width: 220px; cursor: pointer; border-radius: 4px; border: 1px solid #00c58e; display: flex; height: 60px; margin: 10px 5px; margin-right: 0; justify-content: center; align-items: center;}.directory__name { text-align: center;}.directory { width: 100%; margin: 50px auto; max-width: 450px; border-radius: 4px; border: 1px solid #00c58e; box-sizing: border-box; padding: 10px 0;}.directory__info { padding-left: 10px; line-height: 22px; padding-right: 10px;}
Los estilos anteriores se utilizarán en toda la aplicación para lo que crearemos. Como puede ver, tenemos estilos para la navegación y otros aspectos que incorporaremos a la aplicación a medida que avancemos.
- Componentes
Esta carpeta es una que conocemos de Vue.js y contiene sus componentes reutilizables.
Ahora, creemos nuestro primer componente, le asignamos un nombre navBar.vue
y le agregamos el siguiente código. Queremos que la barra de navegación del sitio muestre el logotipo y enlace a las páginas Inicio y Acerca de que crearemos en el futuro. Esta barra de navegación será visible en toda la aplicación. También hará uso de algunos estilos que hemos agregado anteriormente.
template header div nuxt-link to="/" Logo / /nuxt-link /div nav div nuxt-link to="/"Home/nuxt-link /div div nuxt-link to="/About"About/nuxt-link /div /nav /header/templatescriptimport Logo from "@/components/Logo";export default { name: "nav-bar", components: { Logo }};/scriptstyle/style
La sección de plantilla contiene lo que será visible para el usuario. Tenemos un header
elemento que contiene nuestro logotipo y enlaces de navegación. Para que podamos vincularnos a las páginas, utilizamos nuxt-link
las cuales proporcionan navegación entre las páginas componentes.
En la sección de script, importamos el logo
componente usando el alias de Nuxt @
y lo declaramos en nuestro componente para usarlo agregándolo como componente. Esto nos permite renderizarlo en la plantilla.
- Diseño
Aquí almacenaremos los diseños de nuestra aplicación. Esto es particularmente útil si el diseño de su aplicación requiere dos o más diseños, por ejemplo, uno para usuarios autenticados y otro para invitados o administradores. A los efectos de este tutorial, nos ceñiremos al diseño predeterminado.
Abramos nuestro default.vue
archivo y agreguemos nuestro navBar
componente al diseño de nuestra aplicación.
template div Nav / nuxt / /div/templatescriptimport Nav from "~/components/navBar.vue";export default { components: { Nav }};/script
En la sección de plantilla, agregamos nuestro Nav
componente dentro del contenedor de diseño para que siempre aparezca en la parte superior después de importarlo al archivo y declararlo en la sección de secuencia de comandos.
Lo siguiente después de nuestro Nav
componente es nuxt /
, que le indica a Nuxt dónde representar todas sus rutas.
Este Nav
componente es el que creamos arriba. Al agregarlo aquí, el Nav
componente se utilizará en toda la aplicación.
-
Middleware
Esta carpeta se creó para albergar archivos JavaScript que deben ejecutarse antes de que se procesen una página. Si alguna vez usó el protector de navegación de Vuejs , esta carpeta se creó para archivos como ese. -
Páginas
Esta es otra carpeta con la que los desarrolladores con experiencia en Vuejs no estarían familiarizados. Funciona de tal manera que cada*.vue
archivo se crea como una ruta en su aplicación, por lo que sirve como vista y carpeta de enrutador al mismo tiempo; hablaremos más sobre esto en la siguiente sección. -
Complementos
Aquí es donde almacena los archivos que desea ejecutar antes de montar la aplicación raíz Vue.js. No es una carpeta obligatoria por lo que se puede eliminar. -
nuxt.config.js
Este archivo se utiliza para configurar su aplicación; generalmente se completa previamente según la configuración al crear su aplicación. Un archivo nuxt.config.js ideal debería verse así de forma predeterminada:
export default { mode: 'universal', /* ** Headers of the page */ head: { title: process.env.npm_package_name || '', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } ] }, /* ** Customize the progress-bar color */ loading: { color: '#fff' }, /* ** Global CSS */ css: [ ], /* ** Plugins to load before mounting the App */ plugins: [ ], /* ** Nuxt.js dev-modules */ buildModules: [ ], /* ** Nuxt.js modules */ modules: [ ], /* ** Build configuration */ build: { /* ** You can extend webpack config here */ extend (config, ctx) { } }}
Cada vez que se realiza un cambio en este archivo, su aplicación se reiniciará automáticamente para reflejar los cambios. Repasemos qué significan las propiedades utilizadas en el archivo.
- Modo
El tipo de aplicación; Cualquierauniversal
ospa
. Al seleccionar universal, le estás diciendo a Nuxt que quieres que tu aplicación pueda ejecutarse tanto en el lado del servidor como en el del cliente. - Head
Todas las propiedades de metaetiquetas predeterminadas y el enlace de favicon que se encuentran dentro de lahead
etiqueta en su aplicación se encuentran aquí. Esto se debe a que Nuxt.js no tiene unindex.html
archivo predeterminado, a diferencia de Vue.js. - cargar
Todas las aplicaciones de Nuxt vienen con un componente de carga predeterminado y secolor
pueden personalizar aquí. - css
Se espera que ingrese el enlace a todos sus archivos CSS globales para que su aplicación pueda tenerlo en cuenta al montar la aplicación. Agregaremos el enlace a nuestro archivo css y reiniciaremos nuestra aplicación.
/* ** Global CSS */ css: ["~/assets/styles/main.css"]
- complementos
Aquí es donde conecta todos los complementos en su carpeta de complementos a la aplicación. Toma un objeto con propiedades tales comosrc
que acepta la ruta del archivo al complemento ymode
que configura cómo su aplicación trata dicho complemento; ya sea como complemento del lado del servidor o como complemento del lado del cliente. Por ejemplo:
{ src: '~/plugins/universal-plugin.js' }, // for server and client plugins{ src: '~/plugins/client-side.js', mode: 'client' }, // for client only plugins{ src: '~/plugins/server-side.js', mode: 'server' }, // for server side only plugins
Esto es importante para evitar errores tanto en el lado del servidor como en el del cliente, especialmente si su complemento requiere que algo así localStorage
no esté disponible en el lado del servidor.
Para obtener más información sobre el nuxt.config.js
archivo, consulte el documento oficial .
Páginas Nuxt y sistema de enrutamiento
La carpeta de páginas en su aplicación Nuxt se utiliza para configurar las rutas de su aplicación, es decir, el nombre de su ruta depende del nombre de cada archivo en esta carpeta, por ejemplo, si tiene un about.vue
archivo dentro de su archivo de páginas, significa que ahora tiene una /about
ruta en tu aplicación, pero eso no es todo. ¿Qué sucede si desea una ruta dinámica para su aplicación? ¿O una ruta anidada? ¿Cómo lo haces? vamos a averiguar.
Rutas Básicas
Las rutas básicas se pueden clasificar como rutas que no requieren configuración adicional para funcionar. Por ejemplo, una ruta directa /work
o una /contact
ruta. Entonces, si su carpeta de páginas se ve así:
pages/--| me/ -----| index.vue -----| about.vue--| work.vue--| contact.vue--| index.vue
Nuxt generaría automáticamente una configuración de enrutador similar a esta:
router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'work', path: '/work', component: 'pages/work' }, { name: 'contact', path: '/contact', component: 'pages/contact' }, { name: 'me', path: '/me', component: 'pages/me/index.vue' }, { name: 'me-about', path: '/me/about', component: 'pages/me/about.vue' } ]}
Estas rutas se pueden utilizar para acceder a los componentes vinculados a ellas. Puedes ver que la ruta no contiene pages
. Y Nuxt maneja los componentes nombrados index.vue
como debería sin una configuración adicional para eso.
Rutas anidadas
Para crear una ruta anidada, cree una carpeta llamada panel dentro de la carpeta de páginas . Esta carpeta debe contener todos los archivos que desea anidar en ella. Por ejemplo, usuario.vue y configuración.vue . Luego, en la carpeta raíz de las páginas , cree un archivo llamado Dashboard.vue .
pages/ --| me/ -----| index.vue -----| about.vue --| dashboard/ -----| user.vue -----| settings.vue --| dashboard.vue --| work.vue --| contact.vue --| index.vue
Esto generaría automáticamente un enrutador con rutas como esta:
router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'work', path: '/work', component: 'pages/work' }, { name: 'contact', path: '/contact', component: 'pages/contact' }, { name: 'me', path: '/me', component: 'pages/me/index.vue' }, { name: 'me-about', path: '/me/about', component: 'pages/me/about.vue' }, { name: 'dashboard', path: '/dashboard', component: 'pages/dashboard.vue', children: [ { name: 'dashboard-user', path: '/dashboard/user', component: 'pages/dashboard/user.vue' }, { name: 'dashboard-settings', path: '/dashboard/settings', component: 'pages/dashboard/settings.vue' } ] } ]}
Observe que el nombre de la ruta siempre sigue un patrón regular:
name of the folder + '-' + name of the file
Con esto, puedes estar seguro de que cada ruta tendrá un nombre único.
Rutas dinámicas
Las rutas dinámicas son rutas definidas por una variable ; esta variable puede ser un nombre, un número o datos id
obtenidos de los datos del cliente en la aplicación. Esto resulta útil cuando se trabaja con una API, donde id
probablemente el id
elemento provenga de la base de datos.
En Nuxt, las rutas dinámicas se definen agregando un _
nombre de archivo o de carpeta en la carpeta de páginas. Por ejemplo, si desea una ruta dinámica cuyo nombre de variable sea id , todo lo que necesita es nombrar su archivo _id.vue
y Nuxt crea automáticamente una ruta dinámica para usted. Por ejemplo:
pages/--| me/-----| index.vue-----| about.vue-----| _routeName-------| index.vue-------| info.vue--| dashboard/-----| user.vue-----| settings.vue--| dashboard.vue--| work.vue--| _id.vue--| contact.vue--| index.vue
Esto crearía automáticamente un archivo de enrutador con las siguientes rutas,
{ name: 'work', path: '/work', component: 'pages/work' }, { name: 'contact', path: '/contact', component: 'pages/contact' }, { name: 'id', path: '/:id', component: 'pages/_id.vue' } { name: 'me', path: '/me', component: 'pages/me/index.vue' }, { name: 'me-about', path: '/me/about', component: 'pages/me/about.vue' }, { name: 'me-routeName', path: '/me/:routeName', component: 'pages/me/_routeName/index.vue' }, { name: 'me-routeName-info', path: '/me/:routeName/info', component: 'pages/me/route.vue' }, { name: 'dashboard', path: '/dashboard', component: 'pages/dashboard.vue', children: [ { name: 'dashboard-user', path: '/dashboard/user', component: 'pages/dashboard/user.vue' }, { name: 'dashboard-settings', path: '/dashboard/settings', component: 'pages/dashboard/settings.vue' } ] } ]}
Aunque algunas de las etiquetas del enrutador Vue.js funcionan en Nuxt y se pueden usar indistintamente, se recomienda que utilicemos componentes del enrutador Nuxt. Estas son algunas de las diferencias entre las etiquetas de Nuxt Router y las etiquetas de Vue.js Router.
VueJs | NuxtJS |
---|---|
enlace de enrutador | enlace nuxt |
vista de enrutador (para rutas anidadas) | niño-nuxt |
vista del enrutador (predeterminada) | nuxt |
Diferencia entre el enrutador vue.js y el enrutador nuxt.js
En este punto, así es como debería verse su aplicación, con la navegación mostrada en la parte superior.
Ahora que entendemos cómo funcionan las páginas y rutas de Nuxt, agreguemos nuestra primera página y ruta about.vue
. Esta página enumeraría algunos directorios en la aplicación con un enlace a una nueva página que muestra más información sobre dicho directorio.
Agreguemos el siguiente código:
template section h1About Nuxtjs Directory Structure/h1 div div v-for="directory in directories" :key="directory.id" p nuxt-link :to="{ name: 'id', params: { id: directory.id, dir: directory } }" {{ directory.name }}/nuxt-link /p /div /div /section/templatescriptexport default { name: "about-nuxt", data() { return { directories: [ { id: 0, name: "The Assets Directory", info: "By default, Nuxt uses vue-loader, file-loader and url-loader webpack loaders for strong assets serving. You can also use the static directory for static assets. This folder is for un-compiled files such as images, font files, SASS, LESS or JavaScript files" }, { id: 1, name: "The Components Directory", info: "The components directory contains your Vue.js Components. You can’t use asyncData in these components." }, { id: 2, name: "The Layouts Directory", info: "The layouts directory includes your application layouts. Layouts are used to change the look and feel of your page (for example by including a sidebar). Layouts are a great help when you want to change the look and feel of your Nuxt.js app. Whether you want to include a sidebar or having distinct layouts for mobile and desktop" }, { id: 3, name: "The Middleware Directory", info: "The middleware directory contains your Application Middleware. Middleware lets you define custom functions that can be run before rendering either a page or a group of pages (layouts)." }, { id: 4, name: "The Pages Directory", info: "The pages directory contains your Application Views and Routes. The framework reads all the .vue files inside this directory and creates the application router. Every Page component is a Vue component but Nuxt.js adds special attributes and functions to make the development of your universal application as easy as possible" }, { id: 5, name: "The Plugins Directory", info: "The plugins directory contains your Javascript plugins that you want to run before instantiating the root Vue.js Application. This is the place to register components globally and to inject functions or constants. Nuxt.js allows you to define JavaScript plugins to be run before instantiating the root Vue.js Application. This is especially helpful when using your own libraries or external modules." }, { id: 6, name: "The Static Directory", info: "The static directory is directly mapped to the server root (/static/robots.txt is accessible under https://localhost:3000/robots.txt) and contains files that likely won’t be changed (e.g. the favicon). If you don’t want to use Webpack assets from the assets directory, you can create and use the static directory (in your project root folder)." }, { id: 7, name: "The Store Directory", info: "The store directory contains your Vuex Store files. The Vuex Store comes with Nuxt.js out of the box but is disabled by default. Creating an index.js file in this directory enables the store. Using a store to manage the state is important for every big application. That’s why Nuxt.js implements Vuex in its core." } ] }; }};/scriptstyle/style
A partir de la script
sección, creamos una matriz que almacenamos en la directories
variable. Cada matriz contiene un objeto con id
, name
y info
. Estos son los datos que mostraremos al usuario cuando se abra esta página. Queremos mostrárselo al usuario de modo que se pueda hacer clic en los nombres.
We do that in the template
section, using v-for
to loop through the array. This makes it possible to get each item in the array, which we can access using directory
. In the loop, we use nuxt-link
to handle the linking of each time. Using nuxt-link
, we pass the details (id
, name
and info
) of each directory item via nuxt router. We do this because we want to be able to display this on the show page when the user clicks on an item.
If you navigate to the /about
route using your browser, you should see something like this:
Now, let’s create a new file and name it _id.vue.
This would automatically create a dynamic route that takes the id
param from the link display a little information about any directory clicked on from the About page.
Let us add this to our file:
template section h1{{ directory.name }}/h1 p{{ directory.info }}/p /section/templatescriptexport default { name: "directory-info", data() { return { directory: this.$route.params.dir }; }};/scriptstyle/style
What we have done is to create a page that fetches data from the route param dir
using the this.$route.params
. This gets us the name
and info
of the clicked directory, which we then display to the user.
So if you click on any directory link (e.g. store directory), you should see this.
But there’s a problem, if you refresh this page, your directory info gets lost and you get an error. This would be fixed using our Vuex Store so let’s dive into it.
Using Vuex Store In Nuxt
Vuex can be accessed in Nuxt using two modes:
- Classic mode (deprecated).
- Modules mode.
Modules mode
Nuxt automatically creates a Store folder upon the creation of your app. In Modules mode, Nuxt would treat every file inside this folder as a module but index.js
is required for Vuex store to be activated in your app. So let’s create an index.js
file in our store folder and set it up for use. Let us add the following to our file.
index.js
export const state = () = ({ })export const getters = {}export const mutations = { }export const actions = { }
All we have done is to set up the store for our file with all we might need; the state
for storing data, getters
for performing extra manipulation to our state
, mutations
for modifying our state
and actions
for committing mutations.
Nuxt also allows users to separate each core concept into different files which means we can have store.js
, getters.js
, mutation.js
and action.js
and this is good as it makes for easy maintainability. Now, we fix the problem of directory disappearing on refresh, we’ll use the store, but first, we need to install and set up Vuex persist
for our store.
Install Vuex persist
from npm using either command below, depending on your preference.
$ npm install --save vuex-persist
or
$ yarn add vuex-persist
After installing, we’re going to create a vuex-persist.js
file in our plugins folder and add the following:
import VuexPersistence from 'vuex-persist'export default ({ store}) = { window.onNuxtReady(() = { new VuexPersistence({ storage: window.localStorage }).plugin(store); });}
Here, we import our plugin from node-modules
and configure it to save your store in localStorage
. This plugin allows you to choose other storage options such as sessionStorage
too so feel free to explore their documentation for more info.
Remember to add it to your nuxt.config.js
file.
/* ** Plugins to load before mounting the App */ plugins: [{ src: '~/plugins/vuex-persist', mode: 'client' }],
Here, we added the file path to our plugin and told Nuxt to only run this plugin on the client
side of this application.
Now, we can set our store up to accept and store directory info. Update your store to handle directory info like this:
export const state = () =
Deja un comentario