În procesul de dezvoltare software, o practică fundamentală este structurarea codului într-un mod care să permită reutilizarea eficientă a componentelor. Duplicarea codului nu doar mărește dimensiunea bazei de cod, dar complică și procesul de depanare, mai ales în cazul aplicațiilor de mari dimensiuni.
Vue oferă o soluție elegantă pentru reutilizarea codului prin intermediul „composables”. Acestea sunt funcții care încapsulează logică specifică și pot fi reutilizate în diverse părți ale unui proiect, facilitând gestionarea funcționalităților similare într-un mod centralizat.
Composables au fost întotdeauna soluția?
Înainte de introducerea „composables” în Vue 3, „mixins” erau principala metodă de a captura și reutiliza cod în cadrul aplicațiilor. „Mixins” conțineau opțiuni specifice Vue.js, cum ar fi date, metode și hook-uri de ciclu de viață, permițând astfel reutilizarea codului în multiple componente.
Pentru a crea „mixins”, acestea erau organizate în fișiere separate și apoi integrate în componente, adăugându-le la proprietatea „mixins” din obiectul de opțiuni al componentei. Exemplu:
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; }, }, };
Acest exemplu ilustrează conținutul unui mixin pentru validarea formularelor. Acest mixin include două proprietăți de date: „formData” și „formErrors”, ambele inițializate cu valori goale.
„formData” stochează datele de intrare ale formularului, inclusiv câmpurile pentru nume de utilizator și parolă, inițializate ca fiind goale. „formErrors” reflectă aceeași structură pentru a păstra potențialele mesaje de eroare, de asemenea, inițial goale.
Mixin-ul conține și o metodă, „validateForm()”, care verifică dacă câmpurile pentru nume de utilizator și parolă nu sunt goale. Dacă oricare dintre câmpuri este gol, aceasta actualizează proprietatea de date „formErrors” cu mesajul de eroare corespunzător.
Metoda returnează „true” pentru un formular valid, atunci când „formErrors” este gol. Mixin-ul poate fi utilizat prin importarea în componenta Vue și adăugarea la proprietatea „mixin” a obiectului de opțiuni:
<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>
Acest exemplu demonstrează o componentă Vue creată folosind abordarea obiectului „Options”. Proprietatea „mixins” include toate mixin-urile importate. În acest caz, componenta utilizează metoda „validateForm” din mixin-ul „formValidation” pentru a informa utilizatorul dacă trimiterea formularului a fost sau nu un succes.
Cum se utilizează „Composables”?
Un „composable” este un fișier JavaScript autonom care conține funcții adaptate la cerințe sau aspecte specifice. Se pot utiliza API-ul de compoziție Vue într-un „composable”, folosind funcții precum „refs” și „refs calculate”.
Acest acces la API-ul de compoziție permite crearea de funcții care se integrează în diverse componente. Aceste funcții returnează un obiect care poate fi importat și încorporat cu ușurință în componentele Vue prin intermediul funcției de configurare a API-ului de compoziție.
Pentru a utiliza un „composable”, se creează un fișier JavaScript în directorul „src” al proiectului. În cazul proiectelor mai mari, este recomandată organizarea într-un folder în „src” și crearea de fișiere JavaScript separate pentru diferite „composables”, având grijă ca denumirea fiecărui „composable” să reflecte scopul acestuia.
În interiorul fișierului JavaScript, se definește funcția necesară. Iată o restructurare a mixin-ului „formValidation” ca „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, }; }
Acest fragment începe prin importarea funcției „reactive” din pachetul „vue”. Apoi, creează o funcție exportabilă, „useFormValidation()”.
Continuă prin crearea unei variabile „reactive”, „state”, care găzduiește proprietățile „formData” și „formErrors”. Fragmentul se ocupă apoi de validarea formularului printr-o abordare foarte similară cu mixin-ul. În cele din urmă, returnează variabila de stare și funcția „validateForm” ca obiect.
Acest „composable” poate fi utilizat prin importarea funcției JavaScript din fișierul componentului:
<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>
După importul „composable”-ului „useFormValidation”, acest cod destructurează obiectul JavaScript returnat și continuă cu validarea formularului. Apoi, afișează o alertă pentru a indica dacă trimiterea formularului a fost un succes sau dacă există erori.
„Composables” reprezintă noua generație de mixin-uri
În timp ce mixin-urile au fost utile în Vue 2 pentru reutilizarea codului, „composables” le-au înlocuit în Vue 3. „Composables” oferă o abordare mai bine structurată și mai ușor de întreținut pentru reutilizarea logicii în aplicațiile Vue.js, facilitând astfel construirea de aplicații web scalabile cu Vue.