Conceitos de Web Componentes no Frontend
Anotações com base no curso de Web Componentes da DIO
Shadow DOM
Shadow DOM - arvore fantasma para manipular componentes.
Trabalhar de maneira encapsulada sem ter que mecher em tudo.
Criando Componentes
Componentes: Nada mais é que uma função em js que vai retornar mais codigo js, html e css
// Nova class que hedará os comportamento html
/* retornará uma mensagem na pagina html*/
class CardNews extends HTMLElement {
constructor(){
super();
//esta classe criará uma sombra que pode ser "OPEN" ou 'Closed'
const shadow = this.attachShadow({mode: "open"})
shadow.innerHTML = "<h1>Hello World</h1>"
}
}
//criando elementos customizado que tera um apelido e o mode selector CardNews
customElements.define('card-news', CardNews)
Anatomia e vantagnes de componentes
Componentes são um conjunto de elementos, style e prop que podem ser aproveitadas de diversas formas e poder tralhalhar de forma isolada em uma só coisa
Estilizando um componente
class TituloDinamico extends HTMLElement {
constructor(){
super ();
//criando a variável para shadow
const shadow = this.attachShadow({mode: "open"});
//base do componente
const componentRoot = document.createElement("H1");
componentRoot.textContent = 'Ruan'
//estilizar o component
const style = document.createElement("style");
style.textContent = `
h1 {
color: blue;
}
`
//enviar para a shadow
shadow.appendChild(componentRoot);
shadow.appendChild(style);
}
}
customElements.define("titulo-dinamico", TituloDinamico)
obs: os estilos adicionando no components pertecem somente ao escopo do component
Criando uma Prop
class TituloDinamico extends HTMLElement {
constructor(){
super ();
const shadow = this.attachShadow({mode: "open"});
//base do componente
const componentRoot = document.createElement("H1");
//o conteudo que vier da prop/propriedade titulo será capturado
componentRoot.textContent = this.getAttribute('titulo');
//estilizar o component
const style = document.createElement("style");
style.textContent = `
h1 {
color: blue;
}
`
//enviar para a shadow
shadow.appendChild(componentRoot);
shadow.appendChild(style);
}
}
customElements.define("titulo-dinamico", TituloDinamico)
Componente de uma maneira mais profissional
class CardNews extends HTMLElement{
constructor(){
super();
const shadow = this.attachShadow({mode:"open"});
shadow.innerHTML= "<h1>Hello</h1>"
}
//construir novo método
build(){}
styles(){}
}
customElements.define("card-news",CardNews )
Setando classes
class CardNews extends HTMLElement {
constructor(){
//chama um construtor atravez do metodo super
super();
//esta classe criará uma sombra que pode ser "OPEN" ou 'Closed'
const shadow = this.attachShadow({mode: "closed"})
//adicionandp os dois metodos na shaow como filhos
shadow.appendChild(this.build())
shadow.appendChild(this.styles())
}
build(){
//criando elemento div
const componentRoot = document.createElement("div");
//setando class
componentRoot.setAttribute("class", "card")
const cardleft = document.createElement("div");
//setando class
cardleft.setAttribute("class", "card-left");
const cardright = document.createElement("div");
//setando class
cardright.setAttribute("class", "card-right")
//pedurando os dos filhos ao component pai
componentRoot.appendChild(cardleft);
componentRoot.appendChild(cardright);
return componentRoot;
}
styles(){
}
}
//criando elementos customizado que tera um apelido e o mode selector CardNews
customElements.define('card-news', CardNews)
Construindo Mais Props
class CardNews extends HTMLElement {
constructor(){
//chama um construtor atravez do metodo super
super();
//esta classe criará uma sombra que pode ser "OPEN" ou 'Closed'
const shadow = this.attachShadow({mode: "closed"})
//adicionandp os dois metodos na shaow como filhos
shadow.appendChild(this.build())
shadow.appendChild(this.styles())
}
build(){
//criando elemento div
const componentRoot = document.createElement("div");
//setando class
componentRoot.setAttribute("class", "card")
const cardleft = document.createElement("div");
//setando class
cardleft.setAttribute("class", "card-left");
//filhos do cardleft
const autor = document.createElement("span");
// duas condiçoes
autor.textContent = "by " + (this.getAttribute("autor") || " Anonymous");
const linktitle = document.createElement("a");
linktitle.textContent = this.getAttribute("Title")
const newsContent = document.createElement("p");
newsContent.textContent = this.getAttribute("content")
cardleft.appendChild(autor);
cardleft.appendChild(linktitle);
cardleft.appendChild(newsContent);
const cardright = document.createElement("div");
//setando class
cardright.setAttribute("class", "card-right");
const newsImage = document.createElement("img");
cardright.appendChild(newsImage);
//pedurando os dos filhos ao component pai
componentRoot.appendChild(cardleft);
componentRoot.appendChild(cardright);
return componentRoot;
}
styles(){
}
}
//criando elementos customizado que tera um apelido e o mode selector CardNews
customElements.define('card-news', CardNews)
Pegando as Props dos sub elementos do component
class CardNews extends HTMLElement {
constructor(){
//chama um construtor atravez do metodo super
super();
//esta classe criará uma sombra que pode ser "OPEN" ou 'Closed'
const shadow = this.attachShadow({mode: "closed"})
//adicionandp os dois metodos na shaow como filhos
shadow.appendChild(this.build())
shadow.appendChild(this.styles())
}
build(){
//criando elemento div
const componentRoot = document.createElement("div");
//setando class
componentRoot.setAttribute("class", "card")
const cardleft = document.createElement("div");
//setando class
cardleft.setAttribute("class", "card-left");
//filhos do cardleft
const autor = document.createElement("span");
autor.textContent = "by " + (this.getAttribute("autor") || " Anonymous");
//Props para o link
const linktitle = document.createElement("a");
linktitle.textContent = this.getAttribute("Title") ;
//acessando uma propriedade que o objeto ja tem
linktitle.href = this.getAttribute("link-url");
const newsContent = document.createElement("p");
//prop para conteudo do P
newsContent.textContent = this.getAttribute("content")
//anexando filhos ao cardleft
cardleft.appendChild(autor);
cardleft.appendChild(linktitle);
cardleft.appendChild(newsContent);
const cardright = document.createElement("div");
//setando class ao cardrigth
cardright.setAttribute("class", "card-right");
//criando elemento de imagem
const newsImage = document.createElement("img");
//criando prop e definindo uma imagem padrão caso der erro
newsImage.src = this.getAttribute("photo") || "assets/default.jpg";
//pegando propriedade ja existente
newsImage.alt = "image";
newsImage.textContent = this.getAttribute("photo")
cardright.appendChild(newsImage);
//pedurando os filhos ao component pai
componentRoot.appendChild(cardleft);
componentRoot.appendChild(cardright);
return componentRoot;
}
styles(){
}
}
//criando elementos customizado que tera um apelido e o mode selector CardNews
customElements.define('card-news', CardNews)
Adicionando Estilos em Web componentes
// Nova class que hedará os comportamento html
/* retornará uma mensagem na pagina html*/
class CardNews extends HTMLElement {
constructor(){
//chama um construtor atravez do metodo super
super();
//esta classe criará uma sombra que pode ser "OPEN" ou 'Closed'
const shadow = this.attachShadow({mode: "closed"})
//adicionandp os dois metodos na shaow como filhos
shadow.appendChild(this.build())
shadow.appendChild(this.styles())
}
build(){
//criando elemento div
const componentRoot = document.createElement("div");
//setando class
componentRoot.setAttribute("class", "card")
const cardleft = document.createElement("div");
//setando class
cardleft.setAttribute("class", "card-left");
//filhos do cardleft
const autor = document.createElement("span");
autor.textContent = "by " + (this.getAttribute("autor") || " Anonymous");
//Props para o link
const linktitle = document.createElement("a");
linktitle.textContent = this.getAttribute("Title") ;
//acessando uma propriedade que o objeto ja tem
linktitle.href = this.getAttribute("link-url");
const newsContent = document.createElement("p");
//prop para conteudo do P
newsContent.textContent = this.getAttribute("content")
//anexando filhos ao cardleft
cardleft.appendChild(autor);
cardleft.appendChild(linktitle);
cardleft.appendChild(newsContent);
const cardright = document.createElement("div");
//setando class ao cardrigth
cardright.setAttribute("class", "card-right");
//criando elemento de imagem
const newsImage = document.createElement("img");
//criando prop e definindo uma imagem padrão caso der erro
newsImage.src = this.getAttribute("photo") || "assets/default.jpg";
//pegando propriedade ja existente
newsImage.alt = "image";
newsImage.textContent = this.getAttribute("photo")
cardright.appendChild(newsImage);
//pedurando os filhos ao component pai
componentRoot.appendChild(cardleft);
componentRoot.appendChild(cardright);
return componentRoot;
}
styles(){
const style = document.createElement("style")
style.textContent = `
.card{
width: 800px;
display: flex;
margin-top: 10px;
flex-direction: row;
justify-content: space-between;
-webkit-box-shadow: 1px 0px 9px 4px rgba(0,0,0,0.75);
-moz-box-shadow: 1px 0px 9px 4px rgba(0,0,0,0.75);
box-shadow: 1px 0px 9px 4px rgba(0,0,0,0.75);
}
.card-left{
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 10px;
}
.card-left> a {
margin-top: 10px;
font-size: 25px;
color: black;
text-decoration: none;
font-weight: bold;
}
.cardleft >p{
color: gray;
}
.cardleft >span{
font-weight: 400;
}
`
return style;
}
}
//criando elementos customizado que tera um apelido e o mode selector CardNews
customElements.define('card-news', CardNews)