VueJs composants récursifs à travers la création d’un TreeView

VueJs composants récursifs treeview
Partagez

Les treeview en vuejs sont un bon exemple de composant récursif. Dans ce tuto, vous allez découvrir les 2 : comment créer un treeview sans devoir manipuler de html avec boucle imbriquée et du coup, vous allez découvrir les composants récursifs de VueJs.

Mise en place du projet

Créez tout d’abord votre projet vide dans Visual Studio Code comme nous le faisons habituellement. Voir le tuto suivant : l’installation d’un environnement de développement complet pour VueJs.

Principe général

Le principe est simple :

  • Notre html doit juste dire qu’il affiche notre treeview
  • Les données du treeview sont dans une variable qui contient une liste de ligne de texte et chacune d’elle peut également contenir d’autres lignes de texte (des ‘enfants’) pour former un treeview
  • Si une ligne de texte contient des enfants, il y a un [+] qui est affiché s’il est fermée (collapsed) et un [-] si elle est ouverte (expanded).
  • Ainsi, un clic sur une ligne qui contient des lignes enfants va ouvrir cette ligne parente pour afficher tous ses enfants

Le code

1. Notre composant

Comme d’habitude, on va supprimer notre composant HelloWorld et en créer un nouveau. Dans notre cas : on va créer un composant TreeItem.vue dans le dossier components.

Dans ce composant, voici à quoi va ressembler le template :

<template>
  <li>
    <div
      :class="{bold: isFolder}"
      @click="toggle">
      {{ item.name }}
      <span v-if="isFolder">[{{ isOpen ? '-' : '+' }}]</span>
    </div>
    <ul v-show="isOpen" v-if="isFolder">
      <tree-item
        class="item"
        v-for="(child, index) in item.children"
        :key="index"
        :item="child"
      ></tree-item>
    </ul>
  </li>
</template>

Pour commencer on crée une liste puisque un treeview, c’est un item qui contient une liste. On a donc notre liste principale : <li> avec un div qui contient le libellé de notre item (item.name) et si c’est un folder (donc qu’il contient des sous-éléments), on va ajouter [+] s’il est fermé ainsi on peut l’ouvrir en cliquant sur ce [+] sinon on affiche un [-].

Enfin, la liste en elle-même <ul> ne sera affichée que si c’est un folder (qu’il contient des sous-éléments) et qu’il est ouvert (isOpen).

Chaque sous-élément de cette liste est lui-même un TreeItem (d’où la récursivité). -> Si c’est un élément simple il sera affiché simplement et s’il contient des sous-éléments, c’est un folder et il sera affiché avec un [+] pour pouvoir l’ouvrir etc.

Petit ajout pour bien voir si c’est un folder ou pas : on change la classe CSS dans la première ligne de code dans le cas d’un folder :

:class="{bold: isFolder}"

On a donc notre template. Maintenant il faut coder tout ça.

Dans la partie script, on a ceci :

<script>
export default {
  name: 'TreeItem', // Le nom de notre composant
  props: {
    item: Object // L'item qu'il représente : soit un texte simple soit un folder qui contient des sous-éléments
  },
  data() {
    return {
      isOpen: false // Une petite variable qui indique si le treeview (folder) est ouvert / fermé (collapsed/expanded)
    };
  },
  computed: {
    isFolder: function() { // La fonction qui indique s'il s'agit d'un folder
      return this.item.children && this.item.children.length;
    }
  },
  methods: {
    toggle: function() { // La méthode qui est appelée quand on clique sur le texte représentant le folder : on ferme ou on ouvre
      if (this.isFolder) {
        this.isOpen = !this.isOpen;
      }
    }
  }
}
</script>

J’ai commenté chaque partie de ce code afin que vous puissiez voir à quoi correspond chaque partie donc rien de spécial à dire.

2. App.vue

Dans notre composant principal (celui qui s’affiche à la place de la DIV #app), on va créer notre TreeView. On va donc avoir comme template ceci :

<template>
  <div id="app">
    <tree-item
        class="item"
        :item="treeData"
      ></tree-item>
  </div>
</template>

On a notre élément principal div id= »app » qui contient notre tree-item avec pour item nos données d’exemple qu’on va définir plus bas dans le code SCRIPT.

Justement, en parlant du code, le voici :

<script>
// Import de notre composant
import TreeItem from './components/TreeItem.vue'

export default {
  name: 'App', // Nom du composant principal
  data() {
    return {
      // Nos données d'exemple pour le treeview
      treeData : {
        name: "My Tree",
        children: [
          { name: "hello" },
          { name: "wat" },
          {
            name: "child folder",
            children: [
              {
                name: "child folder",
                children: [{ name: "hello" }, { name: "wat" }]
              },
              { name: "hello" },
              { name: "wat" },
              {
                name: "child folder",
                children: [{ name: "hello" }, { name: "wat" }]
              }
            ]
          }
        ]
      }
    }
  },
  components: {
    TreeItem // Notre composant
  }
}
</script>

Le code est encore une fois bien commenté donc rien de spécial à dire ici.

Et enfin, voici le code CSS de notre App.vue qui permet de mettre en gras les folder, etc :

<style>
body {
  font-family: Menlo, Consolas, monospace;
  color: #444;
}
.item {
  cursor: pointer;
}
.bold {
  font-weight: bold;
}
ul {
  padding-left: 1em;
  line-height: 1.5em;
  list-style-type: dot;
}
</style>

Pour finir

Voilà un petit tuto tout simple mais qui montre bien comment utiliser les composants de manière récursive. J’espère que cet article vous aura plu. N’hésitez pas à la commenter, à liker, partager et à vous inscrire sur le blog pour ne rien manquer. Je vous dis à bientôt sur le blog developpement-web-facile.com.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *