Le routeur Vue

Comment utiliser le routeur Vue, l'une des pièces essentielles d'une application Vue

introduction

Dans une application Web JavaScript, un routeur est la partie qui synchronise la vue actuellement affichée avec le contenu de la barre d'adresse du navigateur.

En d'autres termes, c'est la partie qui fait changer l'URL lorsque vous cliquez sur quelque chose dans la page et qui aide à afficher la vue correcte lorsque vous cliquez sur une URL spécifique.

Traditionnellement, le Web est construit autour d'URL. Lorsque vous accédez à une certaine URL, une page spécifique s'affiche.

Avec l'introduction d'applications qui s'exécutent dans le navigateur et modifient ce que voit l'utilisateur, de nombreuses applications ont interrompu cette interaction et vous avez dû mettre à jour manuellement l'URL avec l'API History du navigateur.

Vous avez besoin d'un routeur lorsque vous devez synchroniser des URL avec des vues dans votre application. C'est un besoin très courant, et tous les principaux frameworks modernes vous permettent désormais de gérer le routage.

La bibliothèque Vue Router est la voie à suivre pour les applications Vue.js. Vue n'impose pas l'utilisation de cette bibliothèque. Vous pouvez utiliser la bibliothèque de routage générique de votre choix ou créer votre propre intégration de l'API History, mais l'avantage d'utiliser Vue Router est que c'estofficiel.

Cela signifie qu'il est maintenu par les mêmes personnes qui gèrent Vue, vous obtenez donc une intégration plus cohérente dans le cadre et la garantie qu'il sera toujours compatible à l'avenir, quoi qu'il arrive.

Installation

Vue Router est disponible vianpmavec le package nommévue-router.

Si vous utilisez Vue via une balise de script, vous pouvez inclure Vue Router en utilisant

<script src="https://unpkg.com/vue-router"></script>

unpkg.com est un outil très pratique qui rend chaque package npm disponible dans le navigateur avec un simple lien

Si vous utilisez leVue CLI, installez-le en utilisant

npm install vue-router

Une fois que vous installezvue-routeret le rendre disponible à l'aide d'une balise de script ou via Vue CLI, vous pouvez maintenant l'importer dans votre application.

Vous l'importez aprèsvue, et vous appelezVue.use(VueRouter)àinstallerdans l'application:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

Après avoir appeléVue.use()en passant l'objet routeur, dans n'importe quel composant de l'application, vous avez accès à ces objets:

  • this.$routerest l'objet routeur
  • this.$routeest l'objet d'itinéraire actuel

L'objet routeur

L'objet routeur, accessible viathis.$routerà partir de n'importe quel composant lorsque le routeur Vue est installé dans le composant Vue racine, offre de nombreuses fonctionnalités intéressantes.

Nous pouvons faire en sorte que l'application navigue vers un nouvel itinéraire en utilisant

  • this.$router.push()
  • this.$router.replace()
  • this.$router.go()

qui ressemblent aupushState,replaceStateetgométhodes de l'API History.

push()est utilisé pour accéder à un nouvel itinéraire, en ajoutant un nouvel élément à l'historique du navigateur.replace()est le même, sauf qu'il ne pousse pas un nouvel état à l'histoire.

Échantillons d'utilisation:

this.$router.push('about') //named route, see later
this.$router.push({ path: 'about' })
this.$router.push({ path: 'post', query: { post_slug: 'hello-world' } }) //using query parameters (post?post_slug=hello-world)
this.$router.replace({ path: 'about' })

go()va et vient, en acceptant un nombre qui peut être positif ou négatif pour remonter dans l'histoire:

this.$router.go(-1) //go back 1 step
this.$router.go(1) //go forward 1 step

Définir les itinéraires

J'utilise unComposant de fichier unique Vuedans cet exemple.

Dans le modèle, j'utilise unnav tag that has 3 router-linkcomposants, qui ont une étiquette (Accueil / Connexion / À propos) et une URL attribuée via letoattribut.

Lerouter-viewLe composant est l'endroit où le routeur Vue placera le contenu qui correspond à l'URL actuelle.

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/login">Login</router-link>
      <router-link to="/about">About</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

UNErouter-linkcomposant rend unatag par défaut (vous pouvez changer cela). Chaque fois que l'itinéraire change, soit en cliquant sur un lien, soit en modifiant l'URL, unrouter-link-activeLa classe est ajoutée à l'élément qui fait référence à l'itinéraire actif, ce qui vous permet de le styliser.

In the JavaScript part we first include and install the router, then we define 3 composants d'itinéraire.

On les passe à l'initialisation durouterobjet, et nous passons cet objet à l'instance racine de Vue.

Voici le code:

<script>
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const Home = { template: ‘<div>Home</div>’ }

const Login = { template: ‘<div>Login</div>’ }

const About = { template: ‘<div>About</div>’ }

const router = new VueRouter({ routes: [ { path: ‘/’, component: Home }, { path: ‘/login’, component: Login }, { path: ‘/about’, component: About } ] })

new Vue({ router }).$mount(’#app’) </script>

Habituellement, dans une application Vue, vous instanciez et montez l'application racine en utilisant:

new Vue({
  render: h => h(App)
}).$mount('#app')

Lorsque vous utilisez le routeur Vue, vous ne passez pasrenderpropriété mais à la place, vous utilisezrouter.

La syntaxe utilisée dans l'exemple ci-dessus:

new Vue({
  router
}).$mount('#app')

est un raccourci pour

new Vue({
  router: router
}).$mount('#app')

Voir dans l'exemple, on passe unroutestableau auVueRouterconstructeur. Chaque route de ce tableau a unpathetcomponentparams.

Si vous passez unnameparam aussi, vous avez unroute nommée.

Utilisation de routes nommées pour transmettre des paramètres aux méthodes push et replace du routeur

Rappelez-vous comment nous avons utilisé l'objet Router pour pousser un nouvel état auparavant?

this.$router.push({ path: 'about' })

Avec une route nommée, nous pouvons passer des paramètres à la nouvelle route:

this.$router.push({ name: 'post', params: { post_slug: 'hello-world' } })

Il en va de mêmereplace():

this.$router.replace({ name: 'post', params: { post_slug: 'hello-world' } })

L'application rendra le composant d'itinéraire qui correspond à l'URL transmise au lien.

Le nouveau composant d'itinéraire qui gère l'URL est instancié et ses gardes appelés, et l'ancien composant d'itinéraire sera détruit.

Gardiens de route

Depuis que nous avons mentionnégardes, présentons-les.

On peut y penser à des hooks de cycle de vie ou à des intergiciels, ce sont des fonctions appelées à des moments précis lors de l'exécution de l'application. Vous pouvez intervenir et modifier l'exécution d'un itinéraire, en redirigeant ou en annulant la demande.

Vous pouvez avoir des gardes globaux en ajoutant un rappel à labeforeEach()etafterEach()propriété du routeur.

  • beforeEach()est appelé avant que la navigation ne soit confirmée
  • beforeResolve()est appelé lorsque beforeEach est exécuté et que tous les composantsbeforeRouterEnteretbeforeRouteUpdateles gardes sont appelés, mais avant que la navigation ne soit confirmée. Le contrôle final, si tu veux
  • afterEach()est appelé après confirmation de la navigation

Que signifie «la navigation est confirmée»? Nous le verrons dans une seconde. En attendant, considérez-le comme «l'application peut suivre cette route».

L'utilisation est:

this.$router.beforeEach((to, from, next) => {
  // ...
})
this.$router.afterEach((to, from) => {
  // ...
})

toetfromreprésentent les objets d'itinéraire vers et depuis lesquels nous allons.beforeEacha un paramètre supplémentairenextqui si nous appelons avecfalseen tant que paramètre, bloquera la navigation et la rendra non confirmée. Comme dans le middleware Node, si vous êtes familier, next () doit toujours être appelé, sinon l'exécution restera bloquée.

Les composants à itinéraire unique ont également des protections:

  • beforeRouteEnter(from, to, next)est appelé avant que l'itinéraire actuel ne soit confirmé
  • beforeRouteUpdate(from, to, next)est appelé lorsque la route change mais le composant qui la gère est toujours le même (avec routage dynamique, voir ci-dessous)
  • beforeRouteLeave(from, to, next)est appelé quand on s'éloigne d'ici

Nous avons mentionné la navigation. Pour déterminer si la navigation vers une route est confirmée, Vue Router effectue quelques vérifications:

  • ça appellebeforeRouteLeavegarde dans le (s) composant (s) courant (s)
  • il appelle le routeurbeforeEach()garder
  • il appelle lebeforeRouteUpdate()dans tout composant qui doit être réutilisé, s'il en existe
  • il appelle lebeforeEnter()garde sur l'objet route (je ne l'ai pas mentionné mais vous pouvez regarderici)
  • il appelle lebeforeRouterEnter()dans le composant dans lequel nous devrions entrer
  • il appelle le routeurbeforeResolve()garder
  • si tout allait bien, la navigation est confirmée!
  • il appelle le routeurafterEach()garder

Vous pouvez utiliser les gardes spécifiques à l'itinéraire (beforeRouteEnteretbeforeRouteUpdateen cas de routage dynamique) en tant que hooks de cycle de vie, afin que vous puissiez commencerrequêtes de récupération de donnéespar exemple.

Routage dynamique

L'exemple ci-dessus montre une vue différente basée sur l'URL, gérant le/,/loginet/aboutitinéraires.

Un besoin très courant est de gérer des itinéraires dynamiques, comme avoir tous les messages sous/post/, chacun avec le nom du slug:

  • /post/first
  • /post/another-post
  • /post/hello-world

Vous pouvez y parvenir en utilisant un segment dynamique.

C'étaient des segments statiques:

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/login', component: Login },
    { path: '/about', component: About }
  ]
})

nous ajoutons un segment dynamique pour gérer les articles de blog:

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/post/:post_slug', component: Post },
    { path: '/login', component: Login },
    { path: '/about', component: About }
  ]
})

Remarquez le:post_slugsyntaxe. Cela signifie que vous pouvez utiliser n'importe quelle chaîne, et qui sera mappée à lapost_slugespace réservé.

Vous n'êtes pas limité à ce type de syntaxe. Vue s'appuie surcette bibliothèquepour analyser les itinéraires dynamiquesExpressions régulières.

Maintenant, dans le composant Post route, nous pouvons référencer la route en utilisant$route, et le post slug utilisant$route.params.post_slug:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
}

Nous pouvons utiliser ce paramètre pour charger le contenu depuis le backend.

Vous pouvez avoir autant de segments dynamiques que vous le souhaitez, dans la même URL:

/post/:author/:post_slug

Rappelez-vous quand, avant, nous avons parlé de ce qui se passe lorsqu'un utilisateur navigue vers un nouvel itinéraire?

Dans le cas des itinéraires dynamiques, ce qui se passe est un peu différent.

Vue pour être plus efficace au lieu de détruire le composant de route actuel et de le ré-instancier, il réutilise l'instance actuelle.

Lorsque cela se produit, Vue appelle lebeforeRouteUpdateévénement du cycle de vie. Là, vous pouvez effectuer toutes les opérations dont vous avez besoin:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
  beforeRouteUpdate(to, from, next) {
    console.log(`Updating slug from ${from} to ${to}`)
    next() //make sure you always call next()
  }
}

Utiliser des accessoires

Dans les exemples, j'ai utilisé$route.params.*pour accéder aux données d'itinéraire. Un composant ne doit pas être si étroitement couplé avec le routeur, et à la place, nous pouvons utiliser des accessoires:

const Post = {
  props: ['post_slug'],
  template: '<div>Post: {{ post_slug }}</div>'
}

const router = new VueRouter({ routes: [ { path: ‘/post/:post_slug’, component: Post, props: true } ] })

Remarquez leprops: truepassé à l'objet route pour activer cette fonctionnalité.

Itinéraires imbriqués

Avant de mentionner que vous pouvez avoir autant de segments dynamiques que vous le souhaitez, dans la même URL, comme:

/post/:author/:post_slug

Donc, disons que nous avons un composant Auteur prenant en charge le premier segment dynamique:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script> import Vue from ‘vue’ import VueRouter from ‘vue-router’

Vue.use(VueRouter)

const Author = { template: ‘<div>Author: {{ $route.params.author}}</div>’ }

const router = new VueRouter({ routes: [ { path: ‘/post/:author’, component: Author } ] })

new Vue({ router }).$mount(’#app’) </script>

On peut insérer une seconderouter-viewinstance de composant dans le modèle Auteur:

const Author  = {
  template: '<div>Author: {{ $route.params.author}}<router-view></router-view></div>'
}

nous ajoutons le composant Post:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
}

puis nous injecterons la route dynamique interne dans la configuration de VueRouter:

const router = new VueRouter({
  routes: [{
    path: '/post/:author',
    component: Author,
    children: [
      path: ':post_slug',
      component: Post
    ]
  }]
})

Téléchargez mon gratuitManuel de Vue


Plus de tutoriels vue: