Crear ruteo básico en Vue 3 con Vue Router

- 👤 Andrés Cruz

🇺🇸 In english

Crear ruteo básico en Vue 3 con Vue Router

Vamos a aprender a hacer un ruteo simple en Vue 3, para esto vamos a emplear el plugin de Vue Router que es excelente porque es desarrollado y mantenido por la misma gente de Vue, por lo tanto la integración es óptima.

Sobre el ruteo en Vue

La navegación es un tema fundamental para cualquier tipo de desarrollo de aplicaciones que estemos llevando a cabo, y en Vue o cualquier otro framework JavaScript del lado del cliente no puede ser la excepción. 

La navegación mediante rutas nos permite vincular distintas páginas

Páginas basadas en componentes, por lo tanto, podemos escalar la aplicación fácilmente con nuevas páginas y/o componentes.

Los componentes los puedes ver como si fueran una micro app que realiza una función en particular, un listado, un formulario, una funcionalidad, etc, que a su vez, pueden dividir en componentes que se encuentren en otros componentes, pero ya esto es otro tema.

Crear una app en Vue CLI

Como siempre, vamos a partir de la creación de una nueva aplicación en Vue, para eso vamos a usar la línea de comandos que nos ofrece Vue conocido como CLI, vamos a instalarla de manera global a nuestro OS:

npm install -g @vue/cli

O

yarn global add @vue/cli

Recuerda que puedes usar Windows, Linux o Mac ya que es multiplataforma.

Ahora, felizmente creamos un nuevo proyecto en Vue 3:

vue create my-vue-router

selecciona Vue 3, la preview y con esto tendremos nuestro proyecto básico y limpio en VUE 3 en poco tiempo:

 

Consola o Terminal creando un app en Vue Cli
Consola o Terminal creando un app en Vue Cli

 

Vue Router basico

Instalar Vue Router

Sobre la carpeta de nuestro proyecto que creamos anteriormente, ejecutamos:

npm i vue-router@next

Creando el archivo para las rutas

Como puede suponer, al igual que el funcionamiento clásico de cualquier plugin, la vinculación del plugin con Vue lo tienes que hacer en la instancia principal, aquí (en el archivo de la instancia principal) puedes colocar cualquier cantidad de código que en el caso de las rutas serían la definición de las ruta que lucen de la siguiente manera:

import { createRouter, createWebHistory }  from 'vue-router'
 
import Login from '../components/Login';
import App from '../components/App';
import Group from '../components/Group';
import Chat from '../components/Chat';
 
const routes = [
 {
   path: '/',
   name: 'App',
   component: App
 },
 {
   path: '/login',
   name: 'Login',
   component: Login
 },
 {
   path: '/group',
   name: 'Group',
   component: Group
 },
 {
   path: '/chat/:room',
   name: 'Chat',
   component: Chat
 }
]
 
const router = createRouter({
   // 4. createWebHashHistory
   history: createWebHistory(),
   routes, // short for `routes: routes`
 })
 
 export default router

Pero obviamente definiendo todas las rutas que vayas a emplear; así que, para mantener este archivo sencillo, vamos a hacer toda esta definición en un archivo a parte que luego vamos a exportar y definir directamente dentro de la instancia principal de Vue.

Crear y definir el archivo de router

Aunque puedes colocar cualquier nombre a este archivo y colocarlo en cualquier ubicación, a mi me gusta colócalos dentro de:

helpers/router.js

Aquí voy a suponer que tenemos algunos componentes ficticios, aunque son basados en mi curso de Electron en la cual estábamos construyendo una aplicación de Chat con Firebase y puedes obtener más información desde esta página en la sección de curso.

Explicación del código anterior

Aquí no hay mucho que decir, básicamente todo se auto explica, de igual manera:

  • La función llamada createRouter que viene formando parte del plugin de Router Vue nos permite definir las rutas, para esto tenemos que pasar un parámetro que vienen siendo las rutas, un array con las rutas, en las cuales cada elemento tiene que tener el path, que viene siendo la uri y el componente, el nombre es opcional y nos sirve cuando queremos crear un enlace de navegación (router-link) o la navegación de manera programática mediante el componente de router.
  • Por lo demás, a la función de createRouter le tenemos que definir mediante la opción de history el modo de composición de la URL:
  • history: createWebHistory(),

Debajo de esta matriz, notará que creamos el enrutador en sí, utilizando las rutas y también pasamos createWebHistory. Esto se usa para cambiar de usar hash al modo de historial dentro de su navegador, usando la API de historial de HTML5. La forma en que configuramos esto es un poco diferente a la que hicimos en Vue 2 en el mismo curso.

Es simplemente para indicar si queremos una URL limpia o una simulada con una almohadilla.

Definiendo el template base

En nuestro src/App.vue, que es el componente que se crea por defecto y se carga por defecto, colocamos el esqueleto de la app junto con el router-view que nos permite crear la web SPA; y donde se renderizan los componentes por los cuales nuestro usuario navega y que corresponden a las rutas definidas anteriormente:

<template>
 <div id="nav">
   <router-link to="/">App</router-link> |
   <router-link to="/login">Login</router-link> |
   <router-link to="/group">Group</router-link>
 </div>
 <router-view />
</template>

<script>
export default {
 name: "App",
 components: {},
};
</script>

Puedes ver cada uno de los componentes que empleamos aquí de manera demostrativa en el repositorio en github que te dejé anteriormente

Palabras claves:

  1. Ruta: la ruta URL donde se puede encontrar esta ruta.
  2. Nombre: un nombre opcional para usar cuando nos vinculamos a esta ruta.
  3. Componente: qué componente cargar cuando se llama a esta ruta.
  4. Usando <router-view> y <router-link>

Hay dos directivas que nuestra aplicación Vue nos da para usar en nuestra plantilla:

  • <router-view />: cuando se navega a una ruta en el navegador, aquí es donde se representa el componente, es decir, donde es renderizado el contenido cambiante de nuestra página de tipo SPA. Por ejemplo, en nuestro código, ir a / representará el componente Home donde listamos <router-view />.
  • <router-link>: esta es la directiva que usamos para crear enlaces entre nuestras diferentes páginas de componentes, en lugar de usar <a href>. 

¿Por qué Vue Router?

Vue es poderoso para crear aplicaciones de una sola página: páginas web altamente interactivas que NO se actualizan cuando cambia de una página a otra. Si su sitio web tiene varias páginas (o "vistas") y está utilizando Vue, es por eso que necesita Vue Router, ya que nos permite crear las famosas páginas de tipo SPA para hacer todo esto sin mucho problemas empleando uno de los frameworks web del lado del cliente más populares y sencillos del mercado.

Redireccionar 404 en Vue Router

Aquí quería resolver una pequeña situación que ocurre cuando ingresamos a una ruta que no existe. Ya tengo la solución, así que la comentaré un momento.

Si ingresamos a la aplicación y tratamos de acceder a cualquier ruta que no exista, por ejemplo la raíz directamente, veremos que aparece una página en blanco.
Si presionamos F2 o revisamos desde la consola, veremos que esta ruta no hace match con ninguna porque no la tenemos definida. Esa es la razón. Lo mismo sucede si vamos a otra ruta que no exista.

Solución 1: 404 mediante componentes

Existen un par de maneras de solucionar esto. Una de ellas es crear un componente específico.

De manera demostrativa, estoy utilizando el componente ListCategory:

// src/router.js
const routes = [
  {
      path: '/dashboard',
      component: Base,
      children: [
          ***
      ],
  },
  {
      path: '/:pathMatch(.*)*', 
      name: 'NotFound', 
      component: YourComponent404
  },
]

Solución 2: 404 con Redirección

Supón que el componente no existe, o que este componente estaba destinado a mostrar un mensaje de "404" para indicar al usuario que la página no existe.

En este caso, el componente podría funcionar, pero no creo que sea necesario crear uno específico, especialmente en aplicaciones administrativas.
No tiene mucho sentido mostrar una página 404; es mejor redirigir al usuario a una página válida.

Para ello, podemos colocar una redirección:

// src/router.js
const routes = [
  {
      path: '/dashboard',
      component: Base,
      children: [
          ***
      ],
  },
  {
      path: '/:pathMatch(.*)*', 
      name: 'NotFound', 
      redirect: '/dashboard/movie'
  },
]

Explicación de la redirección

La línea de redirección funciona de la siguiente manera:

  • Cuando se ingresa una ruta que no existe, por ejemplo la raíz, en lugar de mostrar una página en blanco o un mensaje de "404", la aplicación redirige automáticamente a una ruta válida.
  • Por ejemplo, si colocamos la raíz (/) en desarrollo (localhost:5173) o en producción (vuecodig.com), y la ruta no existe, el usuario será redirigido automáticamente a la página de destino (/dashboard/movie).
  • De esta forma, evitamos mostrar la página 404 por defecto y garantizamos que la aplicación siempre muestre contenido válido.

Rutas hijas en Vue Router

El sistema de ruteo en Vue es una característica fundamental que permite la navegación entre diferentes páginas o componentes en una aplicación de una sola página (SPA). Vue utiliza una biblioteca llamada Vue Router para manejar el enrutamiento.

El sistema de ruteo en Vue se basa en un archivo de configuración, donde se almacenan las rutas a emplear y su componente asociado. A cada ruta se le pueden establecer parámetros y condiciones específicas según sea necesario.

Cuando un usuario navega a una ruta específica en una aplicación Vue, el sistema de ruteo se encarga de cargar el componente correspondiente y renderizarlo en la vista principal. Esto permite crear una experiencia de usuario fluida y dinámica, donde los cambios de página se realizan de forma instantánea, sin necesidad de recargar toda la aplicación.

Rutas hijas o subrutas en Vue Router

Ahora vamos a conocer cómo crear rutas hijas o subrutas en Vue Router. Mediante este mecanismo podemos agrupar nuestras rutas en base a un mismo componente hijo o subhijo del componente principal de rutas.

Para ello, utilizamos la opción children, que nos permite definir componentes hijos dentro de un componente base. Además, es necesario definir el componente base y el path del componente hijo.

Recuerda que, para esto, necesitas comprender cómo trabajar con las rutas en Vue y cómo estructurar correctamente los componentes padres e hijos.

export const routes = [
   {
       name: 'home',
       path: '/test',
       component: Home
   },
   {
       path: '/academia',
       component: Base,
       children: [
           {
               name: 'index',
               path: '',
               component: Index
           },
           {
               name: 'my-courses',
               path: 'my-courses',
               component: MyCourses
           },
           {
               name: 'detail',
               path: ':slug/:s?/:c?',
               component: Detail
           },
           {
               name: 'register',
               path: 'register',
               component: Register
           },
           {
               name: 'login',
               path: 'login',
               component: Login
           }
       ]
   }
];
const router = createRouter({
   history: createWebHistory(),
   routes: routes,
});

Tal cual puedes ver, puedes definir el resto de tus rutas ya sean que tengan la características de rutas hijas o las tradicionales.

En el componente hijo, como puedes ver, le definimos su propio router-link para que con esto pueda aparecer el contenido respectivo de nuestras rutas hijas:

Base.vue

<template>
 <div>
   <router-link :to="{name:'my-courses'}">Mis cursos</router-link>
   <router-view></router-view>
 </div>
</template>

Parámetros opcionales en Vue Router

Cuando estás trabajando con las Rutas en Vue con Vue Router; seguramente te va a interesar definir parámetros a tus rutas en Vue; y más que esto, que algunos sean opcionales; para eso, lo único que tienes que hacer es colocar el signo de ? delante del parámetro.

Los parámetros opcionales son una característica que permiten definir parte de una ruta como opcional al momento de navegar entre diferentes componentes.

Los parámetros opcionales se definen utilizando los signos de interrogación (?) en la ruta. Por ejemplo, si tienes una miruta/post/:id?, el parámetro id se considera opcional. Esto significa que la ruta /post y la miruta/post/123 ambas serán válidas.

Cuando se utiliza un parámetro opcional en una ruta, puedes acceder a su valor en el componente correspondiente a través de this.$route.params. Si el parámetro opcional no está presente en la URL, su valor será undefined.

export const routes = [
...
    {
        name: 'home',
        path: '/test/:param1?',
        component: Home
    },
...
]

Solo agrego un signo de interrogación ? lo hará opcional

¿Cómo usar múltiples router-views, en un componente?

Vue.js es un framework de aplicación web fácil de usar que podemos usar para desarrollar aplicaciones front-end interactivas.

En este artículo, veremos cómo definir y usar rutas con nombre y vistas con nombre con Vue Router; con Vue Router, podemos usar multiples paginas en una misma aplicacion en Vue y cambiar las mismas mediante la URL para poder ir a otras páginas; con Vue Router, podemos crear una aplicacion en Vue de la maneta tradicional como haríamos en una aplicación en HTML que consta de multiples páginas, la podemos tener en Vue.

Rutas con nombre

Podemos agregar un nombre para identificar una ruta agregando una propiedad de nombre a nuestros objetos de ruta.

Por ejemplo, podemos escribir:

{
    name: 'list-category',
    path: 'category',
    components: {
        default: ListCategory,
        a: { template: 'Listado de categorías' }
    }
},

Y para referenciar la misma, desde alguna parte, hacemos lo siguiente; esta es la forma en la cual podemos crear un enlace en en Vue Router:

<router-link :to="{ name: 'list-category' }">Listado</router-link>

La ventana que tenemos con este enfoque es que al emplear un routerLink en vez de un enlace en HTML tradicional es que, la página no recarga en su totalidad si no, solamente el componente; de esta manera, podemos tener una web SPA muy facilmente con Vue.

Vistas con nombre

Podemos tener vistas con nombre con Vue Router.

Por ejemplo, podemos escribir:

<!DOCTYPE html>
<html lang="en">
  <head>
  </head>
  <body>
    <div id="app">
      <router-view></router-view>
      <router-view name="a"></router-view>
      <router-view name="b"></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const Baz = {
        template: "<div>baz</div>"
      };
      const routes = [
        {
          path: "/",
          components: {
            default: Foo,
            a: Bar,
            b: Baz
          }
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

Tenemos un objeto en el array de rutas llamado routes, al igual que vimos en crear rutas con Vue Router.

Lo más importante del código anterior es el componente llamado router-view que recordemos es el que podemos usar para cargar el componente referenciado en la ruta; en el script anterior puedes notar que existen varios, pero, tienen nombres, por lo tanto ahora, tenemos router-views con nombres y por defecto que podemos usar.

En la ruta del path:

path: "/",

Al tener tres router-views:

<router-view></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view>

La que no tiene nombre, es la que usamos por defecto:

<router-view></router-view>

Para las otras 3, que tienen nombre, se referencian por el mismo:

<router-view name="a"></router-view>
<router-view name="b"></router-view>

Para referenciarlas desde la definición de la ruta:

components: {
            default: Foo,
            a: Bar,
            b: Baz
          }

Acepto recibir anuncios de interes sobre este Blog.

Vamos a aprender a hacer un ruteo simple en Vue 3, para esto vamos a emplear el plugin de Vue Router que es excelente porque es desarrollado y mantenido por la misma gente de Vue, por lo tanto la integración es óptima.

| 👤 Andrés Cruz

🇺🇸 In english