Comment réutiliser la logique dans Vue.js avec Composables

Lors de la programmation, il est important de structurer votre base de code afin de réutiliser le code lorsque cela est possible. La duplication de code peut gonfler la base de code et compliquer le débogage, en particulier dans les applications plus volumineuses.

Vue simplifie la réutilisation du code grâce aux composables. Les composables sont des fonctions qui encapsulent la logique et vous pouvez les réutiliser dans votre projet pour gérer des fonctionnalités similaires.

Était-ce toujours composables ?

Avant que Vue 3 n’introduise les composables, vous pouviez utiliser des mixins pour capturer du code et le réutiliser dans différentes parties de votre application. Les mixins contenaient des options Vue.js telles que des données, des méthodes et des hooks de cycle de vie, permettant la réutilisation du code sur plusieurs composants.

Pour créer des mixins, vous les structurez dans des fichiers séparés, puis vous les appliquez aux composants en ajoutant le mixin à la propriété mixins dans l’objet options du composant. Par exemple:

 
export const formValidationMixin = {
  data() {
    return {
      formData: {
        username: '',
        password: '',
      },
      formErrors: {
        username: '',
        password: '',
      },
    };
  },
  methods: {
    validateForm() {
      this.formErrors = {};
  
      if (!this.formData.username.trim()) {
        this.formErrors.username="Username is required.";
      }
  
      if (!this.formData.password.trim()) {
        this.formErrors.password = 'Password is required.';
      }
   
      return Object.keys(this.formErrors).length === 0;
    },
  },
};

Cet extrait de code montre le contenu d’un mixin pour valider les formulaires. Ce mixin héberge deux propriétés de données, formData et formErrors, initialement définies sur des valeurs vides.

formData stocke les données d’entrée du formulaire, y compris les champs de nom d’utilisateur et de mot de passe initialisés comme vides. formErrors reflète cette structure pour contenir des messages d’erreur potentiels, également initialement vides.

Le mixin contient également une méthode, validateForm(), pour vérifier que les champs nom d’utilisateur et mot de passe ne sont pas vides. Si l’un ou l’autre des champs est vide, il remplit la propriété de données formErrors avec un message d’erreur approprié.

La méthode renvoie true pour un formulaire valide, lorsque formErrors est vide. Vous pouvez utiliser le mixin en l’important dans votre composant Vue et en l’ajoutant à la propriété mixin de l’objet Options :

 <template>
  <div>
    <form @submit.prevent="submitForm">
      <div>
        <label for="username">Username:</label>
        <input type="text" id="username" v-model="formData.username" />
        <span class="error">{{ formErrors.username }}</span>
      </div>

      <div>
        <label for="password">Password:</label>
        <input type="password" id="password" v-model="formData.password" />
        <span class="error">{{ formErrors.password }}</span>
      </div>

      <button type="submit">Submit</button>
    </form>
  </div>
</template>

<script>
import { formValidation } from "./formValidation.js";

export default {
  mixins: [formValidation],
  methods: {
    submitForm() {
      if (this.validateForm()) {
        alert("Form submitted successfully!");
      } else {
        alert("Please correct the errors in the form.");
      }
    },
  },
};
</script>

<style>
.error {
  color: red;
}
</style>

Cet exemple montre un composant Vue écrit à l’aide de l’approche objet Options. La propriété mixins inclut tous les mixins que vous avez importés. Dans ce cas, le composant utilise la méthode validateForm du mixin formValidation pour informer l’utilisateur si la soumission du formulaire a réussi.

Comment utiliser les Composables

Un composable est un fichier JavaScript autonome doté de fonctions adaptées à des préoccupations ou à des exigences spécifiques. Vous pouvez exploiter l’API de composition de Vue dans un composable, en utilisant des fonctionnalités telles que les références et les références calculées.

Cet accès à l’API de composition permet de créer des fonctions qui s’intègrent dans différents composants. Ces fonctions renvoient un objet, que vous pouvez facilement importer et incorporer dans les composants Vue via la fonction de configuration de l’API Composition.

Créez un nouveau fichier JavaScript dans le répertoire src de votre projet pour utiliser un composable. Pour les projets plus importants, envisagez d’organiser un dossier dans src et de créer des fichiers JavaScript distincts pour différents composables, en vous assurant que le nom de chaque composable reflète son objectif.

Dans le fichier JavaScript, définissez la fonction dont vous avez besoin. Voici une restructuration du mixin formValidation en composable :

 
import { reactive } from 'vue';

export function useFormValidation() {
  const state = reactive({
    formData: {
      username: '',
      password: '',
    },
    formErrors: {
      username: '',
      password: '',
    },
  });

  function validateForm() {
    state.formErrors = {};

    if (!state.formData.username.trim()) {
      state.formErrors.username="Username is required.";
    }

    if (!state.formData.password.trim()) {
      state.formErrors.password = 'Password is required.';
    }

    return Object.keys(state.formErrors).length === 0;
  }

  return {
    state,
    validateForm,
  };
}

Cet extrait commence par importer la fonction réactive à partir du package vue. Il crée ensuite une fonction exportable, useFormValidation().

Cela continue en créant une variable réactive, state, qui héberge les propriétés formData et formErrors. L’extrait gère ensuite la validation du formulaire avec une approche très similaire au mixin. Enfin, il renvoie la variable d’état et la fonction validateForm en tant qu’objet.

Vous pouvez utiliser ce composable en important la fonction JavaScript depuis le fichier dans votre composant :

 <template>
  <div>
    <form @submit.prevent="submitForm">
      <div>
        <label for="username">Username:</label>
        <input type="text" id="username" v-model="state.formData.username" />
        <span class="error">{{ state.formErrors.username }}</span>
      </div>

      <div>
        <label for="password">Password:</label>
        <input type="password" id="password" v-model="state.formData.password" />
        <span class="error">{{ state.formErrors.password }}</span>
      </div>

      <button type="submit">Submit</button>
    </form>
  </div>
</template>

<script setup>
import { useFormValidation } from "./formValidation.js";
import { ref } from "vue";
const { state, validateForm } = useFormValidation();

const submitForm = () => {
  if (validateForm()) {
    alert("Form submitted successfully!");
  } else {
    alert("Please correct the errors in the form.");
  }
};
</script>

<style>
.error {
  color: red;
}
</style>

Après avoir importé le composable useFormValidation, ce code déstructure l’objet JavaScript qu’il renvoie et poursuit la validation du formulaire. Il indique si le formulaire soumis est un succès ou contient des erreurs.

Les Composables sont les nouveaux mixins

Alors que les mixins étaient utiles dans Vue 2 pour la réutilisation du code, les composables les ont remplacés dans Vue 3. Les composables offrent une approche plus structurée et maintenable pour réutiliser la logique dans les applications Vue.js, facilitant ainsi la création d’applications Web évolutives avec Vue.