Ao criar componentes VueJs, sempre há preocupações sobre como eles podem se comunicar entre si. Com isso em mente, vejamos algumas abordagens diferentes para resolver esse problema.
Passando dados através de propriedades (props)
Uma maneira muito fácil de passar dados para um componente é usar propriedades (props). Toda instância do componente Vuejs possui seu próprio escopo isolado, e isso significa que não podemos acessar diretamente qualquer dado do componente pai em um componente filho. Os dados podem ser transmitidos para um componente filho usando props.
Props é um atributo Vuejs personalizado para passar dados de componentes pais para filhos. Isso é muito importante para lembrar: você não poderá compartilhar dados entre componentes usando props, a menos que sua intenção seja passar os dados de um componente pai para um componente filho.
O componente filho precisa declarar os props que espera que sejam passados a partir de um componente pai:
<script> export default { props: { myName: { type: String, required: true // default: 'Lucas' } } } </script>
Aqui esperamos uma propriedade chamada “myName”. Como você pode ver na linha 4, os props suportam um objeto como uma propriedade para fornecer alguma validação de dados, tais como: tipos de dados (string, number, object ou até uma function), valores exigíveis e padrão. Você pode ver as opções completas de validação de props aqui.
Agora, no componente pai, precisamos passar os dados para o nosso componente filho usando um atributo tsg v-bind. Esse valor de atributo deve ser o mesmo nome para aquele definido nos props do componente filho:
<template> <div class="component"> <h1>The User Component</h1> <div class="row"> <div class="col-xs-12 col-sm-6"> <app-user-detail :myName="name"></app-user-detail> </div> </div> </div> </template> <script> import UserDetail from './UserDetail.vue'; export default { data: function () { return { name: 'Lucas' }; } }, components: { appUserDetail: UserDetail } } </script>
Ao fazar isso, sempre que o atributo de dados “myName” mudar no componente pai, ele irá fluir para o componente filho.
Mesmo que o uso de props possa parecer uma maneira bastante fácil de compartilhar dados que exigem apenas algumas linhas de código, não é uma opção satisfatória se quisermos compartilhar dados em componentes irmãos (isto é, componentes no mesmo nível hierárquico).
Criando um bus de eventos globais
O padrão de bus de eventos pode ser uma maneira interessante de obter seções não relacionadas de seu aplicativo para conversarem umas com as outras. Ao usá-lo, podemos compartilhar dados adequadamente entre os componentes, apesar de seus níveis hierárquicos.
A primeira coisa que faremos para implementá-lo é criar o bus de eventos no nosso arquivo de módulo raiz (em um projeto gerado usando o vue-CLI,esse arquivo pode ser o app.js):
Tudo o que precisamos fazer aqui é importar a biblioteca do Vue e exportar uma instância do Vue (chamamos isso de eventBus).
Enviando eventos
Agora, temos que usar o bus de eventos no componente do qual queremos enviar dados. Aqui, usaremos como exemplo dois componentes: Server e ServerDetail. O que queremos é passar informações sobre um servidor para um componente chamado ServerDetail. O componente ServerDetail renderizará as informações do servidor de acordo com o servidor clicado pelo usuário no componente Server.
Primeiro precisamos importar o bus de eventos e, em seguida, podemos emitir eventos com os dados que queremos compartilhar com outro componente:
import Vue from 'vue' import App from './App.vue' export const eventBus = new Vue(); new Vue({ el: '#app', render: h => h(App) })
Os props estão sendo usados aqui na linha 15 apenas porque esses componentes também recebem uma propriedade server de outro componente. Os props não são necessários para usar o bus de eventos e eles não estão relacionados. Os props podem ser substituídos por uma propriedade comum de dados que retorna um objeto “server” com o atributo “id”.
Recebendo eventos
Agora, qualquer outro componente do seu app pode ouvir o evento “serverSelected” e usar os dados passados para o evento usando serverBus.$on. Veja o componente ServerDetails:
<template> <div class="col-xs-12 col-sm-6"> <p v-if="!server">Please select a server</p> <p v-else>Server #{{ server.id }} selected, Status {{ server.status }} </p> </div> </template> <script> import { serverBus } from '../../main'; export default { data: function () { return { server: null } }, created() { // Using the service bus serverBus.$on('serverSelected', (server) => { this.server = server; }); } } </script> <style></style>
Utilizamos o método $on dentro do método de atributo created(), apenas porque queremos ouvir o “serverSelected” desde o momento em que esse componente é criado (veja o ciclo de vida da instância Vue) para entender completamente o método criado. Depois disso, ao usar uma função arrow na linha 20, obtemos os dados do server do evento (passados pelo componente Server) e, em seguida, atribuímos ao this.server para que possamos usá-lo no nosso componente ServerDetails.
Passar dados através de eventos pode se tornar rapidamente uma enorme confusão se você estiver lidando com uma aplicação grande e mais complexa com muitos componentes. Consulte o VueX para conhecer uma abordagem melhor para gerenciar seus estados de objeto em toda a sua aplicação Vuejs.
Referências e links úteis
- Passing Data with Props
- Creating a Global Event Bus with Vue.js
- Vue Instance Lifecycle Hooks
- What is Vuex?
- Vue JS 2 – The Complete Guide (incl. Vue Router & Vuex): recomendo fortemente este curso!
***
Artigo traduzido com autorização do autor. Publicado originalmente em: http://andreybleme.com/2018-01-07/sharing-data-across-vuejs-components/