
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.