Cómo hacer más con Vue Router

 

 

 


Índice
  1. Comportamiento de desplazamiento
  2. Obtención de datos
  3. Transiciones
    1. 1. Transición por ruta
    2. 2. Transición dinámica basada en rutas
  4. Metacampos y protectores de navegación
    1. Metacampos
    2. Guardia de navegación
  5. Conclusión
    1. Recursos

Vue Router es el enrutador oficial de Vue que se utiliza principalmente para crear múltiples páginas que viven en diferentes rutas ( /home, /profile) en su aplicación, pero tiene algunas características que algunas personas no conocen. En este tutorial, aprenderemos sobre algunas características sorprendentes que tiene Vue Router y cómo podemos usarlas en nuestra aplicación.

 

Vue Router es el enrutador oficial de Vue. Se integra profundamente con el núcleo de Vue para facilitar la creación de aplicaciones de una sola página con Vue. Algunas de sus características populares incluyen:

  1. Coincidencia de ruta dinámica.
  2. Rutas nombradas.
  3. Vistas nombradas.
  4. Navegación programática.

Estas funciones se utilizan mucho cuando se desarrolla con Vue y esto se debe a que son parte de los conceptos básicos que debe comprender para utilizar el enrutador de manera eficiente. Pero Vue Router tiene algunas características muy útiles que pueden ser muy útiles en el desarrollo y en este artículo las veremos.

A los efectos de este tutorial, crearemos una aplicación sencilla que ayudará a comprender algunos de los conceptos tratados en este artículo. Puedes encontrar todo el código utilizado en este artículo en GitHub . Si está interesado en hacer más con el enrutador, se beneficiará de este tutorial.

Nota: este artículo requiere conocimientos básicos de Vuejs y Vue Router.

Comportamiento de desplazamiento

Este es el comportamiento que se observa al navegar de una página a otra. El comportamiento predeterminado del enrutador Vue solo se nota después de desplazarse a una posición que no es la parte superior de la página. Esto se debe a que, de forma predeterminada, la posición de desplazamiento al salir de una página se mantiene en una página nueva. Lo que esto significa es que, si hace clic en un enlace que conduce a una nueva ruta (es decir, de /homea /about) en una posición, digamos, cerca del pie de página de la página actual, la nueva página comenzaría desde esa misma posición en lugar de comenzar. desde la parte superior de la página.

 

Creé una aplicación Vue usando el comando Vue CLI vue create vue-router-demo. También seleccioné Vue Router como parte de las opciones mientras configuraba mi aplicación porque la usaremos a lo largo de este tutorial.

También necesitaremos realizar llamadas API a JSONPlaceholder para ilustrar algunos de los conceptos que utilizan el enrutador Vue. Para ello, utilizaremos Axios. Para instalar Axios :

# using YARNyarn add axios# or NPMnpm install axios

Después de instalar Axios, podemos actualizar nuestro Home.vuepara que se vea así:

template div p v-if="loading"Loading..../p ul v-else li v-for="post in posts" :key="post.id" router-link :to="{ name: 'Post', params: { id: post.id, post: post } }" {{ post.title }} /router-link /li /ul /div/templatescript // @ is an alias to /src import axios from "axios"; export default { name: "Home", data() { return { posts: null, loading: false, }; }, mounted() { this.getPosts(); }, methods: { async getPosts() { this.loading = true; try { let res = await axios({ url: "https://jsonplaceholder.typicode.com/posts", method: "GET", }); let posts = res.data; this.posts = posts; this.loading = false; } catch (error) { this.loading = false; } }, }, };/scriptstyle .home { padding: 0 30px; max-width: 800px; margin: 0 auto; } @keyframes blink { from { opacity: 1; } to { opacity: 0; } } .post--empty { height: 250px; margin-top: 30px; animation: blink 0.8s ease-in-out infinite alternate both; display: flex; align-items: center; justify-content: center; font-family: "Lobster", cursive; } ul { text-align: left; } a { color: inherit; }/style

Aquí, lo importamos axiosy lo usamos para obtener una lista de postsJSONPlaceholder en el getPostmétodo. También estamos asignando el conjunto de publicaciones obtenidas de esta llamada API a postsla datafunción de esta página, esto se debe a que queremos usar estos datos en nuestra sección de plantilla. Después de esto, recorremos la matriz de publicaciones en una lista ( ul/ul) y también adjuntamos un enlace a cada publicación usando idcada publicación como parámetro de enlace (esto se llama coincidencia de ruta dinámica ). También hemos añadido un párrafo que serviría como indicador de carga.

 

En este punto, así es como se ve esta página:

Lista de publicaciones de JSONPlaceholder. ( Vista previa grande )

Lo siguiente sería crear la página que mostrará la información de cada publicación y crear un enlace para ella en el enrutador de nuestra aplicación.

post.vue

template div div h1{{ post.title }}/h1 p v-html="post.body"/p /div pEnd of page/p /div/templatescript export default { name: "Post", props: ["id", "post"], };/scriptstyle .post { padding: 0 30px; height: 110vh; margin: 0 auto; } p { margin: 10px 0; }/style

Aquí, utilizamos accesorios de paso para enrutar componentes a definir idy postque pasamos desde la página anterior en forma de parámetros de ruta. Esta es una forma sencilla de acceder a los parámetros de ruta y realizar consultas en lugar de hacer esto:

post.vue

script export default { name: "Post", data() { return { post: this.$route.post, }; }, };/script

Luego utilizamos este postvalor en la sección de plantilla para mostrar el título y el cuerpo de la publicación. Finalmente, agregamos un párrafo al final de la página. También agregamos estilo para la página en la sección de estilo, que incluye la definición heightde 110vh. Esto se debe a que necesitamos que la página tenga una altura mayor que la altura predeterminada 100vhpara que podamos observar el comportamiento de desplazamiento predeterminado del enrutador.

Lo siguiente sería crear una ruta que mostrara cada publicación. Actualice su index.jsarchivo en la carpeta /router (o archivo router.js ) para que se vea así:

import Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'Vue.use(VueRouter)const routes = [{ path: '/', name: 'Home', component: Home }, { path: '/:id', name: 'Post', props: true, component: () = import ( /* webpackChunkName: "post" */ '../views/Post.vue') }]const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes})export default router

Aquí, definimos una nueva ruta que hace uso de idlo que se pasaría a esta ruta desde la página de inicio. También estamos desacoplando el parámetro del enrutador (en este caso, posty id) usando accesorios.

La parte superior de esta página se ve así:

Parte superior de la página de publicación. ( Vista previa grande )

Si hacemos clic en cualquiera de las publicaciones en la página de inicio que no requiere que nos desplacemos, no notaremos ningún comportamiento extraño en cuanto al desplazamiento, pero si nos desplazamos un poco hacia abajo y hacemos clic en la última publicación de esta lista, esto debería ser la posición en la /postque aterrizaría la página:

 

Posición de desplazamiento predeterminada. ( Vista previa grande )

Esto es malo para UX y se debe a que el usuario no espera este comportamiento y es posible que deba comenzar desde la parte superior de una página para obtener la información completa en dicha página.

Vue Router viene con la opción de personalizar este comportamiento según las preferencias individuales; un ejemplo sería guardar la posición de desplazamiento de una ruta anterior al intentar avanzar o retroceder. Para solucionar el problema actual en nuestra aplicación, actualizaríamos nuestro archivo de enrutador para incluir lo siguiente:

import Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'Vue.use(VueRouter)const routes = [...]const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes, //add this scrollBehavior(to, from, savedPosition) { return { x: 0, y: 0 } }})export default router

Ahora, si nos desplazamos hasta la parte inferior de la página de inicio y hacemos clic en la última publicación, deberías notar que ahora comienza desde la parte superior de la página.

Nueva posición de desplazamiento. ( Vista previa grande )

Obtención de datos

Al obtener datos de una API, llamamos al método en el enlace del ciclo de vida mountedo createdal método, estos son, con diferencia, los métodos más populares que la gente usa cuando desarrolla en Vue. El enrutador Vue viene con otro método en el que realizamos esta solicitud de API antes de navegar a una nueva ruta al realizar esta solicitud utilizando la beforeRouterEnterprotección en dicho componente. A continuación se muestra un ejemplo de cómo recuperar datos de JSONPlaceholder usando este método:

beforeRouteEnter(to, from, next) { axios .get("https://jsonplaceholder.typicode.com/posts") .then((res) = { next((vm) = vm.fetchData(res)); }) .catch((err) = { console.error(err); });},methods: { fetchData(res) { let post = res.data; this.posts = post; }, },

Aquí, obtenemos una lista de publicaciones de una API usando Axios y cuando se completa esta solicitud, llamamos next. En este punto del ciclo de vida de este componente, thisno está disponible porque el componente no se ha creado pero tenemos acceso, vmlo que nos da acceso a la instancia del componente. Dentro de esta función, pasamos la respuesta de la solicitud API resa nuestro método fetchDataque hemos creado para asignar el valor de esta respuesta postpara que podamos usarlo en nuestra plantilla. Ahora, si actualizamos nuestra /ruta, notaremos que los datos se actualizan muy rápido y en ningún momento hay una página en blanco (siempre que la solicitud sea exitosa).

Transiciones

Vue viene con un transition/ transitioncomponente que permite una fácil implementación de transiciones y animaciones CSS . Esta función se puede ampliar para que funcione en la navegación entre rutas en Vue. He aquí un ejemplo:

 

template div div router-link to="/"Home/router-link /div transition name="slide-fade" router-view / /transition /div/templatestyle #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #nav { padding: 30px; } #nav a { font-weight: bold; color: #2c3e50; } #nav a.router-link-exact-active { color: #42b983; } .slide-fade-enter-active { transition: transform 0.3s cubic-bezier(1, 0.5, 0.8, 1), color 0.5s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-leave-active { transition: transform 1s cubic-bezier(1, 0.5, 0.8, 1), color 1s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-enter { color: mediumblue; transform: translateY(20px); } .slide-fade-leave-to { transform: translateX(100px); color: cyan; }/style

Aquí, agregamos una transición con el nombre slide-fadea nuestra aplicación y la envolvemos alrededor de toda la navegación de ruta que tendría lugar en la aplicación. También estamos agregando un conjunto de estilos que controlan/definen la forma en que funcionarían las transiciones en nuestra aplicación. Sin estas reglas, no se produciría una transición visible. Ahora, si intentamos navegar desde la página de inicio a las publicaciones individuales, notaremos una transición deslizante y atenuada durante el proceso de navegación. Significado de emojis

Hay dos tipos de transiciones basadas en rutas.

1. Transición por ruta

Este tipo de transición se define en el componente que representa una ruta y, por lo tanto, solo afecta la navegación hacia y desde dicha página. Esto nos da la posibilidad de definir una transición especial para rutas individuales si así lo deseamos. A continuación se muestra un ejemplo de cómo hacerlo.

template // add a transition component with name and mode props transition name="slide-fade" mode="in-out" div div h1{{ post.title }}/h1 p v-html="post.body"/p /div pEnd of page/p /div /transition/templatescript export default { name: "Post", props: ["id", "post"], };/scriptstyle //... .slide-fade-enter-active { transition: transform 2s cubic-bezier(1, 0.5, 0.8, 1), opacity 2s ease-in; } .slide-fade-leave-active { transition: transform 2s cubic-bezier(1, 0.5, 0.8, 1), opacity 2s ease-out; } .slide-fade-enter { opacity: 1; transform: skewY(20deg); } .slide-fade-leave-to { transform: skewY(-45deg); opacity: 0.5; }/style

Si intenta navegar fuera de esta página, notaremos que la página se distorsiona y se desvanece durante un período de tiempo 2sa medida que cambia la navegación.

2. Transición dinámica basada en rutas

Esto es similar al método general de agregar transiciones a todas las rutas en su aplicación, pero tiene una diferencia importante, es decir, acepta un nameaccesorio de transición dinámica que le brinda la posibilidad de cambiar el tipo de transición de la forma que desee. Creemos un ejemplo de cómo hacer esto.

 

Actualizaremos nuestro App.vuearchivo con un nameaccesorio dinámico y lo configuraremos para elegir un nombre de transición según un valor.

 template div div router-link to="/"Home/router-link /div transition :name="transitionName" router-view / /transition /div/templatescript export default { data() { return { transitionName: "slide-fade", }; }, watch: { $route(to, from, params) { const toParam = to.params to.params.id ? to.params.id : 0; this.transitionName = toParam % 2 === 0 ? "slide-left" : "slide-fade"; }, }, };/scriptstyle /* add transition styles */ .slide-fade-enter-active { transition: transform 0.3s cubic-bezier(1, 0.5, 0.8, 1), color 0.5s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-leave-active { transition: transform 1s cubic-bezier(1, 0.5, 0.8, 1), color 1s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-enter { color: mediumblue; transform: translateY(20px); } .slide-fade-leave-to { transform: translateX(100px); color: cyan; } .slide-left-enter-active { transition: transform 0.3s cubic-bezier(1, 0.5, 0.8, 1), color 0.5s cubic-bezier(1, 0.5, 0.8, 1); } .slide-left-leave-active { transition: transform 1s cubic-bezier(1, 0.5, 0.8, 1), color 1s cubic-bezier(1, 0.5, 0.8, 1); } .slide-left-enter { color: mediumblue; transform: translateY(20px); } .slide-left-leave-to { transform: skewY(90deg); color: cyan; }/style

Aquí, agregamos un nombre de transición dinámica que se define en la sección de secuencia de comandos de nuestra aplicación. También estamos vigilando $routeque cada vez que cambie, ejecutemos la función que verifica si la ruta actual tiene un parámetro de, idde lo contrario, le damos un valor de 0. También determinamos el nombre de la transición según el tipo de número id(es decir, número par o impar). Ahora, si navegamos entre la página de destino y las diferentes publicaciones disponibles, observaremos que se producen dos tipos de transiciones mientras navegamos.

Metacampos y protectores de navegación

Metacampos

Los metacampos ayudan a proporcionar contexto adicional a una ruta determinada. Un ejemplo de dicho contexto sería si un usuario necesita estar autenticado para acceder a dicha ruta o no. Así es como se ve esto:

import Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'Vue.use(VueRouter)const routes = [{ path: '/', name: 'Home', component: Home, // add meta to this route meta: { requiresAuth: true } },]const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes})export default router

Aquí, agregamos una metapropiedad requiresAutha la /ruta, lo que significa que queremos que los usuarios se autentiquen antes de que puedan acceder a esa ruta. Tenga en cuenta que 'requiresAuth' no es una propiedad estándar, por lo que puede elegir el nombre que prefiera. Cualquier valor que seleccione al final puede ser accesible en el $routeobjeto. Este metacampo en este punto no impediría que usuarios no autorizados accedan a esa ruta; debemos conectarlo al protector de navegación.

 

Guardia de navegación

Tal como su nombre lo indica, el protector de navegación ayuda a proteger y proteger las rutas según sus preferencias (es decir, redirigir a otra página o impedir la navegación). Esta característica funciona junto con los metacampos de ruta para proteger eficazmente las rutas de su aplicación. Hay 3 formas de agregar protección de enrutador en nuestra aplicación:

1. En componente

Vue ofrece la opción de configurar la protección de su enrutador para una ruta particular directamente dentro de sus componentes. Aquí hay un ejemplo en nuestro Home.vuearchivo:

template div p v-if="loading"Loading..../p ol v-else !-- add this text to your template -- p v-if="guest"Hi Guest/p li v-for="post in posts" :key="post.id" router-link :to="{ name: 'Post', params: { id: post.id, post: post } }" {{ post.title }} /router-link /li /ol /div/templatescript // @ is an alias to /src import axios from "axios"; export default { name: "Home", data() { return { posts: null, // add this property guest: false, loading: false, }; }, // add this function beforeRouteEnter(to, from, next) { if (to.matched.some((record) = record.meta.requiresAuth)) { // this route requires auth, check if logged in // if not, display guest greeting. const loggedIn = JSON.parse(localStorage.getItem("loggedIn")); if (!loggedIn) { next((vm) = { vm.guest = true; }); } else { next(); } } else { next(); // make sure to always call next()! } }, methods: {...} };/scriptstyle.../style

Aquí, agregamos un párrafo que solo es visible para usuarios no autenticados. También agregamos una propiedad que controla la visibilidad de este texto. Finalmente tenemos un método de enrutador beforeRouteEnteren el que también conectamos el protector del enrutador y verificamos si el usuario está autenticado o no usando un valor que se agregaría manualmente más adelante. También tenemos una if/elsedeclaración, y dentro de esta declaración, cambiamos el valor de guestdependiendo de la autenticación del usuario.

Y en su App.vue, agregue este ciclo de vida al archivo.

export default { mounted() { localStorage.setItem("loggedIn", false); } };

Entonces, si actualiza su aplicación, deberíamos ver el texto que agregamos en el Home.vuearchivo.

 

Texto del invitado visible. ( Vista previa grande )

2. Por ruta

También podemos agregar una protección de enrutador a nuestras aplicaciones por ruta en nuestro archivo de enrutador como otra propiedad dentro del objeto de ruta específico. He aquí un ejemplo:

{ path: '/', name: 'Home', component: Home, // add meta to this route meta: { requiresAuth: true }, beforeEnter: (to, from, next) = { if (to.name !== 'Home') { console.log('Per-Route navigation guard ti wa online'); next() } else next() } }

Aquí, agregamos una protección de enrutador a la /ruta y actualmente solo estamos registrando un texto aleatorio en la consola, pero podemos hacer un par de cosas dentro de esta protección. Ahora, cada vez que visites la página de inicio, verás esto en tu consola:

Mensaje impreso en la terminal. ( Vista previa grande )

3. Globalmente

También tenemos la opción de crear una protección de enrutador que funcione globalmente para cada parte de la aplicación (siempre que cumpla con la condición de protección). Esta protección global se crea en el archivo del enrutador al igual que la protección por ruta , pero en lugar de definirla dentro de un objeto de ruta específico, se define como un método de la routerinstancia. Para ver un ejemplo de cómo funciona, crearemos un nuevo archivo y ruta en nuestra aplicación guest.vue, le asignaremos un nombre y luego agregaremos las siguientes líneas de código al archivo.

template div h1Guest page/h1 pYou're seeing this page because you are not logged in/p /div/templatescript/scriptstyle/style

A continuación, creamos una /loginruta con esta página recién creada y agregamos una metapropiedad a otras rutas existentes.

 // create new route { path: '/login', name: 'login', component: () = import ( /* webpackChunkName: "auth" */ '../views/guest.vue') }, { path: '/:id', name: 'Post', props: true,a // add meta property meta: { requiresAuth: true }, component: () = import ( /* webpackChunkName: "post" */ '../views/Post.vue') }

Lo siguiente sería crear el protector de navegación global para todas las rutas que requieran autenticación y comprobar la autenticación del usuario mediante localStorage(creado previamente). Redirigiríamos a los usuarios que tienen un loggedInvalor falso a /login.

router.beforeEach((to, from, next) = { if (to.matched.some((record) = record.meta.requiresAuth)) { // this route requires auth, check if logged in // if not, display guest greeting. const loggedIn = JSON.parse(localStorage.getItem("loggedIn")); if (!loggedIn) { next({ path: '/login' }); } else { next(); } } else { next(); // make sure to always call next()! }})

Entonces, si revisa su aplicación en su navegador, notará que actualmente se encuentra en esta página:

Página de invitados. ( Vista previa grande )

Si intentamos navegar a cualquiera de las rutas existentes, seremos redirigidos automáticamente a esta página sin importar lo que hagamos y eso significa que nuestro guardia de enrutador está protegiendo efectivamente esas rutas.

Conclusión

Podemos ver que Vue Router es una herramienta muy poderosa que se puede utilizar para algo más que crear rutas en su aplicación. Hemos aprendido cómo configurar el comportamiento de desplazamiento de las rutas en nuestra aplicación, las diferentes formas de agregar transiciones a las rutas en nuestra aplicación, cómo recuperar datos de una API antes de que se monte un componente, cómo usar la metapropiedad para nuestras rutas y la Diferentes formas de configurar la protección del enrutador.

Recursos

  1. Enrutador Vue
  2. Transiciones CSS en Vuejs y Nuxtjs

(ks, ra, yk, il)Explora más en

  • API
  • vista
  • javascript





Tal vez te puede interesar:

  1. ¿Deberían abrirse los enlaces en ventanas nuevas?
  2. 24 excelentes tutoriales de AJAX
  3. 70 técnicas nuevas y útiles de AJAX y JavaScript
  4. Más de 45 excelentes recursos y repositorios de fragmentos de código

Cómo hacer más con Vue Router

Cómo hacer más con Vue Router

Índice Comportamiento de desplazamiento Obtenc

programar

es

https://aprendeprogramando.es/static/images/programar-como-hacer-mas-con-vue-router-1056-0.jpg

2024-05-21

 

Cómo hacer más con Vue Router
Cómo hacer más con Vue Router

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Top 20