Web Components
O que são (conceito)
Web Components são um conjunto de especificações elaboradas para permitir a criação de elementos web de forma customizada e independente.
Sites construídos com esse conceito tornam-se mais fáceis de manter, isto porque a alteração realizada num elemento será replicada em todo o site, facilitando as alterações e aumentando a produtividade.
A ideia não tão recente, surgiu por volta de 2011 numa conferência de Alex Russell, realizada na Fronteers Conference. Em 2012, começou a ganhar força com sua especificação de uso publicada no W3.
Apesar das diferenças, a chegada de novas bibliotecas — como a ReactJs e posteriormente a VueJs — ajudou a popularizar essa *nova* forma de programar, que visa separar e encapsular o site em pequenas estruturas.
As bibliotecas supramencionadas possuem técnicas e funcionamento diferentes se comparadas ao Web Componentes.
Atualmente, o conjunto de especificações é dividido em 3 peças (ou elementos).
Peças/Elementos
Peça 1) Shadow DOM
O DOM, na programação/marcação web, é uma API que nos permite acessar ou manipular documentos HTML (e XML). Cada um desses documentos é criado por uma árvore de nós com subnós.
Documento HTML
<!DOCTYPE html>
<html>
<head>
<title>Olá</title>
</head>
<body>
<span style="color: red">Olá</span>
<span>Mundo</span>
</body>
</html>
Árvore de nós do documento supra
O Shadow DOM é semelhante ao explicado acima, a principal diferença está na capacidade que ele tem em definir o encapsulamento de uma árvore DOM, a fim de isolá-la do documento principal. Nos navegadores modernos, podemos ver essa técnica em vários elementos HTML.
O código <input type="date" />
, por exemplo, gerará uma árvore encapsulada, que — apesar de um CSS próprio — o código não interfere no restante do documento principal e também não é interferido.
Peça 2) Custom Elements
Como o próprio nome diz, esta peça fornece aos desenvolvedores uma maneira de criar elementos HTML personalizados, incluindo visualmente e com eventos específicos.
Adotado pelo Chromium em 2014 em modo experimental, a versão 0 (V0) — que foi descontinuada em 2016 — não foi implementada por outros navegadores, que passaram a utilizar as especificações da V1.
Exemplificação
Peça 3) Template
Esta é usada como um fragmento de documento (DocumentFragment). Apesar de ele ser adicionado no documento HTML, o navegador ignora-o durante a renderização. Via JavaScript, é possível clonar e modificá-lo antes de o inserir na árvore DOM.
Slots
Elementos slot são usados dentro do elemento template para indicar onde determinado(s) conteúdo(s) será(ão) renderizado(s).
Vantagens e Desvantagem ao usar Web Components
Vantagens
- Reutilização: Podemos utilizar o mesmo elemento em diversos lugares do projeto, de forma simples.
- Produtividade: A alteração do visual, forma ou adição de novos elemento é facilitada.
- Encapsulamento: Com um elemento encapsulado, é possível trabalhar com mais liberdade e evitando conflitos entre códigos.
- Nomenclatura eficiente: O encapsulamento permite que os atributos como class e id possam ser objetivos.
Desvantagens
- Compatibilidade: É possível usar algumas bibliotecas para tornar os elementos compatíveis com navegadores antigos, mas a falta de suporte nativo é uma desvantagem.
- Semântica: Navegadores e buscadores não entendem o significado do elemento
<emoji-picker />
. Isso pode ser contornado para os buscadores e leitores de tela. - Acessibilidade: Os elementos nativos possuem uma série de atributos que são utilizados pelos leitores de tela; nos customizados, a sua atenção deverá ser redobrada. É possível melhorar e adaptar essa questão.
- JavaScript: É necessário que o JavaScript esteja habilitado para componente funcionar. Navegadores com o recurso desabilitado ou de linha de comando (Lynx, por exemplo) poderão não funcionar corretamente.
Criando o primeiro componente
No primeiro exemplo, será criado um componente bem simples, cujo objetivo é dar boas vindas ao usuário.
Base
Comece criando o arquivo responsável pelo novo componente. No exemplo, ele chamar-se-á welcome.js.
Na linha 1 foi definido uma classe que estende os atributos e métodos o objeto HTMLElement. Todo componente deve ser filho da classe estendida, caso contrário o navegador não conseguirá executar e invocar os métodos necessários.
Na linha 2 e 3; foi, respectivamente, definida a função construtora e a invocação da função constructor da classe pai, que é obrigatória. A utilização dessa função é opcional. Ela é chamada durante a criação ou atualização do componente e pode ser usada para criação do ShadowRoot, criação de eventos que poderão ser utilizados. No entanto, ao usá-la, é necessário saber que há algumas restrições, são elas:
- A função super deve ser invocada logo após a criação do construtor;
- É proibido retornar um valor, exceto
return
oureturn this
; - A utilização das funções
document.write
edocument.open
é proibida; - Os atributos e filhos do elemento não devem ser inspecionados;
- O elemento não deve ganhar nenhum atributo ou filho. Essas alterações violam o método
createElement
ao ser usado para criação; - Evitem trabalhar com renderização no construtor, opte pelo método
connectedCallback
;
Na linha 5, criamos o ShadowRoot. Nele, vamos adicionar os elementos necessário para arenderização. Há dois modos possíveis:
- open: Permite que o código exterior tenha acesso aos elementos do componente usando o atributo shadowRoot, por exemplo:
document
.querySelector('v-placeholder')
.shadowRoot
.querySelector('div') - closed: Não permite que o código exterior tenha acesso aos elementos filhos do componente.
Na linha 8, foi definida a attributesChangedCallback
, que será invocada sempre que houver uma adição, atualização, remoção ou substituição de atributos. Para receber tais atualizações, é necessário reescrever o método estáticoobservedAttributes
e retornar um array de strings com os atributos que serão “ouvidos” (linhas 30, 31 e 32) do código Código 01 — Base.
Na linha 16, temos o métodoconnectedCallback
, será invocado quando o componente for adicionado ao DOM. Este método é recomendado para execução de códigos de instalação e renderização.
O método disconnectedCallback
, linha 26, é executado no momento que o elemento for removido do DOM. É ideal para remoção de eventos e limpeza do componente.
Na linha 35, foi definido o nome do componente e a classe responsável por ele. É importante o nome seguir a regra “caracteres-nome_do_componente”, dessa forma o navegador identificará que é um componente customizado.
Utilizando componente
Será abordada duas formas de utilização
Via HTML
No HTML, basta carregar o arquivo de script. A ordem não importa para o funcionamento, pode ser dentro do <head>
ou no final do <body>
. Após carregá-lo, basta utilizar a tag com o nome criado com o nome definido no primeiro parâmetro da função window.customElements.define
.
Via JavaScript
Você também pode usar a função document.createElement
para criar o elemento e el.setAttribute('atributo', 'valor')
para definir os valores necessários.
Resultado
Exemplo Adicional
Este é um exemplo um pouco mais complexo. Nele, utilizando o elemento <v-image>
para carregar um placeholder enquanto a imagem principal não é carregada. Também adicionamos suporte a alguns filtros e efeitos com CSS.
GitHub do Projeto
Conclusão
É isso! Os componentes estão aí para serem explorados e utilizados, obviamente dependendo do projeto e seu público alvo. Eles são uma mão na roda e realmente auxiliam bastante.
Caso tenham alguma dica ou sugestão, é só comentar. Agradeço-os pela leitura.
Projetos que utilizam Web Components
— https://lightroom.adobe.com/
— https://www.youtube.com/
— https://meet.google.com/
— https://photos.google.com/
— https://patternfly.github.io/patternfly-elements/
— https://github.com/
— https://www.polymer-project.org/
— https://en.miui.com/
Links úteis
Referências
> MDN (org.). Using custom elements. In: MOZILLA. Using custom elements. [S. l.], [20 — ]. Disponível em: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements. Acesso em: 3 jul. 2020.
WHATWG (org.). HTML: Scripting. [S. l.], [20 — ]. Disponível em: https://html.spec.whatwg.org/multipage/scripting.html. Acesso em: 8 jul. 2020.
WHATWG (org.). HTML: Custom elements. [S. l.], [20 — ]. Disponível em: https://html.spec.whatwg.org/multipage/custom-elements.html. Acesso em: 12 jul. 2020.
MDN (org.). Web Components: Using shadow DOM. [S. l.], [20 — ]. Disponível em: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM. Acesso em: 12 jul. 2020.
W3C (org.). Shadow DOM. [S. l.], [20 — ]. Disponível em: https://www.w3.org/TR/shadow-dom/. Acesso em: 3 jul. 2020.
HANASHIRO, Akira. O que é DOM, Virtual DOM e Shadow DOM?. [S. l.], 17 abr. 2020. Disponível em: https://www.treinaweb.com.br/blog/o-que-e-dom-virtual-dom-e-shadow-dom/. Acesso em: 16 jul. 2020.
GLAZKOV, Dimitri. What the Heck is Shadow DOM?. [S. l.], 14 jan. 2011. Disponível em: https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/. Acesso em: 16 jul. 2020.
https://github.com/mdn/web-components-examples