Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 22, 2021 09:13 pm GMT

Web Components, comunicao entre componentes (parte 5)

Essa a quinta parte da srie de tutoriais sobre Web Components, no deixe de ver as outras partes. Neste tutorial vamos ver um pouco mais sobre algumas abordagens de como podemos fazer uma comunicao entre nossos componentes.

Eventos

Sim, j que todo componente que criamos se trata de um elemento HTML customizado, ns podemos ouvir e disparar eventos como qualquer outro elemento faz, alm de adicionar eventos customizados tambm. Eventos sero a forma mais comum que ter para fazer a comunicao entre os elementos.

Disparando eventos

Caso voc no sabia ns podemos disparar os eventos do HTML de forma programtica, sem a necessidade de interaes do usurio.

const clickEvent = new Event('click')document.querySelector('button').dispatchEvent(clickEvent)

Com esse simples cdigo voc ver que o evento atrelado ao boto foi disparado sem que houvesse um real click nele.

A classe Event recebe dois parmetros, sendo o primeiro o nome do evento e o segundo sendo um objeto de configurao para o evento, em que podemos configurar coisas como bubbles, cancelable, composed. Para saber mais olhe: https://developer.mozilla.org/en-US/docs/Web/API/Event/Event

Criando eventos personalizados

Utilizando de uma API muito parecida com a de eventos que acabamos de ver, podemos usar a classe CustomEvent para criar um evento customizado.

const formErrorEvent = new CustomEvent('form-error', {  detail: new Error('Form Error')})

Como pode ver a API praticamente a mesma, no caso dos custom events ns podemos passar o atributo detail em que podemos passar qualquer valor que queremos propagar a outros elementos.

Essa alis uma tima forma para fazer a comunicao entre os elementos.

Exemplo

Um simples exemplo usando um evento customizado:

<!-- HTML --><app-root></app-root>
// Javascriptclass AppForm extends HTMLElement {  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.shadowRoot.innerHTML = `      <form>        <input placeholder="Name" />        <button>Submit</button>      </form>    `  }  connectedCallback() {    const input = this.shadowRoot.querySelector('input')    const form = this.shadowRoot.querySelector('form')    form.addEventListener('submit', ev => {      ev.preventDefault()      if(!input.value) {        const formErrorEvent = new CustomEvent('form-error', {          detail: new Error('Empty name field')        })        this.dispatchEvent(formErrorEvent)      }    })  }}customElements.define('app-form', AppForm)class AppRoot extends HTMLElement {  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.shadowRoot.innerHTML = '<app-form></app-form>'  }  connectedCallback() {    this.shadowRoot      .querySelector('app-form')      .addEventListener('form-error', ev => {        console.log(ev.detail.message)      })  }}customElements.define('app-root', AppRoot)

API do componente

Eventos so muito teis quando queremos obter o valor do resultado de uma operao feita por outro elemento ou simplesmente de ser notificador quando algo ocorrer. Porm, existem situaes em que queremos simplesmente que o elemento mude seu comportamento ou estado atual, nessas situaes construir uma API a melhor forma de comunicao, pois ns pedimos ao elemento que ele faa algo e ele internamente faz o que for necessrio para que aquilo ocorra.

Exemplo

<!-- HTML --><app-root></app-root>
// Javascriptclass LightSwitch extends HTMLElement {  // Estado do elemento  #isOn = false  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.shadowRoot.innerHTML = `      <style>        div {          width: max-content;          padding: 14px;          border-radius: 6px;        }        .off {          background-color: #ddd;        }        .on {          background-color: #08c;        }      </style>      <div class="off">        <button>Toggle</button>      </div>    `  }  connectedCallback() {    this.shadowRoot      .querySelector('button')      .addEventListener('click', () => {        this.toggle()      })  }  /*    Mtodo pblico que pode ser usado    para mudar o estado do elemento  */  toggle() {    this.#isOn = !this.#isOn    const className = this.#isOn ? 'on' : 'off'    this.shadowRoot.querySelector('div').className = className  }}customElements.define('light-switch', LightSwitch)class AppRoot extends HTMLElement {  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.shadowRoot.innerHTML = `      <light-switch></light-switch>      <button>        Toggle from outside      </button>    `  }  connectedCallback() {    const lightSwitch = this.shadowRoot      .querySelector('light-switch')    this.shadowRoot      .querySelector('button')      .addEventListener('click', () => {        // Chamando o mtodo para alterar o estado do elemento        lightSwitch.toggle()      })  }}customElements.define('app-root', AppRoot)

Comunicao por terceiros

Por terceiros, me refiro a outros elementos ou estruturas na qual podemos delegar a parte da comunicao para uma entidade que no diretamente quem queremos impactar. Esse tipo de abordagem muito til quando queremos que algo seja refletido em vrios elementos de uma vez e/ou quando no sabemos quais elementos sero afetados. uma abordagem muito comum para o gerenciamento de estado, seja especfico a alguns componentes ou um estado global.

Devo enfatizar que essa somente uma forma de gerenciar essa parte de estado compartilhado e afins.

Exemplo

O exemplo abaixo simples, usando um objeto especfico para manter o estado de um contador e utilizando de eventos para capturar as mudanas que acontecerem.

<!-- HTML --><app-root></app-root>
// Javascriptclass CounterStore {  count = 0  #events = {    onCountChange: []   }  increment() {    this.count++    for(const event of this.#events.onCountChange) {      event()    }  }  onCountChange(listener) {    this.#events.onCountChange.push(listener)  }}const counterStore = new CounterStore()class AppRoot extends HTMLElement {  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.shadowRoot.innerHTML = `      <div>Count: ${counterStore.count}</div>      <button>Increment</button>    `  }  connectedCallback() {    this.shadowRoot      .querySelector('button')      .addEventListener('click', () => {        counterStore.increment()      })    counterStore.onCountChange(() => {      this.shadowRoot        .querySelector('div')        .innerText = `Count: ${counterStore.count}`    })  }}customElements.define('app-root', AppRoot)

Concluso

Agora voc viu como podemos mexer com a comunicao entre nossos Web Components, lembrando que isso que mostrei so s abordagens e que sempre bom lembrar que aqui estamos mexendo com Javascript puro, ento h espao para que voc crie sua prpria maneira de gerenciar isso. Espero muito que tenha gostado e caso tenha alguma dvida pode deixar nos comentrios e at o prximo!!!


Original Link: https://dev.to/gabrieljm/web-components-comunicacao-entre-componentes-parte-5-ido

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To