Na programação, é fundamental organizar seu código de maneira que permita a reutilização de componentes sempre que possível. A duplicação de código pode sobrecarregar o sistema e dificultar a depuração, principalmente em aplicações maiores.
O Vue facilita a reutilização de código por meio de “composables”. Composables são funções que agrupam a lógica, permitindo que você as empregue em todo o projeto para lidar com funcionalidades semelhantes.
A reutilização de código sempre foi feita com “composables”?
Antes do Vue 3 introduzir os “composables”, os mixins eram usados para capturar trechos de código e reutilizá-los em diversas partes da aplicação. Mixins continham opções do Vue.js, como dados, métodos e ganchos de ciclo de vida, permitindo a reutilização de código entre componentes.
Para criar mixins, você os organizava em arquivos separados e os aplicava aos componentes adicionando-os à propriedade `mixins` dentro do objeto de opções do componente. Por exemplo:
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; }, }, };
Este código mostra um mixin para validação de formulários. Ele contém duas propriedades de dados – `formData` e `formErrors` – inicialmente definidas com valores vazios.
`formData` armazena os dados de entrada do formulário, incluindo os campos de nome de usuário e senha, inicialmente vazios. `formErrors` espelha essa estrutura para conter mensagens de erro, também inicialmente vazias.
O mixin também possui um método, `validateForm()`, que verifica se os campos de nome de usuário e senha não estão vazios. Se um dos campos estiver vazio, ele preenche a propriedade de dados `formErrors` com a mensagem de erro adequada.
O método retorna `true` para um formulário válido, quando `formErrors` está vazio. Você pode usar o mixin importando-o para seu componente Vue e adicionando-o à propriedade `mixin` do objeto 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>
Este exemplo mostra um componente Vue usando a abordagem de objeto Options. A propriedade `mixins` inclui todos os mixins que você importou. Nesse caso, o componente usa o método `validateForm` do mixin `formValidation` para informar ao usuário se o envio do formulário foi bem-sucedido.
Como utilizar “composables”
Um “composable” é um arquivo JavaScript independente com funções adaptadas a necessidades específicas. Você pode aproveitar a API de Composição do Vue em um “composable”, usando recursos como `refs` e `computed refs`.
Este acesso à API de Composição permite criar funções que se integram em vários componentes. Essas funções retornam um objeto que você pode importar e utilizar facilmente nos componentes Vue através da função `setup` da API de Composição.
Crie um novo arquivo JavaScript no diretório `src` do seu projeto para usar um “composable”. Para projetos maiores, considere organizar uma pasta dentro de `src` e criar arquivos JavaScript separados para diferentes “composables”, garantindo que o nome de cada um reflita sua finalidade.
Dentro do arquivo JavaScript, defina a função necessária. Aqui está uma reestruturação do mixin `formValidation` como um “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, }; }
Este código começa importando a função `reactive` do pacote `vue`. Em seguida, cria uma função exportável, `useFormValidation()`.
Continua criando uma variável reativa, `state`, que abriga as propriedades `formData` e `formErrors`. O código então lida com a validação do formulário de maneira muito similar ao mixin. Por fim, retorna a variável de estado e a função `validateForm` como um objeto.
Você pode usar este “composable” importando a função JavaScript do arquivo para seu componente:
<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>
Após importar o “composable” `useFormValidation`, este código desestrutura o objeto JavaScript que ele retorna e continua com a validação do formulário. Ele alerta se o formulário enviado foi bem-sucedido ou contém erros.
“Composables” são os novos mixins
Embora os mixins fossem úteis no Vue 2 para reutilização de código, os “composables” os substituíram no Vue 3. Os “composables” fornecem uma abordagem mais estruturada e sustentável para reutilizar a lógica em aplicativos Vue.js, facilitando a construção de aplicações web escaláveis com o Vue.