Comunicação entre Componentes no Vue 2.0: Props, Eventos Customizados e Event Bus

No desenvolvimento de aplicações com Vue.js, a arquitetura baseada em componentes exige estratégias eficientes para o compartilhamento de informações. A gestão de estado e a transferência de dados entre diferentes níveis da árvore de componentes são fundamentais para criar interfaces dinâmicas e reativas. Abaixo, exploramos as três abordagens mais comuns para a comunicação entre componentes no Vue 2.0.

1. Fluxo de Dados Descendente: De Pai para Filho (Props)

O método primário de enviar dados para componentes internos é através de props. Este mecanismo segue o princípio do fluxo de dados unidirecional, onde o componente pai "seringa" informações no componente filho.

Componente Principal (Pai):

<template>
 <div class="container-pai">
   <h2>Área do Pai</h2>
   <input type="text" v-model="usuarioLogado" placeholder="Digite o nome do usuário">
   
   <!-- Passando a propriedade para o componente filho -->
   <ExibicaoPerfil :nomeUsuario="usuarioLogado" />
 </div>
</template>

<script>
import ExibicaoPerfil from './ExibicaoPerfil.vue'

export default {
 components: { ExibicaoPerfil },
 data() {
   return {
     usuarioLogado: ''
   }
 }
}
</script>

Componente Interno (Filho):

<template>
 <div class="perfil-card">
   <p>Perfil Ativo: {{ nomeUsuario }}</p>
 </div>
</template>

<script>
export default {
 props: {
   nomeUsuario: {
     type: String,
     default: 'Visitante'
   }
 }
}
</script>

2. Comunicação Ascendente: De Filho para Pai (Eventos)

Para que um componente filho notifique o pai sobre mudanças ou ações do usuário, utilizamos a emissão de eventos customizados através do método $emit.

Componente Filho (Emissor):

<template>
 <div class="secao-filho">
   <button @click="notificarMudanca">Atualizar Status</button>
 </div>
</template>

<script>
export default {
 data() {
   return {
     novoStatus: 'Processado com Sucesso'
   }
 },
 methods: {
   notificarMudanca() {
     // Emite um evento chamado 'statusAlterado' carregando um payload
     this.$emit('statusAlterado', this.novoStatus);
   }
 }
}
</script>

Componente Pai (Receptor):

<template>
 <div>
   <p>Notificação do Sistema: {{ logMensagem }}</p>
   <!-- Escutando o evento emitido pelo filho -->
   <StatusCard @statusAlterado="atualizarInterface" />
 </div>
</template>

<script>
import StatusCard from './StatusCard.vue'

export default {
 components: { StatusCard },
 data() {
   return {
     logMensagem: 'Aguardando ação...'
   }
 },
 methods: {
   atualizarInterface(valor) {
     this.logMensagem = valor;
   }
 }
}
</script>

3. Comunicação entre Componentes sem Relação Direta (Event Bus)

Quando componentes que não possuem uma relação direta de parentesco precisam trocar informações, e a implementação do Vuex parece excessiva, utilizamos um Event Bus. Trata-se de uma instância isolada do Vue que atua como um hub central de eventos.

Configuração do Barramento (event-bus.js):

import Vue from 'vue';
export const EventBus = new Vue();

Componente Emissor (Componente A):

<template>
 <button @click="dispararAlerta">Enviar Alerta Global</button>
</template>

<script>
import { EventBus } from './event-bus.js';

export default {
 methods: {
   dispararAlerta() {
     EventBus.$emit('alertaGlobal', 'Nova atualização disponível!');
   }
 }
}
</script>

Componente Receptor (Componente B):

<template>
 <div class="notificacao-box">
   Mensagem: {{ alerta }}
 </div>
</template>

<script>
import { EventBus } from './event-bus.js';

export default {
 data() {
   return {
     alerta: ''
   }
 },
 created() {
   // Registra o listener quando o componente é criado
   EventBus.$on('alertaGlobal', (msg) => {
     this.alerta = msg;
   });
 },
 beforeDestroy() {
   // É importante remover o listener para evitar memory leaks
   EventBus.$off('alertaGlobal');
 }
}
</script>

Tags: vuejs frontend javascript vue-props event-bus

Publicado em 7-7 17:55