Transcrições
1. Introdução: Olá e seja bem-vindo a esta
classe em componentes da Web, seu guia para criar elementos HTML
personalizados com JavaScript. Sou
Christopher Dodd. Sou desenvolvedor
web freelancer e professor de
topo aqui
no SkillShare.com, cobrindo todas as coisas de
desenvolvimento web e freelancer
online. Na aula de hoje, vamos
aprender sobre o conjunto de quatro especificações que
compõem os componentes da Web, meta especificação
e como podemos usá-las para criar novas tags HTML personalizadas e reutilizáveis para
use em páginas da Web e aplicativos da web. Para aqueles
que têm experiência codificação com JavaScript, aprender a criar
elementos personalizados para seus aplicativos da Web e sites pode ser uma ferramenta útil para encapsular a funcionalidade, e estamos usando isso
em qualquer lugar dentro de um projeto específico ou
em vários projetos. Se você estiver pronto para
aprender a criar seus próprios
elementos HTML personalizados com JavaScript, clique no próximo vídeo e
eu o verei por dentro.
2. Componentes da web - um exemplo de vida real: Componentes da Web foi algo
que surgiu no meu radar dado o meu trabalho com sites de comércio eletrônico com
tecnologia Shopify. Era junho de 2021 quando Shopify revelou que seu
tema padrão havia sido atualizado para encapsular a maioria
da lógica JavaScript em cerca de 20 componentes
da Web diferentes, como modais, quantidade,
entradas, e muito mais. Eles até criaram seu
próprio componente deslizante não
requer bibliotecas
JavaScript externas. Embora eu não tenha
conseguido encontrar nenhuma declaração da
Shopify sobre o motivo pelo qual eles
escolheram criar seus
novos temas da loja online 2.0 como este, confio que, se
os componentes da Web fossem como Shopify, uma
empresa de tecnologia de US$multi-bilhões queria
estruturar a lógica de seus temas desenvolvidos
internamente, então essa era uma especificação para tomar nota e
aprender mais sobre. um site de comércio eletrônico, como aqueles normalmente hospedados
na Shopify Espera-se que um site de comércio eletrônico, como
aqueles normalmente hospedados
na Shopify, tenha algumas
funcionalidades comuns que podem ser encapsuladas por meio de componentes
da Web. Para usar o
tema Dawn da Shopify como exemplo, principais pontos de
interatividade,
como a tabela de itens
na página do carrinho, as opções para filtrar
produtos dentro de uma coleção e o formulário do produto, são todas as áreas em que
a funcionalidade pode ser empacotada em componentes
da Web separados. No final desta aula,
vamos tomar exemplo da
Shopify como
inspiração para criar nossa própria funcionalidade de
carrinho de compras consiste em três componentes
separados, que
consiste em três componentes
separados,
todos
interagindo com uns aos outros. Mas antes de chegarmos
lá, precisamos obter uma compreensão mais profunda da teoria por trás
dos componentes
da web. Começando com uma visão geral
das quatro
especificações de componentes da Web.
3. As 4 especificações de componentes de web: Para esta lição em particular, vou me referir
ao site
dedicado a ajudar
os desenvolvedores a compartilhar, descobrir e reutilizar
componentes da Web, components.org da web. Então, se você já está perdido em algum momento sobre a
seguinte teoria, você pode simplesmente verificar novamente em web components.org/specs
para acompanhar. Como está escrito aqui
no web components.org, os componentes
da web são uma
meta-especificação possibilitada por
outras quatro especificações. A especificação de elementos personalizados,
a
especificação DOM sombra,
a especificação do modelo HTML
e a especificação do módulo ES. Nesta lição, abordaremos
brevemente todas
essas especificações do ponto
de vista teórico e, nos próximos vídeos, analisaremos cada
especificação na prática. Vamos começar com elementos
personalizados. A
especificação de elementos personalizados é a
especificação fundamental que torna os componentes da web possíveis. Usando esse método de definição
no objeto de elementos personalizados, podemos definir um novo elemento
personalizado. O primeiro argumento é o
nome do elemento personalizado, que é o que usamos para
chamá-lo dentro do HTML. O segundo parâmetro
é o construtor, que é onde toda
a lógica irá. Podemos criar essa classe
construída estendendo a classe de elemento
HTML
ou uma classe de elemento
HTML nativo existente como no exemplo aqui, mas chegaremos a
isso um pouco mais tarde. Na maioria das vezes,
você estenderá a classe de elemento HTML normal
para criar seus componentes. Isso é chamado de elemento personalizado
anônimo. Aqui temos acesso ao
componente como ele existe no DOM através da
poderosa, essa palavra-chave. Cada vez que usamos o
elemento personalizado em nosso HTML, uma instância é criada e
podemos escrever código dentro dessa declaração de classe relacionado
especificamente à instância específica do componente. A próxima especificação
é o shadow DOM, que permite criar um DOM separado para
o DOM comum. O DOM regular, portanto,
às vezes é referido como o DOM leve para distingui-lo quando se fala sobre
a alternativa, que é a sombra DOM. A API shadow DOM
permite anexar uma subárvore DOM a elementos
dentro do documento da Web. O
DOM sombra anexado é encapsulado, o que
significa que as
informações de estilo dentro dele não podem se aplicar a
elementos externos e vice-versa. Podemos anexar o shadow DOM a qualquer elemento por meio do método de sombra
anexado. Mas, no contexto da
criação de componentes da Web, o shadow DOM é normalmente
criado diretamente
no próprio componente da Web
usando this.AttachShadow. Usando este objeto de raiz de sombra, podemos construir uma
subárvore de elementos, todos praticamente invisíveis para o DOM da luz principal. Em seguida, vamos falar sobre a especificação do modelo
HTML. Essa é simplesmente uma maneira
de criarmos uma estrutura HTML que não será renderizada
como HTML normal. Criamos um modelo
através da tag template, colocamos nosso HTML dentro
e quando a página é carregada, o HTML não é renderizado, mas ainda é acessível
via JavaScript. Como o nome sugere, podemos
usar essas tags para criar um código de
modelo que pode ser clonado e usado em vários locais. No contexto da
construção de um componente da Web, a tag de modelo pode ser
usada para definir o HTML do componente
clonando o HTML de dentro das tags e
colocando-o diretamente
no HTML interno do o componente
ou em seu shadow DOM. Finalmente, a
especificação do módulo ES define a inclusão e o uso de documentos
JS em
outros documentos JS. Embora não seja essencial para a
construção de componentes da Web, armazenar seus componentes da Web como código
modular que existe dentro seu próprio arquivo JS pode ser útil
para a estruturação de projetos, especialmente ao trazer
terceiros componentes da web. A sintaxe da
especificação é
importar seu
script externo como de costume, exceto desta vez você definir o
módulo como o parâmetro type. Em seguida, você escreve a entrada
seguida do caminho para o arquivo. Os recursos da especificação de
elementos personalizados,
a especificação SOMBRA DOM, a
especificação do modelo HTML e a especificação do módulo ES funcionam bem juntos para nos
ajudar a escrever de forma limpa, elementos HTML
personalizados encapsulados e reutilizáveis. Teoricamente, é apenas a
especificação
de elementos personalizados necessária para
criar elementos personalizados,
mas, como você verá
em vídeos posteriores, combinação
de recursos de cada especificação é muitas vezes a melhor maneira de tirar o
máximo proveito dos componentes da web.
4. Elementos personalizados parte 1: Agora que abordamos as quatro
especificações de componentes da Web no último vídeo, vamos analisar cada uma
delas em profundidade
e em ação dentro do
nosso editor de código. O que vou fazer é
iniciar um novo projeto. Tenho uma pasta
aqui para o meu código. Vou criar
uma nova pasta de projeto e vou
chamá-la de componentes da Web. Você pode chamá-lo do
que quiser. Então vou arrastar
isso para o meu editor de código, que é o Visual Studio Code, e isso
abrirá automaticamente essa pasta para nós. Em seguida, vou
fechar isso, clicar em novo arquivo aqui e criar um arquivo HTML. Vamos
chamá-lo de index.html. Agora, usando o Emmet dentro
do Visual Studio Code, posso gerar algum HTML
boilerplate
digitando o ponto de exclamação
e, em seguida, pressionando “Enter”. Vou alterar o título aqui apenas para componentes da Web. Então vou criar
o arquivo JavaScript, vou
chamá-lo de component.js porque vamos
trabalhar com um único componente primeiro. Vou fazer o clássico
hello world para o nosso console. Volte para aqui e, em seguida, a modificação
final que
preciso fazer começar é realmente
vincular esse arquivo JavaScript. Lá vamos nós. Agora, o que vou fazer é
voltar para nossa pasta e vamos abrir
isso no Google Chrome. É o Google Chrome para mim, mas você pode usar o
navegador que quiser. Vou usar a opção de
comando Eu para abrir minhas ferramentas de desenvolvedor aqui, e se eu for para o console, vou
aumentar isso para vocês,
vocês podem ver hello world, o que nos mostra que
estamos vinculando corretamente esse arquivo JavaScript
que criamos aqui. Incrível. Agora que isso está feito, vamos realmente criar
nosso primeiro componente da Web. Mais uma vez, há alguma
placa de caldeirinha nisso. Tudo o que temos que fazer, e isso será o
mesmo para cada componente da Web, além dos
personalizados integrados que veremos mais tarde, vou chamar
esse componente da web e como você pode ver aqui, a primeira letra de cada uma
das palavras neste
nome de classe aqui são maiúsculas. Essa é a convenção que usamos. Em seguida, digitamos extensões
e, em seguida, elementos HTML. Então aqui
precisamos de um construtor. Então chamamos a super função, que vamos
chamar toda vez que fizermos um componente web
e basicamente o que isso faz é herdar as funções construtivas
da classe que é estendendo-se. Precisamos disso
para aproveitar o que estamos
estendendo aqui. Em seguida, vamos até
aqui e finalizaremos isso executando o
método define em elementos personalizados. O primeiro parâmetro
será o nome
do elemento em
nosso documento HTML e, em seguida o segundo argumento é o nome da classe que
acabamos de criar aqui. Lá nós o temos, nosso
primeiro componente web. Agora, para trazer isso para o nosso front-end e
executá-lo em nosso HTML, agora temos essa tag personalizada disponível
para nós, componente da web. Isso é claro que é igual ao que dissemos aqui
neste método de definição. Talvez eu corra
isso lado a lado. Aqui vamos nós. Finalmente, para que possamos verificar se esse componente da Web está sendo construído
e executado na página, vou colocar um
login do console aqui e digitar
hello world novamente. Vamos voltar ao
nosso documento HTML, atualizar a página e você pode ver o hello world é o registro
do console. Se olharmos em nossa página aqui, você pode ver que isso é porque
chamamos esse elemento personalizado. Agora, até agora, isso não parece ser um uso prático de
usar isso, mas
à medida que avançamos
neste curso, você começará a ver
como os componentes da Web encapsula certas
funcionalidades para elementos específicos aqui . Uma das maneiras que
podemos ver isso é
usando a palavra-chave, esta. Se eu apenas digitar isso em um registro
HTML e console que, então poderemos fazer
referência ao que
colocamos entre essas tags. Vou colocar o
olá mundo lá. Vamos voltar
aqui, atualizar. Você pode ver que temos
algum conteúdo entre
essas tags de componentes da Web e, em seguida, isso também é ecoado aqui
em nosso console. Isso apenas mostrará que
podemos
usar o
próprio componente da Web como referência usando isso e, em seguida, fazer coisas
dentro desse componente, o que começaremos a
ver muito em breve. Esse é nosso componente básico da web. Em seguida, deixe-me
mostrar como podemos criar HTML interno dentro do
nosso componente da web. Vou fazer isso dentro método
do construtor porque isso é executado sempre que o
componente é construído. Vou escrever alguns comentários aqui. O primeiro método é
simplesmente definir o HTML interno. Vou
anotar isso. Podemos usar esse
HTML interno como
fizemos antes e, em vez
de produzi-lo,
podemos substituí-lo . Vou usar os ticks de trás
aqui para não ter nenhum problema com aspas,
sejam aspas duplas
ou aspas simples. O que vou fazer é criar
uma div e dentro da div criar uma extensão e, em seguida,
no intervalo, vou dizer, este é um componente da web. Novamente, se eu atualizar
aqui e depois
inspecionar esse elemento, você poderá ver que
inserimos esse HTML
no componente da Web. A segunda maneira de
fazer isso é
criando elementos e
adicionando-os ao DOM. Vou te mostrar como
fazemos isso agora. Vamos comentar isso e mostrarei a
segunda opção aqui. Vamos apenas mover isso
para que possamos ver mais disso. Talvez aumente o
tamanho da tela. Lá vamos nós. Então o que vou fazer
é usar o documento cria elemento e podemos
literalmente colocar o nome do elemento aqui
para criar um elemento. Mas precisamos
armazená-lo em algum lugar, então vou colocar um
const div na frente. Isso armazenará o elemento div
recém-criado nesta constante div. Então eu vou criar a
extensão que tínhamos antes. Estou criando exatamente a
mesma coisa que aqui em cima. O documento cria extensão do elemento. Então agora temos
nossa div e nossa extensão. Antes de anexar a
div ao nosso documento, vou atualizar
o HTML interno da extensão para
o que tínhamos antes, este é um componente da web. Então, o que posso fazer é usar esses métodos filho anexados para construir basicamente o DOM. Posso aninhar o vão
dentro da div, e então posso aninhar a div dentro do próprio
componente da web, assim. Agora, se eu voltar aqui, temos um problema. Esse problema é que
colocamos conteúdo aqui. Só vou
remover isso, salvar isso. Se voltarmos, lá vai você, teremos div com
o vão dentro. Essa é outra forma de fazer isso. A maneira final de fazer isso
é analisar uma string HTML. Vou
comentar isso e, em seguida,
escreverei o terceiro comentário, analisarei uma string HTML. Digamos, por exemplo, em uma situação específica,
eu tinha uma string HTML e queria colocar
a string HTML como HTML
dentro desse componente da web. Vamos criar isso de novo. A mesma coisa novamente, div
com uma extensão dentro, este é um componente da web, feche a extensão, feche a div. Então, o que eu preciso fazer
porque isso é uma string, eu preciso analisá-la. A maneira como posso analisá-lo
é usando o analisador DOM. Vejamos isso agora. Posso definir o
HTML interno const para o novo analisador DOM
e, em seguida, executar o método parse
from string, que tomará a
string HTML como seu primeiro argumento. Em seguida, o formato texto/HTML. Então o que isso vai fazer é
me dar esse DOM analisado. O que eu preciso fazer
é realmente encontrar o corpo e, em seguida, tirar o HTML
interno disso. Estou basicamente criando
um novo DOM com essa string HTML e
, em seguida, estou pegando o HTML interno do
corpo desse novo DOM. Então o que posso simplesmente fazer é dizer que esse HTML interno é
igual a HTML interno. Sendo este o componente da Web, estou definindo
o HTML do componente da Web para o HTML interno dessa string HTML
analisada. Tudo parece bom. Atualize aqui e
obtemos exatamente o mesmo resultado. Agora, não ficará
imediatamente claro para você por que você precisaria usar três métodos diferentes
ou qual método usar. Use qualquer método que
funcione para você, se este for o mais fácil e
você puder se
safar, definitivamente use esse. Mas há certas
situações em que talvez você esteja recebendo HTML
retornado de uma API, que é o
caso dos temas da Shopify, então você precisa usar
esse método de analisador DOM, ou talvez ele esteja recebendo um um pouco complicado com a criação novos elementos que
estão se encaixando em uma estrutura HTML mais complexa Nesse caso, você pode
querer usar esse método. Neste exemplo simples, parece que essa é a maneira mais fácil de
fazê-lo, o que é. Mas, à medida que os exemplos
ficam mais complexos, você pode começar a precisar usar uma combinação disso ou disso. O que eu queria fazer
nesta pequena seção era mostrar como
você pode fazer isso. A próxima coisa que quero
mostrar são atributos personalizados. Vou me
livrar de tudo isso. Não se preocupe, tudo isso
estará no link do GitHub, para que você possa ver esse
código sempre que quiser. O que eu quero mostrar agora
é que podemos realmente criar nossos próprios atributos
personalizados. Aqui nesta tag de componente da web, eu poderia digitar algo como texto ou qualquer parâmetro que
eu quisesse passar. Digamos que este
seja um componente da web. Tenho um parâmetro
pelo nome do texto e estou
analisando isso como um valor. Como usamos isso? Bem, vou
fechar isso. O que vou fazer é acessar esse atributo via
this.getAttribute. Em seguida, o argumento para isso é o
próprio nome do atributo, que é texto. Vamos apenas registrar
isso no console para começar. Em seguida, encontraremos um uso mais
prático disso. Atualizando aqui, se eu entrar no console, você poderá ver que este é
um componente da Web e que corresponde ao
parâmetro que defini aqui. Isso não é muito útil até agora. O que vou
fazer é o número 1, vou definir isso
em uma variável. Vou criar uma variável
dentro desse componente, então anexando-a a isso. Vou chamá-lo de conteúdo de texto
interno. Mas antes de fazer isso,
quero verificar se esse elemento realmente
tem esse atributo. Vou usar o método de atributo has analisando por texto
como o nome do atributo. Então eu vou colocar isso
no bloco if lá. Mais uma vez, isso deve funcionar. Não há erros aqui, não
há log do console, mas isso é porque
não registramos
nada do console ou mudamos
nada ainda. O que eu poderia fazer aqui
é como antes, usar o método
que tínhamos antes desse método simples de apenas
definir o HTML interno. O que vou fazer é usar essa mesma estrutura novamente com a div e a extensão aninhada. Mas no intervalo aninhado, vou colocar um valor dinâmico com base
nesse atributo. Como definimos essa
variável aqui, o que vou fazer é colocar isso aqui
this.InnerTextContent. Em seguida, atualize aqui. Você pode ver que temos o mesmo resultado do
que tínhamos antes. Vamos voltar ao nosso HTML. Se eu fosse mudar isso para, esse é um componente. Isso é o que é enviado
para o vão. Agora, o único problema
com isso é se voltarmos aqui
e digamos que temos um componente web bastante dinâmico aqui, onde esse valor
vai mudar. Se eu mudar isso para, este é um componente da Web, novamente, apenas não um componente.Você
verá que nada é atualizado. Isso porque,
na verdade, temos que
observar as alterações nos atributos, para que isso realmente mude. De volta ao arquivo component.js, falaremos mais sobre métodos de ciclo de
vida
na próxima seção. Mas, por enquanto, o que vou fazer é mostrar o método do ciclo de
vida que
podemos usar para verificar a mudança de
atributos. Aqui, nosso atributo certo
mudou o retorno de e leva três argumentos. O primeiro é o nome do
atributo em si. Vou dizer o nome attr. O segundo atributo
é o valor antigo, e o terceiro atributo
é o novo valor, o valor para o qual ele
será alterado. Então vou
colocá-lo em um cheque aqui. Se o nome atrr for texto, vamos atualizar
o HTML interno. Mantenha essa estrutura. Em vez desse conteúdo de texto
interno, vamos defini-lo para o novo valor que vem
no retorno de chamada. Isso pode
parecer o último passo, mas há mais um
passo que precisamos fazer, que é dizer ao componente
da Web para observar
esse atributo específico. Essa é apenas uma maneira os componentes
da Web ficarem
mais enxutos e se certificar que eles não estão
verificando atributos que não importam
para o programador. O que precisamos fazer para isso
é simplesmente digitar estático, obter atributos observados. Então, vamos
retornar uma matriz com todos os atributos
que queremos assistir, que é apenas texto. Vamos ao nosso
navegador aqui, atualize. Temos um erro de sintaxe. Isso é porque eu preciso colocar isso fora
do construtor. Este é o
método do construtor aqui. Preciso colocar isso lá fora,
refrescar aqui. Isso deve funcionar. Sem erros. Se eu entrar aqui e mudar, este é um componente para este é um componente da Web
ou qualquer outra coisa, você pode ver que o HTML
interno mudou. Executamos
esse método com sucesso aqui porque estamos verificando se há atributos observados
com o nome do texto. Verificamos se o nome do
atributo que vem através desse callback
é texto e, em caso afirmativo, atualizamos o HTML interno para essa nova estrutura HTML
com o novo valor. Já cobrimos
muito a ver com
a especificação de elementos personalizados. Vou dividir
a segunda metade
deste vídeo em uma parte 2. Na próxima parte, veremos métodos de ciclo e eventos personalizados.
5. Elementos personalizados: Neste vídeo da Parte 2, discutindo os recursos
da especificação de elementos personalizados, falaremos
sobre métodos de ciclo de vida e elementos personalizados. No último vídeo, na verdade,
vimos um desses métodos de ciclo de vida, o atributo mudar o retorno de chamada. Vou colocar
isso como número 3, sobre
o qual falaremos
em apenas um segundo. Um pouco de isenção de responsabilidade
aqui, vou
considerar o construtor número 1 aqui mesmo que tecnicamente não
seja um método de ciclo de vida, mas ajuda a olhar para o
construtor no contexto da
vida- métodos de ciclo de qualquer maneira. Há um segundo aqui, que revelarei muito em breve, e um quarto, que revelarei aqui. Vamos falar sobre o
construtor primeiro. O construtor, vou escrever
alguns aqui e vou colocar isso no
GitHub para vocês para que possam se referir a ele mais tarde. Deixe-me consertar esse erro de digitação. Isso é executado quando o componente
é criado na memória, mas não necessariamente
anexado ao DOM ainda. De acordo com minha pesquisa, esse é o melhor lugar
para a inicialização, mas não o melhor lugar para
interagir com o DOM. Agora, a diferença
entre o construtor e o próximo
é bastante sutil. Mas se você tiver
problemas
em colocar algo nessa função de construtor
e ela não funcionar, o próximo provavelmente é
onde você precisa colocá-lo, e esse é o retorno de chamada
conectado. Vou digitar isso aqui, retorno de chamada
conectado. Isso é executado quando o elemento é realmente
anexado ao DOM. Parece exatamente
assim, retorno de chamada conectado. Este terceiro,
como vimos antes, atributo alterado callback está simplesmente verificando se um
atributo foi alterado. Muito simples de entender. Este quarto que
vamos ver é o retorno de chamada desconectado, que é o oposto completo
do retorno de chamada conectado. Isso é executado quando o elemento
é desanexado do DOM. Você pode pensar, bem,
por que precisamos disso? É útil para
realizar a limpeza,
portanto, processos que não
queremos mais executar
quando nos livrarmos dela. Parece exatamente com
o retorno de chamada conectado exceto que o retorno de chamada
desconectado. Há mais um ou dois, mas esses são os principais. Vimos construtor,
vimos o retorno de chamada de mudança de atributo. Os dois que ainda não
vimos até que este vídeo esteja conectado
e desconectado. O que vou
fazer aqui é colocar
alguns logs do console e
, em seguida, posso mostrar como
é quando o callback
conectado é executado e o
retorno de chamada desconectado é executado. Tudo o que vou fazer é
dizer callback conectado
e, em seguida, escrever
aqui, retorno de chamada desconectado. Se eu executar esse código agora, se eu entrar no meu console, atualizar a página, você poderá ver o retorno de chamada
conectado executado. Se eu colocar em um log de console aqui, digamos construtor, e depois passarmos aqui, você pode ver o construtor e o retorno de chamada
conectado é executado. Aqui é onde acontece a
diferença sutil entre o
construtor e o
callback conectado. retorno de chamada conectado é
tecnicamente quando o elemento é anexado ao DOM e construtor é quando
ele é criado na memória. Mas os dois estão
acontecendo automaticamente quando colocamos esse componente
em nosso documento. Como posso
demonstrar a diferença entre
callback conectado e construtor? Bem, uma das maneiras que
posso mostrar isso é removendo programaticamente esse componente web do DOM, ainda tendo em uma memória
e depois reconectando-o. Isso é o que vou fazer
neste exemplo aqui. Logo acima da tag de script
JS do componente, vou criar
outra tag de script. O que vou fazer é pegar um controle do próprio componente
da web. Vou criar um componente da Web
variável
e, em seguida, usaremos o seletor de consulta de
documento para capturar o elemento do
componente da Web. Assim como faríamos com
qualquer outro elemento, podemos fazer isso com nossos próprios elementos
personalizados também. Então, o que vou
fazer é apenas basear isso no tempo limite para os propósitos
deste exemplo. Vou criar essa função de
tempo limite. Vamos executá-lo depois de um segundo. Então, dentro da função de
tempo limite, o que vou fazer
é remover filho no corpo
do documento e remover HTML do componente da Web do corpo do documento, apenas para reanexá-lo novamente. Componente web
filho DocumentBody.append. Basicamente, tudo o que isso
está fazendo é depois de
um segundo desta
página ser carregado, vamos remover esse componente web
do corpo no qual ele está atualmente e
colocá-lo de volta no corpo. Vamos atualizar aqui
e esperar um segundo. Você pode ver que a função de
construtor é executada uma vez porque o componente da Web
é criado uma vez na memória. Então, é claro, o retorno de chamada conectado
acontece
praticamente simultaneamente
com o construtor. Mas então o que vemos
depois de um segundo, se eu executar isso novamente,
depois de um segundo, que é o parâmetro que
colocamos aqui para o tempo limite, você verá que o callback
desconectado é executado porque estamos removendo
um componente da Web do DOM e, em seguida,
estamos colocando-o de volta para que o retorno de
chamada conectado seja executado novamente. Aqui você pode ver a diferença sutil
entre o construtor que está sendo criado a memória e a interação do
componente web com o DOM. Muitas vezes isso acontece
ao mesmo tempo. Mas se fôssemos pegar o componente da Web e
movê-lo ao redor do nosso DOM, o callback
conectado e o callback
desconectado são úteis. Demonstramos
dois em um lá. Mas se voltarmos aqui
e eu realmente
entrar na seção
de elementos das minhas ferramentas de desenvolvimento aqui, clique no componente da Web. Na verdade, vamos
limpar tudo isso. Clique neste elemento agora
e exclua-o do nosso DOM. Se eu for até a guia do console, você poderá ver que o
retorno de chamada desconectado foi executado novamente. Isso é basicamente o retorno de chamada
conectado e o retorno de chamada
desconectado. É simplesmente executado quando o
elemento é anexado
ao DOM e quando o elemento
é separado do DOM. Veremos como precisamos usar o callback
conectado
em um exemplo quando chegarmos aos
componentes da Web na prática mais tarde nesta
classe, mas por enquanto, até que você tenha um
problema em que você precisa usar o callback conectado, você provavelmente pode
usar apenas o construtor para todas as suas inicializações
e tudo o que você
deseja executar quando esse
componente da Web for criado. Depois de começar a encontrar problemas com o código
em execução dentro
do construtor, é quando você precisa começar
a examinar a função de retorno de chamada conectada. São
métodos de ciclo de vida. Finalmente, nesta
especificação de elementos personalizados, quero falar sobre eventos
personalizados. O que vou fazer é
limpar um pouco desse código. Vou me livrar
desse conjunto Timeout. Ainda vou manter meu componente web
nessa constante aqui. Acerte, “Salvar” nisso,
vá para cá. O que vou fazer é
atualizar esse HTML aqui. Vou ter que fazer isso duas vezes porque temos isso
aqui também. Só vou
criar um botão. Neste botão,
vou colocar
o evento
especial de gatilho de conteúdo. Vou copiar esse
código aqui. Quando o atributo muda, o que realmente acontece na primeira vez em que o
atributo é definido de qualquer maneira. Se não fizermos isso, se eu deixar isso desligado
e executar a página, você verá que o botão
não aparece qualquer maneira porque o atributo muda, retorno de chamada é executado assim que
reconhece esse atributo. Este não é o
código mais limpo, mas vamos copiar e colar isso aqui. Agora, se eu olhar para o meu componente aqui e clicar neste botão, faremos que ele faça
algo muito em breve. Vamos nos livrar
desses registros do console. Não precisamos mais deles. Podemos manter esse retorno de chamada
conectado lá. Vou me livrar
desses comentários aqui, aqueles que deixarei no
ramo relevante
do GitHub para que você possa fazer
referência a isso mais tarde. Vou me livrar
desses comentários por enquanto. Então o que vou fazer é
criar nosso próprio evento personalizado. Vou criar um
método que será executado em nosso EventListener, então acione um evento especial. Para criar
nosso próprio evento personalizado, podemos simplesmente atribuir um novo evento. No parâmetro aqui, podemos chamar o evento
onde quisermos. Só vou
chamá-lo de Especial. Agora esse novo evento, esse evento especial é armazenado nesta constante de evento especial. Quando esse método é executado, o que podemos fazer é
despachar esse evento
executando o evento de despacho. Então aqui correndo
um evento especial. Então, o que vamos
fazer aqui é ir ao retorno de chamada conectado e adicionar um ouvinte de eventos
ao evento de clique
no botão para executar
este evento especial. Vou encontrar o botão
dentro desse componente da Web, que podemos fazer por meio
desse seletor de consulta. Adicione EventListener,
procure o evento click. Em seguida, podemos executar este evento especial de
gatilho. Então vamos vincular isso,
portanto, permitindo-nos
referenciar isso como
o componente da web. Se o método bind o
confundir um pouco, não se preocupe. Isso me confundiu por
algum tempo também. Tudo o que ele faz é
garantir que essa palavra-chave dentro da função
esteja relacionada a isso, o componente da web, não a esta a função
ou qualquer outra coisa. É apenas um passo extra. Se não o
usarmos, acabaremos com isso, não sendo o que
pretendemos que fosse. Agora, o que vai acontecer é que quando clicarmos no botão, vamos acionar
esse evento especial que envia nosso
próprio evento personalizado, que é chamado de evento especial. Mas se eu clicar no botão,
nada realmente acontece. Tecnicamente, esse evento
especial é acionado, mas não estamos realmente ouvindo
esse evento especial. Nada realmente
atualiza na página. Vamos mudar isso. Vamos
entrar em nosso arquivo HTML aqui. Abaixo aqui em
nossa tag de script, vou adicionar esse EventListener
em nosso componente da web. Já armazenamos
nosso componente da Web aqui nessa constante, para que eu possa fazer o componente da Web,
adicionar EventListener. Podemos literalmente ouvir o evento especial
que criamos, para que possamos colocar em especial. Então, vamos colocar essa função anônima que
simplesmente irá consolar o log. O evento especial
foi acionado. Temos três passos aqui. Criamos um método de evento
especial que envia um
evento personalizado que chamamos de especial. Nós anexamos isso ao clique EventListener
no botão. Em seguida, vamos ouvir
esse evento especial no
próprio componente da Web e no log do console, o evento especial
foi acionado se esse evento tiver
sido despachado. Se voltarmos ao nosso
documento aqui e eu clicar em “Acionar evento especial”,
você pode ver que ele será executado, o evento especial
foi acionado. Se eu clicar nisso, você pode ver
o número sobe aqui. Obviamente, esse
exemplo simples não comunica a
necessidade de um evento personalizado. Mas quando você começar a ter elementos
mais complexos pode ser que você
queira ter um botão que
aciona o evento especial. Você quer ter
outra coisa que desencadeia
o evento especial. Só faz sentido
semanticamente ter um evento especial em
seu componente da web, então isso é útil. Um exemplo que você pode encontrar no mundo real são os Modals. Você pode ter um evento fechado
em um componente web modal. Esse evento fechado pode
ser acionado a partir de um clique de botão ou clicando fora do modal
ou clicando em Cancelar. Você tem três eventos diferentes
separados que
deseja acionar o mesmo evento no próprio componente da Web. Em seguida, você pode verificar fora do
seu componente da Web se o evento fechado
nesse componente da Web modal foi executado. Esse é um exemplo que eu vi
no mundo real por
usar elementos personalizados. Mas, novamente, eu simplifiquei
muito neste vídeo, o mais simples possível para
vocês verem isso em ação. Novamente, se você não sentir a
necessidade de usar esse recurso, não
precisará usá-lo. Mas se você vê isso
no mundo real e está
tentando entender o que está acontecendo quando você vê
algo assim,
bem, essa é a explicação. Podemos criar
eventos personalizados que podemos enviar em nosso componente da Web. Isso nos permite procurar eventos que acontecem no próprio componente
da web. É parte de toda essa
mentalidade de encapsular funções e eventos
dentro de um componente. Isso é tudo o que eu
queria falar sobre o tópico da especificação de
elementos personalizados. No próximo vídeo,
vamos
falar sobre o Shadow DOM.
6. O DOO de sombras: Bem-vindo de volta, pessoal. Neste vídeo, vamos
continuar de onde paramos com o último vídeo em termos
de nosso pequeno projeto aqui. Mas vamos
passar para algo chamado especificação Shadow
DOM,
que, como aprendemos
na seção de teoria, é uma maneira de
anexar uma sub-árvore DOM a um Componente Web
separado do DOM principal. Então, temos nosso DOM principal aqui como representado pelo nosso HTML. Podemos criar o que é
chamado de Shadow DOM em nosso Componente da Web ou em qualquer
elemento para esse assunto. E esse DOM é separado que é referido
às vezes como o Dom da Luz, que é sombra e
luz são opostos. Então, chamar
o DOM Regular de Luz Dom é uma maneira diferenciá-lo
do Shadow Dom. Você pode me ouvir referir
ao DOM Normal como o
Light Dom neste vídeo. Então, apenas uma nota lá. Então, o que vou
fazer é remover parte
desse código para os eventos personalizados. É um código um pouco tolo de qualquer maneira, que era apenas para
demonstrar um ponto. Então, vou me livrar
desse callback conectado
e desse evento especial. Nós realmente não precisamos, vou deixar o
Callback desconectado lá dentro. E vou até aqui
e removerei todo esse JavaScript adicional
do documento HTML. Então, vamos pular direto
e anexar um Shadow Dom ao nosso Componente Web
personalizado. Como fazemos isso é muito simples. O que fazemos é executar o
método, anexar sombra. E fazemos isso essa palavra-chave que se refere ao Componente Web, é claro. E tudo o que precisamos fazer é
passar em um objeto JavaScript. E vamos passar
no modo de “abrir”. Também podemos passar
no modo de “fechado”, mas é bastante irrelevante. Você pode procurar por que
passaríamos abertos ou fechados
fazendo alguma pesquisa, mas isso não é particularmente
importante agora. Então, o que vou fazer
é, em vez de ter nosso HTML inserido
diretamente no elemento, o que vou fazer é
colocar aqui Shadow Root. Agora, esta é uma palavra-chave especial
que nos permite anexar esse HTML interno à
raiz de sombra, que é o início da sub-árvore DOM dentro
do
nosso basicamente Shadow DOM. Deixe-me salvar o
que já é. Mude para nosso HTML. Eu também tenho um diagrama aqui. A propósito, eles se
abriram entre as aulas. Vou te mostrar isso
em apenas um segundo. E então vamos
atualizar aqui. Em seguida, vamos entrar em elementos e vamos clicar
nesse elemento. Agora você pode ver que
temos a
mesma coisa que tínhamos antes, mas também temos
uma raiz de sombra. Então, podemos clicar
aqui e dar uma olhada, e você pode ver que
temos esse HTML interno. Agora, a razão pela qual temos essa outra div lá também, acredito que é porque não
mudamos isso para sombra Root. Então eu vou mudar isso,
atualizar aqui. E agora você pode ver se
entramos em nosso Componente Web, não
temos essa
div e se estende por dentro, mas o que temos
é um Shadow Dom. E dentro desse Shadow Dom, temos uma div e a extensão,
e, claro, o botão
que não faz
mais nada dentro desse Shadow Dom. Você pode estar pensando
qual é a diferença entre anexá-lo
ao Shadow Dom versus anexar esse HTML diretamente ao Componente
da Web. E fico feliz que esteja se perguntando
isso porque é exatamente disso que vou falar agora
nesta tabela a seguir. Então, basicamente, o principal
com o Shadow Dom é CSS. Dado que o Shadow Dom é
separado do DOM principal, ele não herda o
CSS do Light Dom, como podemos ver aqui
nesta tabela. Se eu for para o conteúdo do
Shadow Dom, o Light Dom CSS
não se aplica. outro lado, qualquer CSS
dentro do Shadow Dom não se aplica ao
próprio Componente
da Web ou a qualquer conteúdo externo. No entanto, podemos
superar isso usando o pseudo-seletor hospedeiro de cólon, sobre
o qual falaremos
em apenas um segundo. Então, basicamente, esta tabela resume a
relação entre Light DOM CSS e o Shadow DOM CSS em relação ao próprio Componente
Web, conteúdo
ranhurado dentro
desse Componente da Web e o Conteúdo do Shadow DOM. Vou analisar cada um
desses exemplos muito em breve, mas vamos começar
com um exemplo básico para nos começar aqui. Isso é meio que pulando
para o próximo vídeo, mas vou criar um slot. Então deixe-me
entrar no componente aqui. E em vez de botão,
o que vou
fazer é criar um slot. Vou
copiá-lo aqui também. Claro, qualquer conteúdo
que eu ranquear aqui, entraremos em onde nossa tag de
slot foi definida. Então, o que vou fazer é
criar uma extensão e dizer que este é um elemento ranhurado. E então o que vou
fazer é começar a escrever algum CSS em nosso Light Dom. Então, vou atingir o vão e vou
dar a ele uma cor de vermelho. Clique em “Salvar” nessa
atualização aqui. E você pode ver que este é um elemento ranhurado e
a cor é de fato vermelha. Mas o que você
também deve ter notado é que dentro dessa div
há outro vão. E essa extensão não
assumiu o CSS em nosso Light Dom e isso é porque faz parte
da raiz de sombra. Então, se quiséssemos estilizar
essa tag em particular, o que faríamos é
entrar no componente aqui, e em qualquer lugar onde
criamos nosso HTML, criamos uma tag de estilo separada. E então podemos colorir
nossa extensão como tal. Vamos torná-lo verde. E novamente, não é o código
mais limpo, mas temos que copiar
isso aqui também. Vou clicar em “Salvar” nisso e
depois atualizar aqui. Você pode ver que a extensão
Shadow Dom é verde e a extensão
ranhurada é vermelha. Então este é o básico de
estilizar o Shadow Dom. Se você tiver um elemento
dentro do Shadow Dom, o estilo normalmente precisa acontecer dentro do
Shadow Dom também. E isso não afetará qualquer
extensão que esteja entalhada. Por outro lado, quaisquer elementos dentro do Shadow Dom não herdam os estilos
do Light Dom. Então, como você viu aqui, quando eu coloquei uma
regra de estilo para cor vermelha em vãos dentro
do Light Dom, isso não se aplicava à
extensão dentro do Shadow Dom. Então esse é o exemplo básico
de estilizar o Shadow Dom. Mas vamos realmente voltar ao nosso diagrama aqui e vamos passar por todos os
diferentes cenários. Portanto, o primeiro cenário usando o Light Dom CSS para estilizar
o próprio Componente Web. O que quero dizer com isso
é como estamos usando o nome do elemento
para direcionar esse intervalo. Também podemos fazer isso
com um Componente da Web. Então, ele funciona como
qualquer outro elemento HTML. Podemos apenas escrever
Componente da Web e vamos apenas dizer decoração de texto, sublinhar, salvar e atualizar sobre isso
e você pode ver que todo
o Componente Web
tem um sublinhado agora. Voltando aqui
para o Shadow Dom CSS, podemos realmente estilizar o
próprio Componente Web de dentro
do Shadow Dom usando um host de
dois pontos pseudo-seletor especial. Então, vamos voltar
e fazer isso agora. Então, se eu entrar em nosso
componente aqui, e antes de fazermos essa extensão
de verde, vamos fazer o host. Talvez vamos apenas deixar
o peso da fonte em negrito de tudo
no componente da web. Vou clicar em “Salvar” nisso,
atualizar aqui. Isso não está funcionando devido a
esse retorno de chamada de alteração de atributo. Vamos realmente limpar isso agora e fazer esse código limpo. Em vez de definir
exatamente o mesmo código duas vezes, o que farei é direcionar
o intervalo específico aqui e atualizar esse
valor para o novo valor. Em vez de definir
o HTML interno explicitamente na
raiz de sombra, voltarei aqui, encontrarei essa
extensão específica na raiz de sombra, depois direcionarei o
HTML interno dessa extensão
e, em seguida, defini-lo
como o novo valor. Isso é muito mais limpo. Dessa forma, mantemos a estrutura HTML
interna da nossa raiz sombra sem ter que atualizar a coisa
toda a vez. Isso deve fazer isso
funcionar agora, o que funciona, agora
temos todo o componente
da Web em negrito, e conseguimos fazer isso
dentro da raiz de sombra usando esse
pseudo-seletor de host. Vamos voltar para a mesa aqui. Vejamos o conteúdo
com fenda. O conteúdo ranhurado
no contexto
do Light DOM não é considerado parte do
Shadow DOM, portanto, os estilos
Light DOM se aplicam
aqui. Já vimos isso. Nós vimos isso no caso
deste vão aqui que
foi encaixado. A cor desse vão é vermelha. Novamente, como não é considerado
parte do Shadow DOM, os estilos Light DOM se aplicam aqui. Mas, como vimos antes
com o seletor de host, há uma maneira de estilizar esse conteúdo ranhurado
no Shadow DOM CSS também. Só precisamos usar a pseudo-classe com fenda de
dois pontos e precisamos passar
um parâmetro. Vamos fazer isso agora. Vamos para o nosso arquivo
component.js. Vamos colocar essa
pseudo-classe com fenda e o parâmetro. Vamos colocar a
extensão para estilizarmos o ranhura no vão. Deixe-me mudar a cor para, digamos, cinza. Então, se formos
aqui e nos atualizarmos, o que você acha que
vai acontecer? Vamos descobrir. Como você pode ver, não
há mudança
nessas cores. Por que isso? Se
dermos uma olhada neste segundo elemento aqui, que é o elemento ranhurado, e olharmos para os estilos aplicados, você pode ver que temos
nossa cor vermelha aqui, e então temos
nossa cor cinza para o vão, mas a cor
vermelha está sobrescrevendo. Isso é consistente
com o que
escrevi na tabela
aqui, que é, no caso de conflitos, os estilos do Light
DOM têm precedência. Você pode pensar, eu coloquei isso por
último para que o cinza
assumisse o controle, mas, no caso de haver
um estilo para aquele conteúdo
específico com fenda no Light DOM, o estilo no Light DOM
chega a controle a cor. Se quiséssemos estilizar esse fenda dentro do
nosso Shadow DOM, precisamos ter certeza de
que isso não está lá. Se eu comentar isso e
depois atualizar aqui, você pode ver que
podemos estilizar isso para cinza quando não for substituído por um estilo que se relaciona com o mesmo elemento
dentro do nosso Light DOM. Atualizando aqui,
vamos mantê-lo vermelho,
e vamos voltar para nossa linha final, além da exceção aqui para o conteúdo do Shadow DOM em nossa tabela. Qualquer Light DOM CSS
não terá efeito no nosso Shadow DOM. Acho que já podemos ver
alguns exemplos disso. Podemos ver que existe uma regra de cores para vermelho
em todos os elementos de extensão. Mas se entrarmos aqui, temos uma extensão no
nosso Shadow DOM e, claro, ainda está verde. Já vimos isso e, em seguida com o Shadow DOM
CSS, obviamente, qualquer CSS que criamos
no Shadow DOM terá um
efeito direto no Shadow DOM. Mais uma vez, vimos que com estilo do nosso elemento de extensão
dentro do Shadow DOM, você pode ver que ele é verde. Isso é basicamente
a mesa inteira. A única exceção é que as variáveis CSS
Light DOM estão acessíveis dentro
do Shadow DOM CSS. Se você já usou
variáveis CSS antes, basicamente como isso funciona é, em nosso Light DOM, podemos
criar algumas variáveis CSS. O que vou
fazer é, na raiz, criar uma variável CSS chamada cor
BG e
definiremos isso como preto. Então o que vou fazer é
entrar aqui e definir a cor de fundo para
a variável de cor BG, clicar em “Salvar” sobre isso,
atualizar aqui. Você pode ver que, mesmo que a variável CSS tenha sido
definida no Light DOM, ainda
podemos
trazê-la para o Shadow DOM. É só que a regra
CSS precisa estar no Shadow DOM CSS. Isso nos dá algum controle do conteúdo
do Shadow DOM em termos de uso de variáveis
dentro do nosso Light DOM. Se tivéssemos um esquema de cores, posso mudar isso para, vamos fazer isso amarelo
e clicar em “Salvar” sobre isso. Agora, você pode ver que podemos
atualizar valores dentro do Light DOM e
isso afetará o Shadow DOM ao
usar variáveis. Mas, além disso, se fôssemos entrar aqui e dizer span, fundo, cor de,
o que devemos fazer? Vamos ficar azuis. essa regra de extensão duas vezes, então vou apenas
comentar essa. Vou clicar em “Salvar”,
atualizar aqui. Você pode ver o fundo azul se aplica
somente ao conteúdo
com fenda. Ela não se aplica à
extensão dentro do Shadow DOM. Na verdade, não podemos alterar essa cor através do
Light DOM, a menos que, é
claro, façamos referência a
essas variáveis. Se alguma vez estiverem perdidos,
vou ligar vocês a esta mesa aqui. Vou colocar um link na sua tela
agora para que você possa
conferir quando eu
publicar esta aula. Mas, essencialmente, o Shadow
DOM é principalmente sobre CSS. É uma maneira de
corrigirmos o CSS de um
elemento, talvez se
estivéssemos compartilhando elementos em
diferentes projetos e quiséssemos que o elemento
parecesse exatamente o mesmo, não importa em qual
projeto ele estivesse, o Shadow DOM seria
útil. Mas dentro de seus próprios
aplicativos privados e páginas da Web, não
tenho certeza se o Shadow
DOM é muito necessário, e é por isso
que não
vamos usá-lo
no exemplo prático
no final desta aula. Mas é popular
nos componentes da Web , por isso era importante aprender esta lição sobre o Shadow DOM. Como sempre, tudo isso será confirmado com o GitHub, então você pode esperar
esse código mais tarde. Vou, claro,
compartilhar esta tabela com você, mas isso
resume o Shadow DOM. No próximo vídeo, vamos falar
sobre slots e modelos.
7. Slots e modelos: Bem-vindo de volta pessoal. Neste vídeo,
vamos falar sobre slots e modelos,
que são bastante básicos. Já usamos um slot
no vídeo anterior. Nós colocamos isso em
algum conteúdo aqui. Basicamente, aninhamos
uma extensão dentro desse componente da web
e, em seguida, pudemos escolher onde
queríamos que ele deslizasse para essa estrutura HTML específica
dentro do nosso shadow DOM. Dando uma olhada nisso
no navegador real, você pode ver que temos
nossa raiz sombra aqui. Se eu entrar na div e entrar neste
conteúdo com fenda aqui, você pode ver que há um link para o conteúdo ranhurado
que está bem aqui. É uma coisa estranha em que tecnicamente não faz parte
do shadow DOM, mas é encaixado
no shadow DOM aqui
através desta tag de slot. Agora já vimos
que, na prática, a próxima coisa a ser
analisada é nomear os slots,
então, se quisermos usar vários slots dentro de um componente da Web
específico. Para demonstrar isso, vou remover
todo o código que
realmente não precisamos para
essa demonstração. Novamente, podemos sair no callback
desconectado, mas vou me livrar
desse atributo aqui. Livre-se disso. Então
vou me livrar do atributo como ele
existe aqui no HTML. Vou criar
outro espaço aqui. Então eu vou
escrever que esse espaço também
foi encaixado. Se eu clicar em “Salvar” nisso,
vamos ver o que acontece agora. Se eu atualizar a
página, você pode ver que
há dois vãos
dentro deste slot. Mas o que podemos fazer
por meio de slots de nome é encaixar essas duas
extensões em diferentes partes
da mesma estrutura HTML.
O que quero dizer com isso? Bem, vamos
ao nosso
arquivo component.js aqui e vamos mudar isso. Vamos apenas dizer que temos duas divs. A primeira div terá um **** para a primeira
extensão e vamos criar outra div que se
separe àquela div e dentro será
a segunda extensão que eu rancho
no meu componente web. Uma vez
que nomeiamos esses slots, o que vai acontecer é que
esse espaço entrará no primeiro slot e esse vão
para o segundo slot. Podemos começar
no documento HTML ou
no documento JavaScript. Vou começar aqui
no JavaScript,
tudo o que tenho que fazer é
nomear o slot adicionando o parâmetro name aqui e então aqui eu
vou chamá-lo de Slot 1. Então vou descer para o segundo slot e
nomeá-lo de Slot 2. Então, no nosso index.html,
para
vinculá-los vou usar
o parâmetro slot, e vou usar
novamente esse nome,
então o Slot 1
e, em seguida, o slot é igual ao então o Slot 1
e, em seguida, Slot 2. Agora, se eu clicar em “Salvar”
e atualizar aqui, o que você acha que
isso vai acontecer? Vamos atualizar e vamos dar uma
olhada dentro. Como você pode ver, temos nossos dois
elementos com fenda aqui, mas em termos de onde eles se
encaixam em nossa estrutura de raiz de sombra, vamos abrir esse
bad boy e
podemos ver que temos duas divs. Na primeira div, temos
o primeiro conteúdo com fenda, e na segunda div,
temos o segundo conteúdo ranhurado. Agora eles estão em divs separados e talvez
precisemos disso para
o que precisamos fazer
com nossa estrutura HTML, então estilizar e outras coisas. É assim que podemos encaixar
em várias coisas em diferentes partes da
nossa estrutura de sombra DOM. Seguindo isso,
a próxima coisa que
quero mostrar são modelos. Vou remover
esse código aqui [NOISE] então vou
colocar em um HTML, as regras de estilo e
vou
voltar para index.html aqui. Vou entrar aqui e remover esse conteúdo porque
o que vamos fazer é colocar o conteúdo dentro de
um modelo e seguida, trazer esse conteúdo
para o componente da Web. Podemos fazer isso de duas maneiras. Tenho certeza de que podemos fazer
isso de várias maneiras, mas há duas maneiras de
mostrar a vocês neste vídeo. Poderíamos colocar a tag de modelo fora do componente da Web. Nesse caso, vamos
dar um ID a ele. Vou chamá-lo de
modelo por causa da simplicidade. Então aqui, vamos
criar nosso modelo. Vou apenas fazer um h1 e dizer que esse código de modelo
compõe o componente da Web. Em seguida, vou criar
uma tag de parágrafo e usando o Emmet dentro do
Visual Studio Code, posso digitar Lorem hit, “Tab” e ele gerará
Lorem Ipsum automaticamente. Eu só vou consertar o espaçamento aqui para que vocês possam ver o parágrafo
inteiro. Aperte, “Salvar” nisso. Agora, como esta
é uma tag de modelo, ela não será
renderizada em tempo de execução. Se eu voltar aqui, executar o código, você
verá que temos nosso código de
modelo aqui. Temos esse
fragmento de documento aqui, então temos o
código em nosso HTML, mas nada está renderizando e
isso é porque ele está
dentro de uma tag de modelo, o que significa que não será renderizado
a menos que tomemos esse código de modelo e
renderize-o usando JavaScript. Isso é exatamente o que
estou prestes a fazer. Vou voltar
para o nosso editor de código aqui e ir
para component.js. O que vou fazer é depois de
definirmos nosso HTML interno aqui, que é apenas a tag de estilo, o que vou fazer é
encontrar esse código de modelo. Como posso fazer isso é por seletor de consulta de
documento. Basicamente, eu só
quero encontrar esse elemento. Era um modelo com
o ID do modelo. É por isso que coloquei
hash na frente dele. Então vou encontrar
o conteúdo disso
e, em seguida, vou
executar o clone Node com
o parâmetro true. Com o parâmetro true
que representa um clone profundo, então todos os subelementos dentro do modelo também serão
renderizados. Eu realmente não consigo pensar em
uma situação em que você gostaria de ser falsa aqui. Vamos mantê-lo com verdade. É claro que vamos
precisar usar isso um pouco. Vou armazená-lo em uma
variável, uma constante primeiro. Agora, temos nosso modelo
const. Parece que
acidentalmente coloquei isso fora da função de
construtor, então vou colocar isso de volta
lá. Desculpe por isso. Agora, com esse modelo,
o que posso fazer é anexar esse nó clonado
à raiz de sombra. Vou pegar
a raiz de sombra aqui e executar anexar um filho, colocando esse código
de modelo lá como argumento. Vamos atualizar a página
aqui e ver o que acontece. Você pode ver que agora temos o código do modelo em execução
em nosso componente da Web. Se eu entrar no código
do componente web aqui, você pode ver que temos
nossa raiz de sombra e dentro da raiz de
sombra temos a tag de estilo que definimos explicitamente definindo
o HTML interno. Em seguida, temos a tag h1 e p que definimos
no modelo. O que também podemos fazer para tornar isso um pouco mais simples e encapsulado é colocar
a tag de modelo dentro do próprio componente da web. Vou apenas copiar isso
e depois comentar. Vamos entrar no componente
da web. Agora, como estamos dentro
do componente da Web, podemos apenas fazer referência ao elemento
do modelo
em vez de ter um ID. Vou clicar em
“Salvar” nisso e depois ir até aqui para o nosso código e o que podemos fazer
é tirar esse hash. Em vez de documento,
podemos dizer isso. Isso procurará qualquer modelo
dentro do nosso componente da Web. Vou clicar em “Salvar”
nisso, atualizar aqui, e você verá que obtemos
exatamente o mesmo resultado. Você pode ver que o modelo está
no componente da Web e, em seguida, o código que tínhamos
nesse modelo foi clonado dentro
do shadow DOM. Isso funciona da mesma forma como se não
estivéssemos usando o
shadow DOM. Vamos remover completamente a
sombra DOM. Na verdade,
vou comentar isso porque acho que podemos
usá-lo no próximo vídeo. Vamos apenas anexá-lo
ao HTML interno real. Atualize aqui e
você verá que não está anexando e isso é porque ainda
temos raiz de sombra aqui. Isso acrescenta a
atualização infantil aqui. Mais uma vez, não está funcionando.
O que fizemos? Não é possível ler propriedades de null. Acredito que o problema
aqui é que definimos em nosso HTML explicitamente, que está eliminando o conteúdo HTML dentro do componente da Web
que colocamos aqui, que é apenas essa tag de modelo. Nesse caso, o que eu faria é ir até
aqui e vamos
apenas nos livrar disso e apenas nos livrar vez disso, colocar isso diretamente
no modelo, o que é um pouco mais limpo de qualquer maneira. Vamos “Salvar” nisso e
, ao lado do modelo, colocarei a tag de estilo
diretamente em nosso HTML. Pressione “Salvar”
nessa atualização
aqui e o problema acabou agora. Dependendo de como
você quer fazer isso, isso realmente parece bem limpo porque não estamos colocando nenhum HTML dentro do
JavaScript. Estamos colocando todo o
HTML e os estilos que
entram em nosso componente
da web. Mas como não estamos mais usando
um shadow DOM, esses estilos teoricamente
se aplicarão a tudo. Se entrarmos aqui e colocarmos um vão, digamos que isso é um período. Atualize aqui. Os estilos do nosso
DOM leve que temos aqui e nossos estilos aqui dentro do componente web
serão aplicados. Se eu der uma olhada nisso, vamos dar uma olhada neste período
específico aqui. Você pode ver que a cor de fundo azul e
a cor de fundo
amarela estão aplicando. Mas como isso está acontecendo
mais tarde no documento, ele está substituindo
este aqui. Essencialmente, não
faz sentido uma tag de estilo aqui se pretendemos que isso aplique apenas
ao componente web,
nesse caso, gostaríamos de
ficar com o shadow DOM. Eu só vou para o backspace
aqui e de volta aqui. Vamos manter a sombra
DOM, atualizar aqui. Então, se eu fosse adicionar uma extensão ao nosso modelo
aqui, atualize. Inspecione esse elemento.
Você pode ver que nenhum dos estilos do DOM
claro
está se aplicando aqui porque esse código de
modelo está sendo colocado em um shadow DOM
e, portanto, apenas os estilos que
temos em nossa raiz de sombra se aplicará a ele. Coisas bem simples
de modelos aqui, muita flexibilidade dentro
disso, mas essencialmente, tudo o que é preciso é criar uma tag de
modelo e, em seguida, o que vamos fazer é
basicamente encontrar esse modelo, veja seu conteúdo e execute o clone Node para criar um nó DOM ou subárvore DOM com base nesse modelo e
, em seguida, podemos anexá-lo onde quisermos em
nosso componente da Web, seja à raiz sombra ou
para o HTML interno diretamente. Isso cobre slots e modelos. No próximo vídeo,
vamos
cobrir elementos
internos personalizados.
8. Elementos embutidos personalizados: Tudo bem pessoal. Neste
vídeo, vamos cobrir elementos
incorporados personalizados. Então, até este ponto, estamos estendendo
o HTMLElement raiz. Mas agora vamos estender
um HTMLElement específico, e isso é o que é
conhecido como construção um elemento interno personalizado. Então, o que vou
fazer é remover todo esse código porque
estamos criando esse código porque
estamos criando
um elemento totalmente novo e
, como estou fazendo isso, vou entrar no
meu índice aqui e remover todo esse código também. Podemos também remover
qualquer coisa dentro da nossa tag de estilo. Temos uma ardósia bem
limpa aqui. Então, para demonstrar um elemento incorporado
personalizado, estenderei o elemento do botão
HTML. Então, o que vamos
fazer é criar nosso próprio botão personalizado. Então, começando da
mesma forma que costumávamos escrevendo
aula e, em seguida,
vou chamar meu elemento de botão
personalizado, literalmente apenas CustomButton. Então vou escrever extensões e, em vez de
escrever HTMLElement, o que vou fazer
é HTMLButtonElement. Agora, se você estiver usando um editor de
código ou IDE, como o Visual Studio Code, você pode ver depois que
eu digito HTML, você pode ver uma lista completa de todos esses
elementos diferentes que posso usar. O formato é basicamente HTML, o nome do elemento
e, em seguida, elemento. Portanto, posso estender um elemento de
cabeçalho. Posso estender um elemento de imagem, um elemento de entrada, um rótulo, um link, tantas opções
diferentes aqui. Então, se você precisar navegar
pelas diferentes opções, não tem certeza de qual é
o nome da classe, isso realmente ajuda. Mas o que estou procurando
é um HTMLButtonElement, então vou acertar isso. Então vamos abri-la
como fizemos da última vez. Vou escrever
nosso método de
definição CustomElements , como fizemos anteriormente para componentes
web padrão, e vou fazer
o botão personalizado da tag. Então, como segundo
argumento, como de costume, vamos colocar
essa classe, mas aqui é onde ela fica
diferente novamente. Precisamos colocar em
um terceiro argumento. Precisamos colocar um objeto
JavaScript com um par de valores-chave. A chave será estendida
e o valor é a tag
do elemento que estamos
estendendo, portanto, para um botão HTML, a tag é claro botão. Se eu fosse escrever
isso no HTML, será como se
você estivesse basicamente
pegando a palavra
que está entre
o sinal menor que e
maior que e colocando-o
aqui depois que se estende. Se este fosse um
link personalizado, por exemplo, deixe-me trapacear usando o
preenchimento automático lá. Se estivéssemos estendendo
seu elemento de link HTML, isso mudaria para 'a', porque é isso que
a tag âncora é representada como no HTML. Mas estamos fazendo o
botão, então vou para Control Z até
voltarmos ao botão. Assim como fizemos anteriormente com componentes
web padrão, vou criar
um construtor aqui e, claro,
vou executar
super para que possamos herdar
a função de construtor da classe que
estamos estendendo, que era HTMLButtonElement. Então o que vou
fazer é ir para o nosso index.html aqui e
escrever algum HTML. Na verdade, vamos criar esse elemento incorporado
personalizado. A maneira como fazemos isso é diferente dos componentes
web padrão. Na verdade, vamos
usar o nome original
do elemento que estamos personalizando.
Vai ser botão. Dentro deste botão,
vou escrever pressione-me e depois aqui para transformá-lo em nosso elemento incorporado personalizado e não apenas um botão padrão, vamos usar
o atributo de is. Então, dentro daqui, botão personalizado, que corresponde ao que
escrevemos
no primeiro argumento do
nosso método definido aqui. Voltando aqui,
o que eu poderia fazer para este exemplo é
que vou colocar em um link. Vou colocar
um atributo personalizado de link e
vamos colocá-lo para google.com. Então, isso seria como um comportamento
padrão de uma tag de link talvez. Então, escreveríamos href
e, se
clicarmos no link, ele iria para
esse URL específico. Nesse caso, se
eu fizer isso
agora e voltar
ao nosso código
aqui e clicar em “
Pressione-me” nada vai acontecer porque esse é
um atributo personalizado. Ele não vai fazer
nada a menos que escrevamos algum código em nosso componente
aqui para lidar com isso. Então é exatamente isso que
vou fazer a seguir. Vou pegar esse
valor para isso.getAttribute. Então vou colocar
o nome do atributo no link
deles e,
claro, vou
armazená-lo em algum lugar. Vou armazená-lo no próprio componente
da Web, então vou dizer que
isso.link é igual ao valor deste link.
GetAttribute. Se eu quisesse, eu também
poderia fazer se
isso tiver um atributo
como fizemos antes, mas vou
presumir que ele tem isso porque estou no controle de escrever esse
código e vou certifique-se de que ele
tenha esse atributo. Então o que vou fazer é configurar um ouvinte de
eventos. Se esse elemento for clicado, clique em “Evento”, então
vou executar esse código. O que vou fazer é alterar a localização da janela href
para o valor deste.link. O que fizemos
aqui é que pegamos o valor dentro
do atributo link, armazenamos nessa variável
e, em seguida, criamos um ouvinte de eventos para o evento click
neste botão personalizado. Quando for clicado, ele
redirecionará o usuário
para o que armazenamos
nesse atributo de link. Então, vamos testar se isso funciona. Agora, vou atualizar
aqui e vou
clicar em “Pressione-me”
e, como você pode ver, vamos até google.com. Agora, novamente, não é o exemplo
mais prático porque poderíamos ter
usado apenas uma tag de link para isso. Mas deixe-me estender este
exemplo um pouco mais longe. Como temos um elemento
aqui que está herdando todo o comportamento original
de um elemento de botão, talvez
tenhamos que impedi-lo
de se comportar como um botão. Um exemplo disso
seria se estivesse dentro de um formulário. Vou ter um formulário
aqui e vou definir
a ação para endpoint
como exemplo. Isso obviamente enviará o formulário para lugar nenhum porque eu realmente não
tenho um endpoint. Isso se chama endpoint. Então, se eu clicar
em “Salvar” e eu atualizar aqui e
clicar em “Pressione-me”, você verá que ele herda o comportamento de um
botão dentro de um formulário, que é enviar o formulário. Então aqui você pode
ver que estamos indo para esse endpoint aqui
que não existe. Portanto, isso é claro que é
diferente se eu tivesse uma tag de link porque
temos uma tag de link, Número 1 ela não
apareceria assim
porque não é um botão. Número 2, uma tag de link
não aciona um cume de um formulário
se estiver dentro de um. Então, o que podemos fazer é
ir até o component.js aqui e posso ir
Event.preventDefault. Ele é salvo nessa
atualização aqui. Se eu clicar nisso, mesmo que esteja dentro de um formulário, ele impedirá esse comportamento padrão
e, em seguida, ele fará o que
dissemos para fazer, que é redirecionar o usuário para qualquer que seja o endereço
no atributo link. Voltando aqui, apenas
para perfurar esta casa, se eu fosse colocar
um botão padrão que não fosse um dos nossos elementos embutidos
personalizados e diga que você pode me pressionar
também e então eu
atualizo aqui. Se eu clicar no botão, você
pode me pressionar também, vai agir como um
botão padrão e enviar o formulário. Mas como personalizamos esse outro botão para evitar o padrão e, em vez disso, redirecionar
o usuário para google.com, ele se
comportará de forma diferente. Então, espero, novamente, não o exemplo
mais prático, mas espero que isso comunique o que podemos fazer com elementos. Podemos pegar alguns
dos comportamentos e atributos
de um elemento que gostamos, e podemos
modificá-los para nossos propósitos. Obviamente, há
quantidades insanas de flexibilidade aqui. Você pode tomar isso em
qualquer direção que quiser, mas isso não é algo
que vamos
usar particularmente na
seção prática desta classe, apenas algo para manter
nota porque ela cai sob a especificação
do componente web. Podemos estender
elementos específicos aqui, e isso é o que é conhecido como elementos internos
personalizados. Pessoal, então no próximo vídeo, o que vamos fazer é cobrir especificação final
da qual ainda não
falamos, que é a especificação dos
módulos ES. Vejo você no próximo vídeo.
9. Módulos ES: Pessoal, então neste vídeo
final antes de
entrarmos em nosso projeto prático de
aula, vamos falar sobre os módulos ES, que é a quarta
especificação dentro da
meta-especificação de componentes da web. Os módulos ES são
essencialmente uma maneira de estruturarmos nosso
projeto de forma diferente. Podemos colocar cada um de
nossos componentes em seu próprio
arquivo JavaScript modular e,
em seguida, trazê-lo para outro
arquivo JavaScript e, em seguida, trazer esse arquivo JavaScript
para o nosso documento HTML. Ou, alternativamente,
podemos apenas trazer cada componente em nosso
documento HTML sem esse arquivo. Mas nos exemplos
que vou mostrar, vou importar todos
os componentes para um
único arquivo JavaScript
e, em seguida, colocaremos isso em nosso documento HTML. Alguns projetos, isso
vai ser muito útil, alguns projetos não vão
fazer sentido algum. Vamos usar os módulos ES
na prática que
vem depois desta lição. Isso será algo que
veremos em ação muito em breve, mas para esta lição, vamos realmente
demonstrar módulos ES. Como eu disse, o que vou
fazer é
importar todos os nossos componentes, agora há apenas um mas vou
transformar um segundo em um arquivo JavaScript central, e vou chame
esse index.js. Agora, o que vou
fazer para começar, vamos fechar isso para que
possamos ver a coisa toda, é
que vou mover esse
método de definição de elementos
personalizados aqui e movê-lo para o nosso index.js. Para que tenhamos acesso
a essa classe aqui, o que vou ter que
fazer é exportá-la
daqui e depois
importá-la para aqui. Primeiro de tudo, porque
só temos a única classe aqui, não
vou
fazer uma exportação nomeada, vou fazer uma exportação
sem nome. Eu apenas exporto o padrão e, em seguida, o
nome da classe que eu quero exportar. O que isso faz é
exportar apenas essa classe,
então, uma vez que eu a importar aqui, posso referenciá-la
diretamente em nosso código aqui. Vou executar a instrução
import aqui, estamos procurando um
botão personalizado e depois,
depois da palavra-chave from aqui, coloco o caminho para o arquivo. Agora, que eu fiz isso,
o que preciso fazer é atualizar
o código aqui, então, em vez de component.js, coloquei index.js. Como vimos na aula de teoria, preciso alterar ou adicionar o atributo aqui
do módulo de tipo. Vou clicar em “Salvar” nisso. Vamos atualizar aqui. Devemos ver que ainda temos esses botões, mas se eu
clicar no primeiro, que é nosso elemento
incorporado personalizado, você pode ver que
temos a mesma funcionalidade que um botão
padrão. Ambos são
exatamente os mesmos. O motivo está aqui
em nosso Console JavaScript. Temos um erro de política CORS
aqui e a razão é porque realmente não podemos fazer isso executando o HTML
do sistema de arquivos. O que precisamos fazer
é executar um servidor. Isso é muito fácil dentro do código
do Visual Studio. Espero que seja fácil e simples o suficiente no seu IDE também. Caso contrário, você sempre pode usar o Visual Studio Code e
vou apenas ir aqui
e clicar em Go Live. Agora você pode ver que estamos
executando um servidor. A maneira como posso ver isso é
porque temos um endereço IP aqui em vez de um caminho
do sistema de arquivos. Agora, se eu pressionar Command Option I para
abrir o console, você não poderá ver erros
e se eu clicar em “Pressione-me”, ele me
levará ao Google em vez do endpoint
que ele está procurando aqui. Vou
fechar este no sistema de arquivos e
usaremos este. Aqui, você pode ver tudo
isso já funcionando. Importamos o código do
component.js para index.js
e, em seguida, importamos
isso para index.html. Mas isso
realmente não faz sentido
e, portanto, criamos
outro componente. Vou criar um
segundo componente aqui. Isso é um nome terrível,
mas vou chamá-lo de componente 2. Sabe o quê? Apenas por diversão, vamos criar outro elemento incorporado
personalizado. Vou escrever uma
classe e vamos estender o elemento link para
criar um link personalizado. Vou escrever link personalizado estende HTML, elemento âncora. Abra isso aqui, obviamente vou
colocar o construtor. Então vou chamar super
como sempre fizemos. Para isso, o que eu poderia fazer é adicionar ouvinte de eventos para clique, [NOISE] isso é
semelhante ao que fizemos antes, mas agora temos o comportamento padrão
de uma tag âncora. O que vou fazer é basicamente tornar este
um link de confirmação. Vou executar Confirmar e pedir
ao usuário que confirme que
deseja usar o Google. Você quer usar o Google
e, em seguida, se isso voltar tão falso quanto você pode ver neste
ponto de exclamação aqui, então eu vou
evitar o padrão. Vou impedir que o
usuário use esse link. Exemplo bastante básico lá. Então, é claro,
vou exportar isso, e como estamos
exportando apenas uma classe, posso usar o padrão aqui. Vamos
exportar link personalizado
e, em seguida, vamos
para index.js e usar o mesmo formato. Vou importar o botão
personalizado do component2.js e, em seguida, escreveremos nosso
método definido aqui,
então elementos personalizados, definam, chamem de link de traço
personalizado. Em seguida, colocamos o nome da classe, é o segundo argumento. Então, em nossas extensões aqui, estaremos estendendo
o elemento âncora padrão, que é representado apenas
como um no HTML. Se eu, então,
ir para o meu index.html, já
estamos importando
todo esse código. Tudo o que preciso fazer é simplesmente
escrever uma tag aqui. Vamos fazer com que ele vá
para o Google novamente. Então, é claro,
para assumir
a funcionalidade desse elemento incorporado
personalizado, terei que escrever é e, em seguida, dentro
do atributo is, coloque o nome que
especificamos qual é um link personalizado e, em seguida,
vou clicar com o botão direito do mouse para ir ao Google. Aperte, “Salvar” nisso.
Vamos atualizar aqui. Você pode ver o link lá. Nem precisávamos atualizar porque estamos usando o Live Server, que é apenas um recurso
no Visual Studio Code. Isso é chamado de recarga a quente. Então, se eu clicar nisso, vai me perguntar
se eu definitivamente
gostaria de ir ao Google. Se eu clicar em “Cancelar”, isso evitará o comportamento padrão, que está
me direcionando para esse endereço. Mas se eu clicar nele e clicar em “Ok”, ele vai me
direcionar para lá. A funcionalidade dentro
do componente real em si não é o
ponto aqui. O ponto é nossa capacidade de
exportar classes de documentos
JavaScript para
outros documentos JavaScript e em documentos HTML
usando módulos ES. Espero que seja
um conceito legal para vocês que
acabaram de aprender. No próximo vídeo, vamos começar a
criar isso como uma aplicação prática. Nesse vídeo, talvez vários vídeos,
dependendo de quanto tempo vamos, você nos verá usando
módulos ES em ação e, portanto,
verá isso na prática um
pouco mais nos próximos vídeos. Essas são basicamente todas
as quatro especificações para a
meta-especificação de componentes da web. Vamos realmente colocar
isso em prática
no próximo vídeo e criar
nosso próprio projeto personalizado.
10. Componentes de web em prática parte 1: Tudo bem, todos. Bem-vindo à parte prática
baseada em projetos da classe. Recebo o feedback
de
vocês regularmente de que você quer
ver exemplos mais práticos. Neste curso até agora, não
vimos muitos
deles se estou sendo honesto. Sem ter
alguns componentes da Web trabalhando juntos e
sem um caso de uso, é
difícil demonstrar casos de uso práticos
reais de componentes da
Web e muitas
dessas especificações que você não precisa usar
ao mesmo tempo. Por exemplo, neste projeto
que estamos prestes a criar, não
estou usando o
Shadow DOM porque não sinto
necessidade de usá-lo, a menos que
eu esteja tentando manter meu Shadow DOM separado
e o que quero dizer com separar como em estilo CSS
separado para o resto do meu projeto. Se eu estiver no controle
do meu próprio projeto, então eu realmente não
sinto a necessidade criar um Shadow
DOM porque sim, talvez eu queira que os estilos do Light DOM
afetem o Shadow DOM. Misture e combine todos os
recursos de qualquer especificação
que faça sentido para você. Espero que você tenha aprendido alguns bons fundamentos
nesta classe, mas eu queria incluir uma
lição mais prática baseada em projetos para vocês. Isso provavelmente
terá que ser dividido em várias lições, então isso pode aparecer como vários vídeos
nesta aula do Skillshare. Mas o que eu quero fazer é
criar um exemplo prático, o
exemplo mais prático que posso pensar e usar aquele
exemplo prático que vimos anteriormente na aula com o
exemplo de e-commerce via Shopify para criar nosso próprio projeto
inspirado em comércio eletrônico,
e se você quiser levar
esse projeto adiante,
use-o e se você quiser levar
esse projeto adiante, como inspiração para algo que você
deseja usar no mundo real. Sinta-se à vontade para fazê-lo. Mas ao invés mais sobre isso, eu quero apenas pular
direto para ele e deixar vocês acompanharem
o que estou criando aqui. Para este projeto, vou confirmar tudo no Git
para você
possa examinar esse código mais tarde e
comparar seu código com ele. Isso tem sido uma crítica a algumas
das minhas aulas
no passado também, é que vocês não
conseguiram ver o código
em si, além
dos vídeos. Eu ouvi
vocês sobre isso também, e então vou me comprometer enquanto
vou e vocês podem ver
esse código no GitHub depois que
esta aula for publicada e
comparar seu código com o meu. Sem mais delongas, vamos entrar nisso. Vou criar uma pasta de
projeto aqui dentro da pasta de código onde
criamos a outra pasta. Vou chamar este carrinho
de compras. Em seguida, abra o
Visual Studio Code, pegue essa pasta, arraste-a para o Visual Studio
Code e, portanto, sei
que estou abrindo essa pasta específica. Obviamente,
estenderei isso para toda
a largura da sua visualização. Lá vamos nós, e vamos começar com nosso conteúdo
boilerplate. Então, vou criar um
novo arquivo com index.html. A mesma coisa que eu
fiz no passado, use o ponto de exclamação para produzir um documento
HTML boilerplate. Vamos chamar esse carrinho de compras. Então o que vou fazer
é copiar em alguns ativos, CSS e ativos de imagem porque essa classe não está realmente em CSS, e é claro que não
vou fazer com que você
obtenha suas próprias imagens, então eu vou traga esses
agora. Vamos dar uma olhada rápida para que você saiba o que está acontecendo. Acabei de receber um arquivo
styles.css aqui e ele só tem um
monte de códigos diferentes. Este é redundante. Mas temos um monte de códigos
diferentes aqui apenas para estilizar nosso projeto com bom estilo. Novamente, não estamos realmente
focados em estilos nesta classe, mas é muito melhor
ter um projeto que seja bem estilizado
do que um feio. Então eu tenho isso
lá dentro e depois tenho imagens aqui, produtos aleatórios. Estas são
imagens aleatórias de produtos como você pode ver. Todos eles parecem visualmente semelhantes, mas não há relação
entre Coca-Cola Zero e Óleo de Semente de Cânhamo
e Pasta de Curry Vermelho. Um pouco aleatório, mas
só precisávamos de algumas
imagens de espaço reservado para este projeto. Também vou criar
uma pasta JavaScript. Comece clicando em
“Nova pasta”, “js”. Dentro desta pasta js, vou criar um index.js. O que vou fazer
aqui é porque
vamos construir
um carrinho de compras, vou criar um
objeto no objeto da janela. Será um
objeto global chamado cart, e então eu vou
abrir um objeto vazio, e sei que
neste objeto eu
quero ter uma matriz de itens, então estou apenas inicializando
isso aqui. Vou clicar em “Salvar” nisso, e este provavelmente
será meu primeiro commit. Vou abrir
um terminal aqui, executar git init, git add. e, em seguida, git commit
inicial commit. Claro isso, e então
o que vou fazer é
tentar me comprometer de vez em quando para que vocês possam ver
o progresso acontecendo e se referirem ao
código, se quiserem. Temos esta ****
DS Store aqui. Só vou descartar
isso, não preciso disso. De volta ao nosso código aqui, vamos dar nosso primeiro passo
para criar esse projeto. Na verdade, antes de fazermos isso, vamos realmente clicar em “Ir ao vivo”. Agora você verá que estamos executando
nosso arquivo index.html. Também precisamos carregar
nesses estilos, então provavelmente deveria ter feito isso antes do
meu commit inicial. Mas aqui vamos nós, link rel="folha de estilo”
e, em seguida, o caminho para essa folha de estilos
é css/styles.css. Agora, antes de criarmos
qualquer funcionalidade, vou
criar algum HTML aqui, então vamos criar uma div com
a classe de contêiner, coisas
bastante padrão
e, em seguida, carrinho de compras h1. Então o que vou fazer é uma div com a classe
de produtos à venda, e então dentro daqui, o que vou fazer
é criar quatro divs, então div times 4. Vamos clicar em “Salvar” nisso. Vamos dar uma olhada aqui, então você pode ver se eu clico
no clique em “Inspecionar sobre ele”
e vejo produtos à venda. Temos todo o CSS
pronto para usar quando
inserimos esses elementos de produto
nesta div aqui. Antes de fazer qualquer coisa,
deixe-me dar uma visão geral do que estamos
tentando criar aqui. Este será nosso projeto
finalizado. Como você pode ver aqui, temos quatro produtos que
podemos adicionar ao nosso carrinho, e se eu clicar no botão Adicionar ao carrinho abaixo de
qualquer um desses produtos, ele adicionará esse item ao
nosso carrinho aqui. Se eu clicar nesse botão novamente, ele aumentará a quantidade, se eu clicar no botão Adicionar ao carrinho de outro
produto, ele adicionará essa linha
à tabela aqui, que é
atualizar automaticamente o total. Pense que tudo isso
é cerca de 10 dólares, então é uma matemática muito fácil, e também posso atualizar a quantidade por meio desses seletores de
quantidades, e isso atualizará os
totais conforme apropriado. Eu também posso entrar aqui e
definir isso como 10 se eu quiser. Então eu posso definir minha própria quantidade
específica. A teoria por trás disso é
que se fosse um carrinho de compras real, eu poderia clicar em um
botão e ele
iria dar uma olhada
com essa seleção. Para nossos propósitos, se
atualizarmos a página, perderemos nosso carrinho. Poderíamos escrever algum
código para persistir isso no armazenamento local
ou no armazenamento de sessão. Mas para os propósitos
deste vídeo, acho que não
precisamos fazer isso,
isso pode ser uma melhoria
que você faz no futuro. A última coisa que ele faz é, se estiver em um e você
tentar reduzir a quantidade, ele apenas removerá esse
item do carrinho. Se não houver itens no carrinho, a tabela inteira desaparecerá. Então é isso que estamos construindo. Posso deixar essa aba
aberta para o lado, voltar para cá, e vamos começar a trabalhar. Na verdade, mais uma coisa antes de
começarmos nisso, eu quero realmente uma visão geral como vamos dividir
isso em componentes da Web. Aqui você pode ver que temos
cada um desses produtos aqui e a mesma funcionalidade
existe em todos eles. Se eu clicar no botão Adicionar
ao carrinho, ele adicionará esse
produto específico ao carrinho, então cada um desses produtos será
seu próprio componente da Web. Então, como você pode ver, se eu atualizar aqui, clique em “Adicionar ao carrinho”, obtemos
esta outra seção adicionada aqui, que é a nossa lista de itens de carrinho, a tabela de itens do carrinho. Isso também será um
componente. Então, finalmente, dentro desse componente da tabela de itens do
carrinho, temos outro
componente que é nosso
seletor de entrada de quantidade aqui. Então, sempre que eu clicar em
mais ou menos, definiremos uma quantidade específica aqui, vamos defini-la como zero. Veja o que acontece, ele desaparece. Isso também será
um componente. Vamos começar com o componente
do produto. Vamos até aqui e depois vá para o
nosso editor de código. Em nossa pasta js, vamos criar o arquivo para esse componente. Vou chamá-lo de product.js. Vamos começar com a
placa de caldeiras. Vou chamar esse elemento de produto de classe. Claro, vamos estender o elemento
HTML como vimos
ao longo desta classe. Então, antes de escrever
qualquer código dentro, vou
exportá-lo imediatamente. Como estamos usando
módulos ES com cada componente contido em seu próprio arquivo
JavaScript, vou usar o padrão de exportação e, em seguida, basta escrever o nome da
classe depois disso. Pressione “Enter”
sobre isso,
depois mudando para o meu arquivo index.js, vou colocar minha
importação no início do elemento de produtos de arquivo
e, em seguida, direto
do caminho para esse arquivo, que já estavam
na pasta JavaScript, então ela vai ser.product.js. Então precisamos colocar
um método definido aqui,
obviamente, os elementos personalizados definem. Vou chamar esses
elementos de produto como
o primeiro argumento
e, em seguida, trazer essa classe de elemento de
produto. Também preciso importar esse arquivo
index.js para HTML. Não vamos esquecer isso.
Script src=” js/index.js " e, em seguida, não esquecendo esse atributo de
tipo do módulo. Clique em “Salvar” sobre isso, atualize aqui e veja se há
algum
erro de JavaScript que não existe. Perfeito. Vamos voltar. Em vez dessas quatro
divs, o que eu quero fazer é fazer quatro elementos do produto. Vamos clicar em “Salvar” nisso
e ir para aqui. Como de costume, vou adicionar o método
do construtor
e, em seguida, executar super. Agora temos que
pensar em como queremos
construir nosso componente
web personalizado aqui. Se eu olhar para o código
aqui, vamos trazer esse componente da Web
quatro vezes diferentes. Não sei se quero
escrever meu HTML interno dentro de cada um
deles porque ele
vai ser bastante repetitivo. O que eu poderia fazer é
colocar a estrutura HTML dentro da definição de
classe do componente da Web aqui. Dessa forma, é o mesmo para cada componente da Web
que é o que
queremos e que
manterá nosso código limpo. O que vou
fazer é
escrever esse HTML interno. Essa estrutura é baseada no CSS que eu
já configurei. Está aproveitando as
classes já no CSS. Vou criar uma div com a classe de contêiner
de imagem. Feche isso e
, em seguida, vou
tirar a imagem com uma
classe de imagem do produto. Então eu vou colocar no SRC que assim que chegarmos aqui, devemos começar
a pensar conosco mesmos, isso precisa ser
um valor dinâmico. Se for um valor dinâmico, não
podemos realmente definir
algo explicitamente aqui porque
a imagem
do produto será a mesma
para cada produto. Obviamente, a estrutura de cada elemento
do produto será a mesma, mas o produto
vai mudar
e, portanto, a imagem do produto. Portanto, o título e a ID do produto serão alterados. Agora vamos chegar a cada um
desses como ele vier. Mas para começar
o que eu quero fazer é criar um atributo personalizado pelo
menos para a imagem. Dessa forma, podemos passar a imagem em cada um
desses componentes da web. Vimos isso antes na
classe quando
olhamos para atributos
personalizados agora podemos usá-lo na prática. O que vou fazer
é colocar em um
atributo de imagem e vamos dar uma
olhada dentro da nossa pasta aqui. Fazemos disso o caminho para a
imagem, image/coke-zero.jpg. Vamos copiar isso aqui e
aqui e depois
atualizaremos isso. O segundo
será o óleo de semente de cânhamo. O próximo será o
creme de corpo mágico e, em seguida, o final será pasta de groselha vermelha.
Clique em “Salvar” nisso. Então, o que podemos fazer é ir para
o nosso componente web aqui. Podemos definir a imagem
nos componentes da Web. Estamos definindo uma
variável anexada a este componente da Web
como fizemos antes, get atributo e
vamos obter o valor desse atributo de
imagem. Então, dado
que temos esse valor
, podemos entrar aqui e inseri-lo
aqui neste SRC. Vou clicar em “Salvar” nisso, atualizar aqui e
vamos ver o que temos. Eles vão para o
console, sem erros. Mas você pode ver que também não está se
deparando. Estou suspeitando que isso seja
por causa de algum erro tolo. Sim, é um erro de digitação boba. Deve ser elemento do produto e
não elementos do produto. Basta passar e se
livrar desses S's. Clique em “Salvar” e, em seguida,
se
atualizarmos aqui, na verdade nem precisamos atualizar porque você pode
vê-lo funcionando para nós. Vamos ver se
ainda podemos ver as coisas. Sim. Vamos
colocar isso na parte inferior e, em seguida, você pode ver que
temos nossa linha de
quatro imagens de produtos. Temos a mesma estrutura para cada elemento de produto que
armazenamos aqui, mas estamos passando pelo valor
dinâmico de onde está a URL
da imagem e seguida, estamos colocando-a em
nossa estrutura de modelos aqui. Mas é claro, como mencionei
antes, o URL da imagem não é o único
conteúdo dinâmico que precisamos
passar para esse elemento do produto. Precisamos da barra de título
do nome do produto. Precisamos de seu preço
e precisamos de sua identificação. Vamos criar alguns atributos
para isso também. Vamos continuar com o próximo
na hierarquia visual. Vamos continuar com o nome. Vou fazer exatamente o
mesmo formato que fiz aqui. Crie uma variável chamada
this.name e, em seguida, obtenha o valor do nome
do atributo. Obviamente, isso ainda não
foi criado. Vou entrar aqui, vou fechar isso para que
possamos ver isso melhor, e então vou criar um atributo name para
todos esses elementos de produtos. Então este vai
ser coca zero. Vou colocar
entre parênteses, pode. Então aqui
óleo de semente de cânhamo e aqui eu vou
chamá-lo de creme corporal e depois aqui pasta de curry vermelho. Clique em “Salvar” nisso. aqui e, na verdade,
precisamos usar esse nome em
algum lugar do nosso código. Eu posso ir até aqui
e então eu posso ir exatamente como
fizemos com a imagem, criar um h2 dentro deste h2. Posso deslizar nthis.name. Atualizando aqui, agora você
pode ver o nome de cada produto abaixo
da imagem do produto. Há alguns problemas
de CSS aqui e isso é porque não
deveria estar dentro
do deveria estar dentro contêiner de imagem.
Deixe-me consertar isso. É suposto estar
fora desta div. Eu pressiono em “Salvar” nessa
atualização aqui , então você pode ver que não
temos mais esse problema. Doce. Isso compõe
nossa hierarquia visual. Mas a outra coisa que
precisamos fazer é realmente armazenar alguns dados
neste elemento do produto para quando clicamos em “Adicionar ao carrinho” porque
dependendo de qual botão ou elemento
clicamos em “Adicionar ao carrinho” on vai ter
um valor diferente. A maneira como vou
fazer isso é, em vez de adicioná-lo ao HTML interno vou criar um elemento e depois
anexá-lo ao DOM. A razão pela qual
vou fazer isso dessa maneira é para que eu possa anexar um ouvinte de eventos a ele antes
de anexá-lo ao DOM. O que vou fazer é criar
um elemento para o botão. Vai ser botão e,
claro, tenho que
guardar isso em algum lugar, então vou apenas guardar isso no botão
chamado constante. Vou definir o HTML
interno do botão para adicionar ao carrinho e depois
adicionarei um ouvinte de eventos. Na verdade, vamos comentar
isso por enquanto. Volte para ele em um segundo. Vou acrescentar
isso para adicionar o documento primeiro. Clique em “Salvar”
sobre isso, atualize aqui e você pode ver que
temos nossos
botões Adicionar ao carrinho e seu estilo, assim como no nosso exemplo por causa do CSS que
já chegamos lá. Agora, para que isso funcione,
precisamos saber qual é o nome e o id do produto que estamos
adicionando ao carrinho? Porque isso não
está fazendo nada, e é aí que
vamos passar o id. Mas também precisamos saber qual é
o preço de cada produto, para que
possamos adicioná-lo à
nossa tabela de carrinho também. Vamos passar
o id e o preço. Vamos criar atributos
para eles também. Vou começar
dentro do componente, e digo que this.id é igual a
isso.getAttribute, não atributos de animações, id
e, em seguida, this.price,
this.getAttribute price. Então eu vou
para os elementos aqui. Vamos adicionar um id para cada um. O primeiro que
vamos fazer 1, 2, 3 e 4. Há apenas produtos completos,
então só precisamos de ids simples. Então vou
adicionar o preço. Vamos mantê-lo simples
e fazer com que cada um deles $10. Vamos apenas passá-los
como dígitos agora e convertê-los em
números inteiros ou flutuadores mais tarde. Agora voltando para o
nosso componente web, esta é a parte em
que realmente construímos algumas funcionalidades e ficamos um
pouco mais complicados. Como você pode ver aqui, tenho um
EventListener comentado. O que eu quero fazer antes de
criarmos isso é criar o método que esse
EventListener irá acionar. Fora do construtor, vamos criar nosso próprio
método chamado AddToCart. No AddToCart, o que
vamos
fazer é construir um objeto com todos os atributos
que queremos
adicionar a um objeto de item de carrinho. Vou criar
um objeto de item const e você deve ver o que quero
dizer com isso muito em breve. Claro que vou
adicionar uma chave de id e vou pegar
o id armazenado
neste componente da Web. Vou fechar isso para
que você possa ver mais. Então, vou pegar o nome e isso será
igual ao nome, conforme definido
no componente da Web. A quantidade sempre será igual
a uma porque o botão Adicionar ao carrinho apenas adicionará um por padrão. Você pode adicionar um seletor de
quantidade a esse elemento mais tarde se
quiser como uma melhoria. Mas, por enquanto, sempre que você clicar em “Adicionar ao carrinho”, basta
adicionar um. Vou consertar isso no número 1
e, em seguida, o preço será isso.price. Vamos dar uma olhada. Quando realmente executamos isso, tudo o que vou fazer para começar apenas
para vê-lo é executar o log do console
e, em seguida, IteMobject, o objeto que acabamos de criar. Aqui em cima, no addEventListener, obviamente
vou
procurar o clique em “Evento”, e então vou executar
esse método AddToCart, e então vou vincular isso, modo que quando eu estiver
aqui em baixo neste sempre que fizer referência a isso, vou fazer referência ao componente
da web,
não ao evento. Clique em “Salvar” sobre isso,
atualize aqui. Vamos abrir nosso console
e, se eu clicar em “Adicionar ao
carrinho” no óleo de semente de cânhamo, você poderá ver que ele
envia os dados. Podemos ver que o id do
produto é 2, o nome é Óleo de semente de cânhamo. Estamos adicionando um e o
preço de cada um é 10. Se eu fizer isso na Coca-Cola Zero Can, recebo um pouco
de dados diferentes. Se eu fizer isso no
Creme Corporal e na Pasta de Curry Vermelho, você pode ver que recebo um objeto de
item diferente sempre. Isso confirma que
estamos enviando através um objeto com todas as
informações de que precisamos. Agora, o que precisamos fazer
é escrever um pouco de lógica para
adicioná-lo a essa matriz de itens
dentro do nosso objeto de carrinho. Vamos aqui e
mostrarei como podemos
acessar esse objeto de carrinho. Como está no objeto
da janela, podemos digitar window.cart para dar uma
olhada nele ou
podemos simplesmente escrever carrinho porque já estamos
no contexto da janela. Como você pode ver, não importa de
que maneira fazemos isso, podemos ver que temos um objeto com uma matriz de itens
vazia. O que queremos ver quando
produzimos isso novamente, depois de adicionarmos ao carrinho, é que temos um novo item
nessa matriz de itens.
Vou limpar isso. Vamos fazer isso agora. Vou comentar
esse log do console, e o que precisamos fazer
na maioria dos casos é adicionar esse objeto simplesmente à matriz
desse item. Vamos fazer
window.cart.items.push para adicionar esse objeto de item
à matriz de itens
e, em seguida, vamos colocar o objeto do item como
argumento lá. Vamos clicar em “Salvar” nisso. Atualize aqui. Se eu digitar o carrinho agora, você pode ver que temos uma matriz de
itens vazia. Vamos obter um pouco
mais específicos e dizer itens de carrinho especificamente. Temos uma matriz vazia
que está clara para ver. Deixe-me fazer isso mais
uma vez. Nós temos o antes, então se eu clicar em “Adicionar
ao carrinho” e
digitarmos carrinho.items agora, você verá que temos um
objeto em nossa matriz, e se eu olhar para dentro, é nosso óleo de semente de cânhamo
com o quantidade de um. Se eu clicar em “Adicionar ao carrinho” no Body Cream e depois
vou carrinho.items, agora
você deve ver que
temos dois itens em nossa matriz com cada um
desses produtos. Agora temos um problema que eu não sei se você
pensou nisso ou não, mas logo descobrirá
que isso é um problema. Se eu adicionar outro
do mesmo produto que
já temos em nosso carrinho, digamos óleo de semente de cânhamo novamente, e então eu vou até
aqui e vou carrinho.items, você verá que temos três
itens no carrinho, e temos óleo de
semente de cânhamo duas vezes, mas com uma quantidade cada. Queremos ver um item
na matriz para óleo de semente de cânhamo, mas queremos que esse
número seja dois. Precisamos escrever um
pouco de lógica extra para isso. Vamos voltar para aqui e vamos usar o método find dentro do JavaScript para descobrir se o item já
existe na matriz. Vou criar um item
constante no carrinho. Em seguida, vamos
procurar window.cart.items, então vamos usar
a
busca do método passando pelo item. Se o id do item for igual
ao ID do objeto do item, encontramos uma correspondência, e esse será o objeto. Antes de escrever qualquer outra coisa, vamos fazer console.log
item_in_cart. Ele deve vir
como indefinido ou algum outro valor nulo se
puder realmente encontrar alguma coisa, mas se encontrar algo, nós realmente obteremos
o objeto em si. Refrescante aqui. Vamos clicar em “Adicionar ao carrinho” e
ele aparecerá como indefinido. Mas se clicarmos em “Adicionar
ao carrinho” novamente, você verá que
já temos esse produto existente no carrinho. Se ir carrinho.items, você pode ver que
temos o mesmo item duas vezes no carrinho.
Precisamos consertar isso. O que vamos fazer
é executar se item_in_cart, então tudo o que queremos fazer
é pegar o item que
já está no carrinho e apenas aumentar sua
quantidade em um. Mas se não estiver no carrinho, então se ele aparecer
indefinido, por exemplo, vamos executar esse código aqui para empurrar
esse item para o carrinho. Vamos salvar isso e vamos ver se isso
corrige nosso problema aqui. Vou adicionar
óleo de semente de cânhamo, vou adicionar creme corporal. Vamos dar uma olhada nos
nossos itens de carrinho agora. Temos um
óleo de semente de cânhamo e um creme corporal. Se eu adicionar um do
mesmo produto novamente, o óleo de semente de cânhamo e depois vamos dar uma olhada no carrinho.items, você pode ver que só temos
dois itens em nossa matriz agora, e se eu clicar neles, você pode ver clicando em “Adicionar ao carrinho”
no óleo de semente de cânhamo, na verdade não criou
um novo item em nossa matriz, mas simplesmente aumenta a quantidade
desse item existente, que é exatamente o que queremos. Voltando aqui, essa é essencialmente toda a
funcionalidade que precisamos, especificamente
do elemento do produto. Apenas para resumir neste
ponto antes de seguirmos em frente, criamos um componente web de
elemento de produto. Passamos em
quatro parâmetros. Dentro do próprio componente web, temos uma
estrutura padrão que é comum a todos os componentes da Web do
elemento do produto e uma funcionalidade comum
do AddToCart, que podemos ver aqui. Eu removerei esse log do console porque tudo isso está funcionando, e agora você pode ver, mesmo que ainda não tenhamos cart.items
representado visualmente na página, podemos adicionar itens
à nossa array de itens do carrinho. O objeto cart aqui é
basicamente nosso objeto de estado, e o que
vamos fazer é usar esse objeto de carrinho para criar nossa
tabela de itens de carrinho no próximo vídeo. Como prometido, vou
confirmar esse código e descartar. Eu provavelmente deveria ter colocado
isso no get ignore. Despalco, entre aqui,
descarte isso e, em descarte isso e, seguida, confirmarei nossas
alterações para index.html, index.js e, claro, a criação de product.js. Vou preparar todas essas alterações
e adicionarei a mensagem de commit,
criarei o componente
da Web do elemento do produto. Varrer. Vou pressionar o commit sobre isso, novamente, descartar essas alterações. Vou
dividir isso em outro vídeo. No próximo vídeo,
veremos o componente de itens do carrinho.
11. Componentes de web em prática parte 2: Tudo bem, pessoal.
No último vídeo, configuramos um index.js, que tem nossos objetos cortados
com a matriz de itens, e aprendemos como podemos
preencher essa matriz de itens por meio desse elemento de produto que criamos
no vídeo anterior, e, obviamente, isso também tem um componente
visual. Temos cada um
desses elementos de produtos com
esses botões de adicionar ao carrinho. Se eu clicar em qualquer
um desses botões de adicionar ao carrinho, ele atualizará nosso carrinho.items
que temos aqui, mas isso ainda não está representado
visualmente
na tela. Isso é o que
faremos neste vídeo. Vamos criar
um novo componente chamado itens de
carrinho. Vamos
fazer isso agora. Vamos para nossa pasta JS, criar um novo arquivo
chamado cart-items.js. Vamos colocar nosso código
boilerplate componente aqui. Itens do carrinho são o que
vou chamá-lo, e vamos estender
a classe de elemento HTML. Lá vamos nós. Estou tentado aqui apenas a escrever elementos
personalizados definidos, mas lembre-se de que estamos
usando módulos ES. Em vez disso,
o que vou fazer é exportar itens do carrinho
e, em seguida, vou
fazer meu método definido aqui no arquivo de índice. Defina itens de
carrinho, itens de carrinho aqui. Eis que o
código do Visual Studio sabe o que estou
tentando importar e
adiciona automaticamente a
instrução input aqui. Mas se seu editor de código não fizer isso por qualquer motivo, você pode simplesmente
escrever esse código. É o mesmo formato do
que tínhamos antes. Doce. Para colocar este componente de itens de carrinho
em um documento, vou simplesmente ir até
aqui dentro do nosso contêiner, então está tudo contido, vou adicionar em nosso componente web personalizado de itens
de carrinho. Ele vai
colocar automaticamente a tag de fechamento lá. Agora, se eu atualizar minha página aqui
e não houver erros, posso dizer de forma confiável que
temos isso em nosso documento aqui. Se eu entrar aqui, você pode ver que temos nosso componente
web de itens de carrinho vazio aqui. Na verdade, vamos adicionar
algumas coisas a ele. Vamos fechar os produtos
por enquanto. Vamos para dentro da
nossa definição de classe aqui. Obviamente, como sempre, vamos precisar do
nosso construtor
e, dentro do nosso construtor,
colocaremos nosso super método. Agora, ao contrário de todos
os outros componentes que
fizemos no passado, eu realmente vou deixá-lo lá para o método do
construtor. Vou colocar toda a
nossa renderização dentro de outra
função chamada render. Agora, por que eu faria isso? A razão é
porque quando adicionamos um novo produto ao carrinho
por meio desse elemento de produto, precisaremos renderizar pela primeira vez ou
renderizar novamente nossa tabela de itens de carrinho. Vai ser útil
ter nossa função de renderização aqui
para que possamos renderizar novamente
sempre que precisarmos. Todo o código dentro desta função de
renderização não será executado quando o
componente de itens do carrinho estiver incluído
na página, como temos aqui,
será executado
quando pedirmos especificamente para renderizar. Isso vai ser um monte
de código e eu não vou aprofundar
em tudo isso, mas vou explicar à medida que vou. O que vou fazer é criar um ponto de partida para esse componente de itens de
carrinho. Vou definir o HTML interno para nada quando executarmos o render. Agora, a intenção disso é quando executamos o render
no futuro,
precisamos acabar com o conteúdo que tínhamos antes,
caso contrário, poderíamos ter um pouco
do HTML interno antigo dentro nosso componente quando nós tem
que renderizar novamente o carrinho. Então o que vou
fazer é construir um HTML usando o documento create, o segundo método que vimos
no vídeo anterior
em três maneiras de criar HTML
dentro do nosso componente da Web. Esqueci de colocar o
nome da variável aqui. Vou chamar isso de
um contêiner de mesa. Em seguida, vou adicionar
a classe de contêiner de tabela a essa div de contêiner de tabela
e, em seguida, o segundo
elemento que vou
criar é chamado de tabela. Esta é a nossa tabela de itens de
carrinho real. Indo criar um elemento de tabela, atribua-o à constante da
tabela aqui. Então o que vamos
fazer é
percorrer todos os itens
do carrinho. Vou executar um
quatro cada nestes. Vou ter
dois argumentos aqui, um para o elemento em si para que ele
seja o item em si, e então o segundo
será o índice. Deixe-me voltar
a isso em um segundo antes de entrar nesse código profundo. O que vou fazer
é table_container. O que eu quero fazer é anexar nossa tabela a esse contêiner de
tabela
e, em seguida, vamos anexar o contêiner de tabela
ao nosso componente da Web. Há um pouco acontecendo
aqui, mas fique comigo. O que estamos fazendo é que basicamente
criamos se eu salvar e
depois atualizar aqui. Agora, não está realmente
renderizando porque, lembre-se, isso está no método de renderização, não está no construtor
como tínhamos antes. O que vamos
ter que fazer é executar algum código para encontrar o componente da Web que
estamos procurando,
que é itens de carrinhos
e, em seguida, executar o método de
renderização nisso. Se eu voltar aqui agora, você pode ver que dentro
de nossos itens de carrinho, teremos uma
div com a classe de contêiner de mesa e dentro
vamos ter a mesa. Isso é o que estamos fazendo aqui, estamos criando essa estrutura
HTML. Agora, o que vamos fazer é para cada item na matriz, vamos adicionar. Vou pegar
o HTML interno, e vou
usar o plus igual para acrescentar à nossa string aqui, vamos abrir isso, e vou
adicionar em uma linha para cada item de carrinho em
nosso matriz cart.items. Vamos ver isso em
ação. Se eu clicar “Salvar” e eu for aqui, e vamos reexecutar
esse método de renderização, voltar para aqui, encontrar nosso
contêiner de tabela de itens de carrinho e dentro da nossa tabela, você verá que ainda não há
linhas na tabela, mas isso é porque
na verdade
não temos nada em nossa matriz cart.items. Se eu for carrinho.items, não
há nada lá dentro. Se eu fosse adicionar, digamos, dois itens à nossa matriz, vamos dar uma olhada
agora, cart.items. Definitivamente temos dois
itens em nossa matriz agora. Se eu fosse executar
renderização em itens de carrinho, voltar para os elementos aqui, entrar em nossa tabela, você pode ver que temos duas linhas. Agora, obviamente, precisamos preencher
cada uma dessas linhas com os dados de cada um
desses itens de carrinho, e é isso que
vamos fazer agora. vez, haverá um pouco de
código aqui, mas fique comigo. Precisamos de três células de tabela. Na primeira célula da tabela, vamos colocar
o nome do item. Portanto, é claro que temos acesso a cada item à medida que o
percorremos, porque é isso que
definimos aqui. Vou dizer o nome do item. Então, aqui, teremos
uma entrada de quantidade. Chegaremos a isso um
pouco mais tarde. Neste, teremos um sinal de $ e, em seguida, teremos o preço do ponto do item. Vamos consertar isso em um segundo porque esse precisa
ser o preço da linha. Portanto, se a quantidade
for maior que uma, precisamos atualizar isso. Então o que vou fazer
é apenas um pouco de formatação. O primeiro td. Quero o texto
alinhado à esquerda, mas isso é padrão, então não
vou
mudar nada lá. No segundo,
vou fazer com que
o texto se alinhe ao centro. Então, o último,
vou definir o texto alinhado à direita. Agora, se eu clicar em “Salvar” nisso, acho que ele é
recarregado automaticamente de qualquer maneira. Pressione “Adicionar ao carrinho” em
dois desses botões. Então eu executo a função de renderização. Você pode ver aqui que temos os
primórdios da nossa tabela. Temos o nome do produto que está no corte e no preço. Mas é claro, se eu
acertar este novamente, só
temos dois
itens na matriz. Ele não atualiza a
quantidade ou o preço da linha. Então, antes de criarmos
a quantidade selecionada aqui, posso simplesmente colocar
a quantidade do item. Enquanto estamos aqui, vamos consertar esse preço, o preço da linha. Vamos chamar esse preço de linha. Isso será igual a garantir que coloquemos
isso dentro do loop. O preço da linha
será igual aos tempos de
preço do ponto do item pela quantidade do
item. Vou clicar em “Salvar” nisso. Atualize aqui, vamos
adicionar alguns itens ao carrinho. Acabei de pressionar “Adicionar ao
carrinho” no óleo de semente de cânhamo, depois no creme corporal, depois de volta ao óleo de
semente de cânhamo novamente, então devemos ver dois
itens em nossa matriz. Se eu for aqui, você pode ver que nossa seleção
foi salva. Se executarmos render, podemos ver que ele está
aparecendo em nossa tabela aqui embaixo. Agora, é claro, toda
vez que temos que
executar a função de renderização nós mesmos, obviamente não
queremos fazer isso. Não vamos esperar que
o usuário entre em seu console e saiba
qual comando executar. Então, vamos configurar isso para que ele seja executado em nosso produto dot js. Depois de adicionarmos ao carrinho, então aqui
vou adicionar uma linha. Podemos literalmente pegar
essa linha e colocá-la lá. Clique em “Salvar” nisso,
atualize aqui. Toda vez que clicarmos em
“Adicionar ao carrinho”, ele renderizará novamente o carrinho. Isso me irrita um pouco. Quero armazenar esse componente
da Web em suas próprias variáveis, então vou criar uma variável para isso. Vou subir
aqui e fazer esses itens de
carrinho de pontos iguais e depois
pegar esse elemento do DOM. Isso eu sinto que é
um pouco mais limpo. Mais uma vez, não preciso
fazer isso dessa maneira, mas eu gosto um
pouco melhor. A próxima parte que
vou fazer antes passar para codificar entrada de quantidade é
criar o rodapé da tabela. Então, se eu olhar para ele agora, na verdade não
temos
o total e, para isso, criaremos
um rodapé de tabela. Vou apenas
remover isso lá. Vamos para os itens do carrinho dot
js. Já estamos lá. Depois desse código, o que vou fazer é criar um novo elemento chamado
documento de rodapé cria elemento. Isso vai ser uma div. Então também vou ter que
descobrir o total do carrinho. Então, vou ter que
usar um método um pouco complicado aqui, itens de método um pouco complicado aqui, ponto de carrinho de pontos de
janela
e, em seguida, executar o método de
redução
nele para contar tudo. Portanto, o item total, se
isso confundir você basta estudar
o método reduzido, mas é uma maneira adicionar todos os valores
para criar um total. O que vou fazer é porque os preços
vão passar como strings, porque nós
os colocamos como uma string em nosso HTML aqui, só
precisamos
passá-los para números inteiros. Agora, podemos querer
passá-los para carros alegóricos se tivéssemos valores
decimais, mas
para este projeto, não
teremos valores decimais. O valor mais baixo será um e vai
subir em um, então nada será de
US $2,75 ou qualquer coisa assim. Nós só vamos
manter isso simples. Vai ser de US $10 ou US $20. Na verdade, tudo
neste projeto será US $10, então estamos mantendo
isso muito simples. Mas só para você saber, talvez
você precise mudar isso. Mas para nossos propósitos, tudo vai ser um número inteiro,
para que possamos fazer pars int. Deixe-me abrir isso
um pouco mais para você. Em seguida, no pars int, vamos pegar o total de tempos de
preço de pontos de item de adição pela quantidade de pontos do
item, que é claro que é
o preço da linha, que calculamos
anteriormente aqui. No segundo parâmetro,
vamos passar por zero. Então, o que podemos fazer é definir o HTML interno do rodapé para, vamos colocar algum
código HTML aqui. Vamos colocar em outra tabela, que vai se
alinhar com a primeira tabela. Vou dar a isso uma
classe de rodapé de carrinho. Então vamos
colocar em uma nova linha. Então, aqui, vamos
colocar uma célula, que só
terá a palavra total. Então vamos colocar em outra
célula para o total em si. Vou colocar o
estilo do texto, alinhar. Ele se alinha com o preço da
linha aqui. Então aqui podemos
colocar nosso valor dinâmico. Então, vou colocar
um sinal de $ real primeiro
e, em seguida, $ assinar chaves encaracoladas
para colocar no total do nosso carrinho, o que acabamos de calcular. Então aqui embaixo, este ponto
acrescenta rodapé infantil. Vou clicar em “Salvar” sobre isso e
depois vamos atualizar aqui. Se eu clicar em “Adicionar ao carrinho”, você pode ver que temos nosso
total aparecendo aqui. Ainda não consigo reduzir
as quantidades,
mas você pode ver que podemos
pelo menos adicionar itens ao carrinho. Nossa
tabela de itens de carrinho está atualizando, completa com o total, de modo
que quase nos cobre para os itens do carrinho, componentes da
tabela aqui. O último
componente será
o componente de entrada de quantidade, que
será aninhado dentro do componente de itens curt. Vou
dividir isso em seu próprio vídeo, então vamos cobrir isso
no próximo vídeo. Em seguida, faremos nossas modificações
finais para concluir este projeto. Vou pegar vocês
no próximo.
12. Componentes de web em prática parte 3: Neste terceiro e
espero que o vídeo final desta série em que
estamos construindo essa funcionalidade de
carrinho de compras personalizado, vou codificar
a entrada de quantidade. Agora, uma coisa que esqueci de
fazer antes de encerrarmos o último vídeo foi cometer
esse código para vocês, então vou fazer isso agora. Vou descartar
esta loja DS novamente e apenas
dar uma olhada nas mudanças aqui. Eu sempre gosto de fazer
isso antes de me comprometer. Vou preparar todos esses itens
e a mensagem de commit
será criar itens cortados.
Isso está comprometido. Descarte esse novamente. Deixe-me fechar alguns desses. Provavelmente vou ter que
abri-los novamente, mas há
muita coisa acontecendo aqui. Vamos entrar em nossa
pasta js aqui e criar o componente de entrada de quantidade. Novamente, começando com
o código boilerplate, vocês já devem estar bastante
familiarizados com isso. entrada de quantidade estende elementos
HTML. Então vamos
exportá-lo imediatamente. Exporte o padrão, entrada de quantidade
e, em seguida, vá para index.js. Vou escrever meu método de definição de
elementos personalizados primeiro porque sei que ele irá
importá-lo automaticamente. Vamos chamar isso com a entrada de quantidade de nome
estendido. Magic VS Code colocou essa instrução de entrada lá para nós para que eu possa fechar isso. Para esse elemento em particular, o que vou
fazer é basicamente construir tudo
no construtor, como vimos
anteriormente nesta classe. Haverá um pouco de código aqui e se você está se perguntando onde eu tenho
todas as ideias para isso, eu realmente tomei o tema do amanhecer da Shopify como inspiração. Muito desse código
é inspirado
pelo mesmo código dentro desse componente dentro
do tema da Shopify dawn. Se você quiser fazer referência a
isso contra isso, ou se perguntar de onde vem meu
processo de pensamento, você pode dar uma
olhada nesse tema. Como de costume, vamos
colocar o super método
aqui e, em seguida,
o que
vou fazer é escrever todo o HTML dentro do
cart-items.js aqui. Rolando aqui, tudo o que estamos
fazendo até agora é apenas escrever a quantidade do item como está nesta
segunda coluna aqui, mas é claro que não podemos
atualizá-lo, não há nenhuma entrada lá. Vamos substituir isso por
nosso novo elemento personalizado, entrada de
quantidade para
a etiqueta de fechamento. Vou criar todo o HTML interno
dentro das próprias tags. Não fizemos isso obviamente
para o elemento do produto aqui, porque não queríamos ter que escrevê-lo quatro vezes
diferentes. Aqui, no caso
de entrada de quantidade, vamos
escrevê-lo toda vez que houver uma
linha na tabela, e cada linha
ficará praticamente a mesma. A única diferença são
os dados que vêm
no item. Podemos colocá-lo aqui e
ainda será código DRY. Aqui, vou
colocar uma classe de quantidade. Se você me ver escrevendo
aulas como essa, está relacionado ao CSS, então não se preocupe muito
com as aulas. Então vamos criar
nossos dois botões, nosso botão menos,
nossa entrada em si. Obviamente, há
muito mais coisas que precisam entrar aqui, mas vou começar com a estrutura básica primeiro. Temos botão de entrada. Vamos dar uma
olhada em como isso parece. Você pode ver a
estrutura básica lá, mas é claro que vamos
precisar colocar o menos
entre essas tags de botão e, em entre essas tags de botão e seguida, o mais entre
essas tags de botão. Para os atributos,
vamos dar uma classe, vamos colocá-lo
em ambos os botões aqui, classe de quantity__button. Vou fechar isso para
que possamos ver melhor. Botão de tipo. Podemos colocar isso em
ambos, digitar botão
e, em seguida, o nome será baseado em onde quer que
seja menos ou mais. Vou escapar disso e
depois vou colocar menos
no primeiro e depois
mais no segundo. Vamos clicar em “Salvar” nisso e ver o que isso parece até agora. Parece que temos
um hit “Salvar” nisso. Não deve ser tão
relevante de qualquer maneira. Clique em “Adicionar ao carrinho” e,
como você pode ver agora, temos nossos estilos
chegando para as
vantagens e desvantagens. Precisamos adicionar algum código aqui
dentro de nossas tags de entrada aqui. Vamos adicionar alguns atributos. Queremos que o tipo seja
números para que as pessoas usem o texto de inserção de carrinho
aqui além de dígitos. O valor será
igual ao item.quantity. O mínimo será zero. Não queremos valores
negativos. Vamos dar a ele um
ID e o ID
começará com a quantidade e, em seguida, vamos colocar
um traço e, em seguida, usar o índice para diferenciar
cada uma das entradas. Então eu vou colocar um índice de
dados aqui também, o que vai
ser a mesma coisa. Vamos usar o
I como índice de dados. Vou clicar em “Salvar” nisso. Atualize aqui, clique em “Adicionar ao carrinho” e,
como você pode ver, parece que está funcionando. A única coisa que
não está funcionando é não
podemos adicionar e subtrair. Se eu mudar isso para dois, na verdade não mudará
os dois. Se eu mudar isso para zero, na verdade não
muda o zero. É aí que precisamos
começar a codificar nossa quantidade de entrada aqui dentro
de sua definição de classe. Vamos configurar algumas coisas
em nosso construtor. Quero primeiro trazer a
entrada para sua própria variável. Vamos descobrir
isso dentro do DOM,
dentro do nosso componente da web. Então o que vou fazer
é criar um OnButtonClick, que será o
retorno de chamada para nosso EventListener. Vou adicionar no evento como o único
parâmetro. Vou evitar
qualquer comportamento padrão, e então vou
escrever alguma lógica aqui para que isso funcione. A primeira coisa que quero fazer
é pegar o valor anterior, o valor antes de alterá-lo, e isso será igual
ao valor de entrada no
momento dessa execução. This.INPUT representa o elemento de
entrada em si, e é claro que podemos
pegar o valor de qualquer entrada apenas observando
sua propriedade de valor de ponto. Ele vai pegar o valor antes de
mudá-lo e, em seguida, vamos dar uma
olhada no evento e
analisar as metas do evento. O destino do evento
nesta instância será o botão em que clicamos. Então vamos
olhar para o nome do alvo
do evento, ou seja, o botão e, se for mais, estamos apenas usando um operador
ternário aqui, para aumentar para executar o
step-up na entrada. Step-up é apenas um
método que nos
permite aumentar o valor
dessa entrada em um. Se não for mais,
o que significa que é definitivamente menos porque
há apenas duas opções, vamos dar um
passo para baixo. Agora, se eu clicar em “Salvar” nisso, agora que temos nosso manipulador de
eventos aqui, vamos realmente
anexar isso a todos os botões. Para isso, porque há
vários botões, vamos usar um
QuerySelectorAll para cada botão, que está nos dois e
no final, mas ainda
precisamos usar QuerySelectorAll. Isso
nos dará uma matriz e, em seguida, precisamos percorrer eles. Para cada botão, vamos
adicionar um EventListener de clique. Se o botão for clicado, vamos executar
esse manipulador de eventos ao clicar
no botão. Assim como antes,
vamos vincular isso para
que isso represente o
componente da Web e não o evento. Remova esse ponto e vírgula
lá e coloque-o lá. Se eu clicar em “Salvar agora” e
atualizar aqui, clique em “Adicionar ao carrinho”, posso fazer com que isso
aumente e desça, mas o que não está acontecendo? Na verdade, se eu pressionar
menos, ele vai cair. Isso não é muito útil, não é? Acho que isso provavelmente está
relacionado a esse erro de digitação aqui. Isso não é uma comparação, esta é uma tarefa, então deixe-me fazer disso
uma tarefa adequada. Vamos voltar aqui, clique em “Adicionar ao carrinho”. Agora, se eu pressionar para baixo,
ele deve funcionar. Agora, o problema é que o valor dentro
dessa entrada está indo cima e para baixo com
esses pressionamentos de botão, o que é bom, mas
na verdade não está mudando o valor em
nossos dados estrutura. Digamos que eu coloquei
isso até sete, e então vamos realmente ir ao nosso array de itens do carrinho
e dar uma olhada dentro, você pode ver que a
quantidade ainda é uma. Podemos aumentar a quantidade
pressionando o adicionar ao carrinho
aqui e, como você pode ver, ele é atualizado para dois agora. Então, se eu entrar em itens de carrinho, posso ir aqui e
é a quantidade 2, mas colocar isso para cima e para baixo não
muda nada. Vamos consertar isso agora. A maneira como vou corrigir isso
é usando um evento personalizado. Agora, por que vou
usar um evento personalizado aqui? Bem, eu quero acionar um evento de
mudança na quantidade. O que vou fazer
é
passar pela linha do item
que quero alterar e sua
nova quantidade para um método, e então esse método
atualizará cart.items. Agora podemos colocar esse método
dentro da entrada de quantidade, mas acho que faz mais
sentido colocá-lo em itens porque literalmente está
atualizando cart.items, o objeto com o qual esse
componente se relaciona. Vou colocá-lo
aqui antes de renderizar. O que esse método vai fazer, vou
chamá-lo de quantidade de atualização. Vai ter um
índice que se
relacionará com o item de linha aqui. Como você pode ver aqui, estamos percorrendo uma matriz e estamos armazenando na quantidade selecione qual número
na matriz é. Posso utilizar isso para
descobrir o número da linha. Então o segundo parâmetro
será o novo valor, que vou chamar
valor como parâmetro. Então, quando isso for executado com
esses dois parâmetros, o que vou
fazer é procurar o item através de seu índice
e, em seguida, simplesmente pegar
a quantidade
desse item e depois alterá-lo para seja qual for o
valor que passamos. Então, quando isso for atualizado, o que vamos fazer é
renderizar novamente a tabela de itens do carrinho, porque obviamente precisamos
renderizar novamente o preço da linha e
precisamos renderizar novamente o total quando estamos fazendo essas atualizações, então é melhor apenas
renderizar novamente a tabela inteira. Vou clicar em “Salvar” nisso, e então o que
vou fazer é fazer referência aos itens do carrinho. Como vimos antes com o produto, quando fazemos referência aos itens do carrinho, eu o coloquei em sua
própria variável
antes de executar o método
aleatório nele. Como vamos
executar um método sobre isso, quero fazer algo semelhante, configurar isso no construtor, então vou
colocar isso aqui. Então, quando executarmos o clique do
botão, obviamente iremos
alterar o valor da quantidade. Agora, como
atribuímos esse componente da Web
a essa variável aqui, posso usar esses itens.cart e executar o método nesses componentes da Web, para
que eu
possa atualizar a quantidade, e para isso eu só precisa
descobrir qual é o índice. Vou usar esse índice de conjunto de dados de
entrada, então isso me permitirá
acessar esse índice de dados
aqui mesmo. Isso está disponível na matriz
do conjunto de dados. Vou pegar esse índice. Então, como segundo argumento, vou colocar
this.input.value. Vou clicar em “Salvar” nisso. Agora vamos atualizar aqui. Clique em “Adicionar ao carrinho”. Agora, como você pode ver, à medida que eu diminuo e aumento
isso, ela vai renderizar novamente toda
a tabela de itens do carrinho e alterar o preço total
e o preço da linha. Agora há mais uma
coisa faltando aqui, e se eu
mudar isso para dois, isso não
mudará nada. Se eu voltar a isso,
isso mudará, mas se eu colocar um valor
específico, isso não vai mudar isso. Deixe-me refatorar esse
código um pouco mais. O que eu quero fazer
aqui é que eu quero criar um evento personalizado. Agora lembre-se, quando falamos
sobre eventos personalizados anteriormente, isso realmente não fazia sentido
porque estávamos apenas vinculando um clique e transformando isso
em outro evento personalizado. Mas desta vez temos duas maneiras de alterar
o valor de entrada, ou seja, a quantidade neste caso. Podemos definir um valor de
quantidade específico, ou podemos usar botões mais e
menos aqui. O que eu quero fazer
é combinar
esses dois eventos em seu próprio evento, que vou
chamar de evento de mudança. Isso faz sentido. Vamos
vê-lo em ação. Primeiro de tudo, vou
criar esse evento personalizado. Eu vou fazer este
evento. change será,
como vimos anteriormente com a criação de eventos personalizados, criamos um novo evento,
damos um nome a ele
e, dessa vez, quero adicionar um objeto JavaScript
para borbulhando. Eu quero definir bolhas como verdadeiras. O que isso vai fazer
é registrar um evento de mudança no componente
web dos pais também, porque eu quero que ele
seja registrado aqui. Então aqui vou
criar um ouvinte de eventos para o evento de alteração nesses componentes da Web
específicos. Vou colocar em mudança aqui, criar uma função aqui. Vou pegar a entrada. Será o evento de
mudança aqui. Então o que vou
fazer é colocar
a quantidade de atualização aqui. Em vez de ter que
executar esse método quando
executamos o manipulador de
eventos de clique de botão
e, em seguida, também o
manipulador de eventos para quando
alteramos o elemento explicitamente, como fizemos antes, como isso, vou
despachar esse evento de alteração tanto
no clique do botão
quanto na alteração de entrada. Deixe-me escrever aqui isso, e vou investigar a
entrada porque precisamos usar alguns de
seus atributos lá. Então eu vou despachar
esse evento personalizado, então esse evento de alteração. Então, porque estamos olhando para
a entrada específica, em vez de não ter nada aqui o que eu posso fazer é
passar pelo evento
e, em vez de
olhar para essa entrada, posso criar uma
referência ao insira aqui com base no destino atual do
evento. Desculpe, esqueci de colocar
a tarefa lá. Então, podemos remover esse
ponto de cada um deles. Vamos clicar em “Salvar” nisso e
vamos ver se isso funciona. Vou abrir meu
console caso haja erros. Adicione ao carrinho. Coloque isso, coloque isso no chão. Não está funcionando
porque estamos verificando os eventos no
componente da Web e não na entrada. O que vou fazer é apenas adicionar um parâmetro extra aqui
com um objeto JavaScript, e vou definir
bolhas como true. Dessa forma, o
evento de alteração irá bolha
até o próprio componente
de entrada de quantidade. Vamos clicar em “Salvar” nisso, atualizar aqui e vamos ver se isso funciona agora. Você não pode definir propriedades de
quantidade de configuração indefinida, vamos dar uma olhada. Vamos dar uma olhada no
que está por aqui, a entrada do log do console. Vamos dar uma olhada.
Isso está passando pelo próprio
componente da web. Isso deve ser porque
estamos indo até o componente da Web que está
acionando a alteração e seguida, o destino atual do evento
nessa instância se torna
o
próprio componente da Web e não a entrada. Podemos corrigir isso usando apenas nossa consulta selecionada para
entrar e selecionar essa entrada. Vamos clicar em “Salvar”
nisso, atualizar aqui, clicar em “Adicionar ao carrinho”
e, em seguida, temos o mesmo
resultado que tínhamos antes. Na verdade, isso está atualizando nossas quantidades e
atualizando nosso carrinho também. Como você pode ver, isso não
está funcionando. Deixe-me mudar isso para
dois e, em seguida, clique em “Tab”. Como você pode ver, isso está mudando
para o valor explícito. Como você pode ver, mudança já é
um evento nessa entrada, também
estamos aproveitando o evento existente que seria disparado quando o
alterarmos explicitamente. Estamos basicamente
adicionando nosso
clique de botão no evento de alteração. Isso é algo que
acontece automaticamente, nem
precisamos
registrar um evento de mudança quando alteramos esse
valor explicitamente, isso acontece automaticamente. Este é um bom exemplo
de como podemos marcar em um evento personalizado em
algo que já existe. Agora só para limpar
isso, temos esse valor anterior aqui. Supõe-se que, se
clicarmos em um botão,
estamos mudando um valor, mas só para ter certeza de que
vou adicionar uma declaração if aqui. Vamos apenas verificar
se o valor anterior
não é igual ao novo valor. Se eu salvar, atualizar, devemos obter o mesmo
resultado que fazemos. Isso é apenas um cheque extra. É basicamente isso pessoal. Temos nossos três componentes
da web aqui. Temos nosso elemento de produto
e, se eu clicar em “Adicionar ao
carrinho” em qualquer um deles, ele interagirá com nosso componente de itens de
carrinho. Posso usar essas entradas de quantidade para alterar os preços aqui. Na verdade, uma coisa que
não fizemos é se ele atingir zero, queremos removê-lo, e se o total acertar zero, queremos remover
a tabela completamente. Pensei que tínhamos
acabado, mas só temos mais uma
coisa a fazer, é por isso que você deve sempre brincar com seus
projetos e ver. Vamos para o cartitems.js e vamos escrever em
algum código extra aqui. Vou rolar para
baixo até o fundo. A primeira coisa que
vou fazer é se o total do carrinho for zero, bem, na verdade, vou
fazer o inverso. Se o total do carrinho não for zero, então vamos
renderizar o rodapé. Mas se o total do carrinho for zero, esse código
não será executado, que significa que não
teremos um rodapé de carrinho quando essa
função de renderização for executada. Vou economizar nisso.
Então o que eu também farei é colocar um cheque
semelhante aqui. Logo após o preço da linha aqui, não
adicionarei a linha
à tabela, a menos que a quantidade do item seja
maior que zero. Se não for zero, então executaremos esse código, então pegue isso e coloque-o aqui. Clique em “Salvar” nisso. Agora, quando adicionamos algo ao carrinho, aumente
sua quantidade, mas volte para zero, isso removerá isso. Digamos que temos
vários aqui e
removemos todos
eles do carrinho, então toda a tabela do carrinho
não desaparece, é apenas essa linha. Podemos adicionar todos eles, remover alguns deles,
aumentar a quantidade. Se este fosse um aplicativo totalmente
funcional com
funcionalidades de checkout reais habilitadas, poderíamos ter um botão
aqui
que envia esse array de carrinho para
uma página de checkout
e, em seguida, o usuário seria
capaz de para concluir esse pedido. Isso conclui este
pequeno projeto de classe. Deixe-me apenas confirmar esse
código antes que eu esqueça. Mais uma vez, descartando a DS Store. Vamos dar uma olhada rápida
no que mudamos aqui. Tudo parece bom. Se você detectar algum erro
com algo disso, apenas me avise. Comentários abaixo, mas vou
encenar todos esses e, em seguida, concluir o projeto
com entrada de quantidade. Vou descartar este novamente. É praticamente isso pessoal. Vou ter esse código
no GitHub para você. Basta procurá-lo
na minha página do GitHub, que é
github.com/christopherdodd. Deixe-me me livrar disso.
Verifique meus repositórios, veja se você consegue encontrá-los lá. Qualquer dúvida. Deixe-os
nos comentários abaixo. Espero que você tenha gostado desta aplicação
prática do uso de Componentes da Web. Espero que nesta aula, parecendo que começamos com a teoria e
entramos na prática, você pode começar a solidificar o que os Componentes
Web fazem e
por que é importante. Vejo você
no próximo vídeo, onde
concluiremos a aula, e falarei com
você sobre como você pode estender esse projeto de classe
ainda mais se quiser. Obrigado por assistir,
verei você no próximo vídeo.
13. Conclusão: Isso conclui nossa classe
sobre componentes da web. Para o seu projeto de classe, eu
encorajo você a criar seu próprio componente
web totalmente funcional. Para inspiração, você
pode pegar o que
fizemos até agora nesta classe com o exemplo de comércio eletrônico e adicionar funcionalidades
adicionais, como filtragem de
produtos ou seleção de
variância. Como sempre, se você tiver alguma
dúvida ou preocupação, deixe um comentário na caixa de
discussão abaixo e farei o meu melhor para apontar
você na direção certa. Obrigado, como sempre, por assistir
e espero vê-lo novamente em alguns dos
meus outros cursos.