Como emitir eventos para comunicação entre componentes Vue
Uma arquitetura baseada em componentes para a construção de aplicações Web facilita o processo de construção e preservação das mesmas.
Um método de facilitar a comunicação entre componentes é através da emissão de eventos personalizados, enquanto a utilização de props e slots são duas opções adicionais. A utilização de eventos personalizados permite a transferência de dados de um componente filho para o seu homólogo pai.
Emitir eventos de um componente filho para seu pai
Um dos principais métodos pelos quais os componentes do Vue se comunicam entre si é através do uso de props, que permite a transferência de dados de um componente pai para um componente filho.
A comunicação entre componentes no Vue permite a emissão de eventos personalizados de um componente filho para o seu pai, permitindo assim que o pai utilize os dados e as funcionalidades do componente filho.
Considere-se um cenário em que existe um elemento de botão que recupera um valor a cada clique e requer a emissão deste evento para o componente principal, de modo a permitir que este último modifique o seu estado ou execute uma operação de acordo com o valor recuperado.
Convenção de nomenclatura para eventos personalizados emitidos no Vue
Antes de mergulhar no processo de emissão de eventos personalizados, é imperativo ter uma compreensão da nomenclatura utilizada pelo Vue para tais eventos. Antes do lançamento do Vue 3, os desenvolvedores eram obrigados a aderir a convenções rígidas ao criar eventos personalizados, empregando
Ao utilizar modelos HTML, é comum designar eventos personalizados em letras minúsculas com hífens separando as palavras, também conhecido como kebab-case. Por outro lado, ao trabalhar com JavaScript, é comum usar convenções de nomenclatura camelCase para eventos personalizados. No entanto, ambas as opções são aceitáveis ao programar em JavaScript, pois o Vue converterá automaticamente todos os eventos personalizados para kebab-case durante a compilação.
É imperativo que, ao gerar uma ocasião individualizada, a dote de uma denominação abrangente que reflicta com precisão o seu objetivo, uma vez que isto é de extrema importância, particularmente quando vários indivíduos estão a colaborar, de modo a garantir que o objetivo do evento é evidente.
Como emitir eventos personalizados do componente filho para o componente pai
Ao utilizar o modelo Vue, é possível empregar o método “$emit” fornecido pelo Vue para emitir eventos personalizados em linha ou tirar proveito da macro “defineEmits” introduzida no Vue 3.
Emitindo eventos personalizados no Vue com o método $emit
o nome do evento a ser emitido, juntamente com quaisquer dados adicionais que possam ser transmitidos.
O elemento subordinado está a enviar um evento para informar o elemento superior do acionamento de um botão.
<!-- ChildComponent.vue -->
<script setup>
import { ref } from 'vue';
const post = ref('')
</script>
<template>
<div>
<input type="text" v-model="post">
<button v-on:click="$emit('button-clicked', post)">Post</button>
</div>
</template>
O presente excerto de código demonstra o processo de envio de um evento personalizado a partir de um componente secundário. O componente secundário inicia uma variável post com uma cadeia de caracteres vazia como valor inicial.
O componente secundário estabelece subsequentemente uma correlação entre o elemento de entrada e a variável post utilizando as directivas v-model do Vue, que funciona como um mecanismo de ligação de dados. Consequentemente, quaisquer modificações feitas no campo de entrada são reflectidas no estado atualizado da variável post.
O elemento botão está equipado com uma diretiva imperativa, que monitoriza e regista todos os cliques efectuados sobre ele. Após a deteção de tal ocorrência, envia um evento com o nome “botão clicado” juntamente com o valor da variável post como argumento.
O componente principal é capaz de atender ao evento personalizado utilizando o
<!-- ParentComponent.vue -->
import { ref } from "vue";
import ChildComponent from "./components/ChildComponent.vue";
const postList = ref([])
const addPosts = (post) => {
postList.value.push(post)
}
</script>
<template>
<div>
<ChildComponent @button-clicked="addPosts"/>
<ul>
<li v-for="post in postList">{{ post }}</li>
</ul>
</div>
</template>
O presente excerto de código mostra um componente principal que importa e utiliza um componente secundário previamente definido. O componente pai engloba um objeto postList, que é estabelecido como uma referência reactiva. Subsequentemente, constitui uma função addPosts, que funciona após a receção de um parâmetro post. Esta função acrescenta o post dado à matriz postList utilizando o método push().
Ao clicar no botão dentro do ChildComponent, é acionado um ouvinte de eventos que capta o evento personalizado emitido pelo componente. Esse evento subsequentemente aciona a execução da função addPosts. Por fim, o código utiliza a macro
Emitindo eventos com a macro defineEmits
O Vue 3 introduziu a macro
defineEmits
, que especifica explicitamente os eventos que um componente é capaz de emitir. Esta disposição oferece uma forma organizada e sem tipos para declarar eventos, resultando numa base de código melhorada.
Segue-se uma demonstração de
<!-- ChildComponent.vue -->
<script setup>
import { ref } from "vue";
const emit = defineEmits(["button-clicked"]);
const post = ref("");
const buttonClick = () => {
emit("button-clicked", post.value);
};
</script>
<template>
<div>
<input type="text" v-model="post" />
<button v-on:click="buttonClick">Post</button>
</div>
</template>
Existem diferenças na sintaxe de codificação dos blocos de código acima referidos que conduzem a resultados distintos, apesar de manterem uma funcionalidade idêntica.
A macro
defineEmits
cria um evento personalizado para a ocasião “botão clicado” no bloco de código dado. Isto pode ser conseguido invocando a referida macro, que subsequentemente devolve uma função que permite a emissão dos eventos previamente definidos do componente filho para o seu homólogo pai. A informação relativa aos eventos necessários é armazenada na matriz fornecida e acedida pela macro defineEmits durante a sua execução.
O bloco de código dentro do componente filho estabelece uma função conhecida como “buttonClick”. Esta função é responsável por despoletar a emissão do evento “button-clicked” juntamente com a variável “post” para o elemento pai. O modelo HTML dentro do mesmo componente filho inclui um elemento botão que servirá como meio através do qual o utilizador pode interagir com a aplicação.
A utilização da diretiva
v-on:click
no elemento botão permite a ativação da função
buttonClick
após a interação do utilizador, permitindo que o componente pai interaja com o componente filho através dos seus eventos emitidos.
Os programadores Vue beneficiam de uma arquitetura baseada em componentes
É possível transmitir informações para baixo através de um componente filho para o seu pai, utilizando o método $emit em conjunto com a macro defineEmits.
A arquitetura baseada em componentes do Vue facilita a escrita de código organizado e sucinto através da sua implementação de Componentes Web, que é um padrão web W3C.