Skip to main content

Command Palette

Search for a command to run...

Écrire du Code Vue.js Clair et Lisible : La Magie des Composants Propres

Published
6 min read
Écrire du Code Vue.js Clair et Lisible : La Magie des Composants Propres
E

I'm Elvin Kyungu, i am a front-end web developer | Google DSC Lead | Content creator | Lovers of tailwindcss, Vue js and Nuxt js

Introduction

Vue.js est un framework JavaScript puissant et flexible pour créer des interfaces utilisateur. Une des meilleures pratiques en développement Vue.js est de découper vos composants en parties plus petites et réutilisables. Cela facilite la maintenance, la lisibilité et le test de votre code.

Dans cet article, nous allons voir comment structurer une application Vue.js en utilisant des composants propres et bien organisés. Nous allons illustrer cela avec un exemple simple, mais représentatif.

Extraire des Composants pour Améliorer la Lisibilité

Une façon d'optimiser vos composants pour une meilleure compréhension humaine est de séparer l'intention de l'implémentation. C'est l'une des principales raisons pour lesquelles vous devriez créer un nouveau composant : pour pouvoir remplacer un morceau de code par une déclaration qui décrit ce que ce code fait.

Voici un composant très basique :

<template>
  <div>
    <p>{{ user.name }} ({{ user.age }})</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const user = ref({
  name: 'Elvin Kyungu',
  age: 25,
});
</script>

Nous pouvons extraire un composant UserInfo, ce qui rend extrêmement clair ce que fait la ligne de code - afficher les informations de l'utilisateur :

<template>
  <div>
    <UserInfo :user="user" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import UserInfo from './UserInfo.vue';

const user = ref({
  name: 'Elvin Kyungu',
  age: 25,
});
</script>

Après avoir créé ce nouveau composant, nous devons maintenant gérer quelques étapes supplémentaires pour le rendre fonctionnel.

Étape 1 : Créer le Composant UserInfo

Dans cette étape, nous allons définir le composant UserInfo pour encapsuler l'affichage des informations de l'utilisateur.

<template>
  <p>{{ user.name }} ({{ user.age }})</p>
</template>

<script setup>
import { defineProps } from 'vue';

const props = defineProps({
  user: Object,
});
</script>

Étape 2 : Importer et Utiliser le Composant

Ensuite, nous devons importer ce nouveau composant dans notre composant principal et l'utiliser avec les bonnes props.

<template>
  <div>
    <UserInfo :user="user" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import UserInfo from './UserInfo.vue';

const user = ref({
  name: 'Elvin Kyungu',
  age: 25,
});
</script>

En suivant ces étapes, nous avons séparé l'intention (afficher les informations de l'utilisateur) de l'implémentation (le code réel pour afficher les informations).

Écrire du Code Clair et Bien Organisé

Les composants Vue doivent avoir des noms clairs et significatifs pour leurs props, données, propriétés calculées, méthodes et hooks de cycle de vie (et tout le reste). Nous voulons également que notre code de template soit organisé et lisible grâce à une indentation correcte, une mise en forme appropriée et des commentaires occasionnels.

Lorsque votre code est autodocumenté, il annonce l'intention de ce qu'il fait. Voici un exemple peut-être absurde (qui écrirait du code comme ceci ?), mais il faut un peu d'effort pour comprendre ce qui se passe :

<template>
  <div>
    <button @click="c">Increment</button>
    <p>{{ a }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const a = ref(0);

function c() {
  a.value++;
}
</script>

Oui, c'est un compteur. Mais dans l'exemple suivant, il est immédiatement clair de quoi il s'agit :

<template>
  <div>
    <button @click="incrementCounter">Increment</button>
    <p>{{ counterValue }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const counterValue = ref(0);

function incrementCounter() {
  counterValue.value++;
}
</script>

Dans le code refactorisé, nous avons amélioré le nommage des variables et des méthodes pour les rendre plus descriptives. Maintenant, nous n'avons plus besoin de gaspiller notre temps et notre énergie mentale chaque fois que nous revenons à ce composant.

Séparer les composants trop longs

Lorsqu'un composant fait trop de choses et devient trop long, il peut être difficile à comprendre et à maintenir. Le principe des composants longs nous indique que la décomposition d'un composant long en composants plus petits et plus ciblés peut contribuer à améliorer la lisibilité, la réutilisation et la testabilité.

Voici un composant d'un magasin de commerce électronique qui essaie de tout faire :

<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
    <ul>
      <li v-for="item in items" :key="item.id">
        {{ item.name }} - {{ item.price }}
        <button @click="addToCart(item)">Add to cart</button>
      </li>
    </ul>
    <div>
      <h2>Cart</h2>
      <ul>
        <li v-for="item in cart" :key="item.id">
          {{ item.name }} - {{ item.price }}
          <button @click="removeFromCart(item)">Remove</button>
        </li>
      </ul>
      <p>Total: {{ totalPrice }}</p>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const title = ref('My Store');
const description = ref('Welcome to my store!');

const items = ref([
  { id: 1, name: 'Item A', price: 10 },
  { id: 2, name: 'Item B', price: 20 },
]);

const cart = ref([]);

function addToCart(item) {
  cart.value.push(item);
}

function removeFromCart(item) {
  const index = cart.value.indexOf(item);
  if (index !== -1) {
    cart.value.splice(index, 1);
  }
}

const totalPrice = computed(() => {
  return cart.value.reduce((sum, item) => sum + item.price, 0);
});
</script>

Découpage en Composants

Nous allons diviser ce composant en plusieurs composants plus petits :

  1. ProductList.vue : Liste des produits.

  2. Cart.vue : Panier.

  3. ProductItem.vue : Élément de produit individuel.

Composant ProductItem.vue

<template>
  <li>
    {{ item.name }} - {{ item.price }}
    <button @click="addToCart">Add to cart</button>
  </li>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

const props = defineProps({
  item: Object
});

const emits = defineEmits(['add-to-cart']);

function addToCart() {
  emits('add-to-cart', props.item);
}
</script>

Composant ProductList.vue

<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
    <ul>
      <ProductItem
        v-for="item in items"
        :key="item.id"
        :item="item"
        @add-to-cart="addToCart"
      />
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ProductItem from './ProductItem.vue';

const title = ref('My Store');
const description = ref('Welcome to my store!');

const items = ref([
  { id: 1, name: 'Item A', price: 10 },
  { id: 2, name: 'Item B', price: 20 },
]);

function addToCart(item) {
  // Emitting an event to parent component
  emit('add-to-cart', item);
}
</script>

Composant Cart.vue

<template>
  <div>
    <h2>Cart</h2>
    <ul>
      <li v-for="item in cart" :key="item.id">
        {{ item.name }} - {{ item.price }}
        <button @click="removeFromCart(item)">Remove</button>
      </li>
    </ul>
    <p>Total: {{ totalPrice }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const cart = ref([]);

function removeFromCart(item) {
  const index = cart.value.indexOf(item);
  if (index !== -1) {
    cart.value.splice(index, 1);
  }
}

const totalPrice = computed(() => {
  return cart.value.reduce((sum, item) => sum + item.price, 0);
});
</script>

Composant Principal App.vue

<template>
  <div>
    <ProductList @add-to-cart="addToCart" />
    <Cart :cart="cart" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ProductList from './components/ProductList.vue';
import Cart from './components/Cart.vue';

const cart = ref([]);

function addToCart(item) {
  cart.value.push(item);
}
</script>

Avantages du Découpage en Composants

  1. Réutilisabilité : Les composants plus petits et autonomes peuvent être réutilisés dans différentes parties de votre application.

  2. Lisibilité : En séparant les différentes parties de l'application, le code devient plus lisible et plus facile à comprendre.

  3. Maintenabilité : Les composants séparés rendent la maintenance plus facile. Vous pouvez travailler sur une partie de l'application sans risquer de casser les autres parties.

  4. Tests : Les composants plus petits sont plus faciles à tester de manière isolée.

En suivant ces pratiques de découpage de composants, vous pouvez créer des applications Vue.js plus robustes et plus faciles à maintenir.


Mention des Sources

Cet article s'inspire du site officiel de Vue.js ainsi que de l'article de Michael Thiessen intitulé "Make Your Components Easier to Think About".