Implémentation d'une navigation multi-niveaux avec Vue et Vue Router

Dans de nombreux projets web, il est courant de devoir implémenter une barre latérale de navigation permettant de basculer entre différentes pages.

Si nous réalisons cette barre de navigation comme un composant public et que nous l'appelons sur chaque page, cela complique la maintenance ultérieure. Par exemple, toute modification de paramètres nécessiterait de mettre à jour chaque page individuelle.

Cet article présente une approche alternative où la barre de navigation est implémentée comme un composant parent, tandis que les pages de contenu sont des composants enfants. Cette méthode ne nécessite qu'un seul appel au composant de navigatino, simplifiant considérablement la maintenance future.

Fonctionnalités clés

  • Barre latérale supportant plusieurs niveaux de navigation
  • Utilisation de Vue Router (documentation officielle)
  • Implémentation de composants parents et enfants
  • Styles avec ElementUI

Structure de projet

structure_projet.pngImplémentation

--- Configuration de Vue RouterCommencez par installer Vue Router via npm : npm install vue-router. Ensuite, importez-le dans votre fichier main.js :

import router from './router'

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

--- Utilisation de Vue Router dans les vuesDans App.vue, ajoutez un compoasnt router-view. Ce composant agit comme un conteneur pour afficher les routes définies :

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

Il est recommandé de garder App.vue minimal, en l'utilisant principalement comme un conteneur racine. Cela évite certaines erreurs courantes chez les débutants, comme des problèmes de build.

Dans notre cas, nous avons utilisé App.vue uniquement pour afficher la page racine, et créé une nouvelle page index.vue dans components/page pour contenir la barre latérale et afficher les pages enfants :

<template>
   <div>
       <!--v-menu-latéral est notre barre de navigation-->
       <v-menu-latéral  ></v-menu-latéral>
       <div class="contenu" :style="{height: (this.$store.state.bodyHeight-20) + 'px',overflow:'auto'}">
         <div></div>
           <transition name="mouvement" mode="out-in">
           <!--Ce router-view affiche les pages enfants-->
            <router-view></router-view>    
           </transition>
       </div>
   </div>
</template>
<script>
   // Import du composant de barre latérale
   import vMenuLatéral from '../communs/menu.vue';
   export default {
       data() {
           return {}
       },
       components:{
         // Enregistrement du composant de barre latérale
           vMenuLatéral
       },
   }
</script>

La structure de navigation avec routage est maintenant complète

Pour découvrir comment implémenter une navigation multi-niveaux, poursuivez la lecture~

Nous avons extrait toutes les définitions de route dans un fichier séparé pour une maintenance et une gestion centralisées. Dans router/index.js, définissons les noms et les chemins des routes :

import Routeur from 'vue-router';
Vue.use(Routeur);
export default new Routeur(
  {
    routes: [
      {
        path: '/',
        name: 'principal', component: principal,
        children: [
          {
            path: '/desactiver-saisie',
            component: resolve => require(['../composants/page/saisie/index.vue'], resolve),
            meta: {title: 'Désactiver saisie'},
          },
          {
            path: '/selection-liee',
            component: resolve => require(['../composants/page/saisie/selection.vue'], resolve),
            meta: {title: 'Sélection liée'},
          },
          {
            path: '/rafraichissement-bas',
            component: resolve => require(['../composants/page/rafraichissement/rafraichissementBas.vue'], resolve),
            meta: {title: 'Rafraîchissement vers le bas'},
          },
        ],
      },
    ]
  })

--- Création de la barre latérale de navigationNous utilisons le composant de menu d'ElementUI pour notre barre de navigation.

Note importanteLa structure de données du menu est imbriquée (parents contenant des enfants) plutôt qu'à plat avec des identifiants.

L'implémentation repose sur une boucle imbriquée :

<template>
  <div class="barre-laterale">
    <el-menu class="menu-el" :default-active="routeActive" :collapse="reduit" unique-opened router
             collapse-transition>
      <template v-for="element in elements" v-cloak>
        <template v-if="element.sousElements.length!==0">
          <el-submenu :index="element.chemin" :key="element.chemin">
            <template slot="title">
              <span slot="title">{{ element.nom }}</span>
            </template>
            <el-menu-item v-for="(sousElement,i) in element.sousElements" :key="i" :index="sousElement.chemin">
              <span slot="title">{{ sousElement.nom }}</span>
            </el-menu-item>
          </el-submenu>
        </template>
        <template v-else>
          <el-menu-item :index="element.chemin" :key="element.chemin">
            <span slot="title">{{ element.nom }}</span>
          </el-menu-item>
        </template>
      </template>
    </el-menu>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        reduit: false,
        elements: [{
          nom: "Composants ElementUI",
          chemin: "",
          sousElements: [
            {nom: "Désactiver saisie", chemin: "/desactiver-saisie", sousElements: []},
            { nom: "Sélection liée", chemin: "/selection-liee",  sousElements: []
          }]
        }, {nom: "Rafraîchissement mobile", chemin: "/rafraichissement-bas", sousElements: []}]
      }
    },
    computed: {
      routeActive() {
        // Index du menu actuellement actif
        return this.$route.path.replace('/', '');
      }
    },
  }
</script>

L'implémentation est maintenant terminée. Les contributions et suggestions sont les bienvenues !

Étiquettes: Vue.js Vue Router JavaScript frontend Architecture composants

Publié le 14 juillet à 09h11