Transcripciones
1. Introducción: Hola y bienvenidos a esta
clase sobre componentes web, tu guía para crear elementos HTML
personalizados con JavaScript. Soy
Christopher Dodd. Soy desarrollador
web freelance y principal profesor aquí
en SkillShare.com, cubriendo todas las cosas
desarrollo web y trabajo independiente
en línea. En la clase de hoy, vamos
a aprender sobre el conjunto de cuatro especificaciones que
conforman los componentes web, meta especificación,
y cómo podemos usarlas para crear nuevas etiquetas HTML personalizadas y reutilizables para
uso en páginas web y aplicaciones web. Para aquellos de ustedes
que tienen experiencia codificando con JavaScript, aprender a hacer
elementos personalizados para sus aplicaciones web y sitios web puede ser una herramienta útil para encapsular funcionalidad, y lo estamos usando
en cualquier lugar dentro de un proyecto en particular o
a través de múltiples proyectos. Si estás listo para
aprender a crear tus propios
elementos HTML personalizados con JavaScript, haz clic en el siguiente video y te
veo por dentro.
2. Componentes web: un ejemplo de vida real: Web Components fue algo
que surgió en mi radar dado mi trabajo con sitios de comercio electrónico
impulsados por Shopify. Fue junio de 2021 cuando Shopify reveló que su
tema predeterminado había sido actualizado para encapsular la mayoría
de la lógica JavaScript en alrededor de 20 componentes
web diferentes, como modales, cantidad,
entradas, y más. Incluso crearon su
propio componente deslizador que no requiere bibliotecas
JavaScript externas. Si bien no he
podido encontrar ninguna declaración de
Shopify en cuanto a por qué
eligieron crear sus
nuevos temas de tienda online 2.0 como este, confío en que si
los componentes web era como Shopify, una
empresa tecnológica de varios mil millones de dólares quiso
estructurar la lógica de sus temas desarrollados
internamente, entonces esta fue una especificación para tomar nota y
aprender más sobre. un sitio de comercio electrónico como puede
esperar queun sitio de comercio electrónico como
los que normalmente se alojan
en Shopify tenga alguna
funcionalidad común que
se puede encapsular a través de componentes
web. Para usar como ejemplo el
tema Dawn de Shopify, los principales puntos de
interactividad
como la tabla de artículos
en la página del carrito, las opciones para filtrar
productos dentro de una colección, y el formulario de producto, son todas las áreas donde
la funcionalidad
se puede liar en componentes
web separados. Al final de esta clase,
vamos a tomar ejemplo de
Shopify como
inspiración para construir nuestra propia funcionalidad de
carrito de compras que consta de tres componentes
separados, todos los cuales
interactuarán con el uno al otro. Pero antes de llegar
allí, necesitamos obtener una comprensión más profunda de la teoría detrás de los componentes
web. Empezando con una visión general de las cuatro
especificaciones de componentes web.
3. Las 4 especificaciones de los componentes web: Para esta lección particular, me voy a referir
al sitio web dedicado a ayudar a
los desarrolladores a compartir, descubrir y reutilizar
componentes web, web components.org. Entonces, si alguna vez estás perdido en algún momento sobre la
siguiente teoría, simplemente
puedes volver a chequear en web components.org/specifications
para seguir adelante. Tal y como está escrito aquí
en web components.org, los componentes
web es una
meta-especificación hecha posible por
otras cuatro especificaciones. La
especificación de elementos personalizados, la especificación shadow DOM, la especificación de plantilla HTML y la especificación del módulo ES. En esta lección, cubriremos
brevemente todas
estas especificaciones
desde un punto de vista teórico y en los próximos videos, veremos cada
especificación en la práctica. Empecemos con elementos
personalizados. La
especificación de elementos personalizados es la
especificación fundacional que hace posible los componentes web. Utilizando este método define en
el objeto de elementos personalizados, podemos definir un nuevo elemento
personalizado. El primer argumento es el
nombre del elemento personalizado, que es lo que usamos para
llamarlo dentro del HTML. El segundo parámetro
es el constructor, que es donde irá toda
la lógica. Podemos crear esta clase
construida extendiendo la clase de elemento
HTML
o una clase de elemento
HTML nativa existente como en el ejemplo aquí, pero llegaremos a
eso un poco más tarde. La mayoría de las veces
estarás extendiendo la clase de elemento HTML normal
para crear tus componentes. A esto se le llama un elemento personalizado
anónimo. Aquí tenemos acceso al
componente tal como existe en
el DOM a través de lo poderoso, esta palabra clave. Cada vez que usamos el
elemento personalizado en nuestro HTML, se crea
una instancia y luego
podemos escribir código dentro esta declaración de clase relacionada
específicamente con la
instancia particular del componente. La siguiente especificación
es la sombra DOM, que le permite crear un DOM separado
al DOM regular. Por lo tanto, el DOM regular es referido a
veces como el DOM de luz para distinguirlo al hablar de
la alternativa, que es el DOM sombra. La API de sombra DOM
le permite adjuntar un subárbol DOM a elementos
dentro de su documento web. El
DOM de sombra adjunta está encapsulado, lo que significa que la
información de estilo en su interior no puede aplicarse a
elementos externos y viceversa. Podemos adjuntar el DOM de sombra a cualquier elemento a través del método de sombra
adjunta. Pero en el contexto de la
construcción de componentes web, el DOM de sombra se
crea típicamente directamente en el propio componente web
usando esto.AttachShadow. Usando este objeto raíz de sombra, podemos construir un
subárbol de elementos, todos los cuales son virtualmente invisibles a la luz principal DOM. A continuación, hablemos de la especificación de plantilla
HTML. Esta es simplemente una forma
de crear una estructura HTML que no se
renderizará en su lugar
como HTML normal. Creamos una plantilla
a través de la etiqueta de plantilla, colocamos nuestro HTML dentro
y cuando la página se carga, el HTML no se renderizará, pero sigue siendo accesible
a través de JavaScript. Como su nombre indica, podemos
usar estas etiquetas para crear código de
plantilla que se puede clonar y usar en múltiples ubicaciones. En el contexto de
construir un componente web, la etiqueta de plantilla se puede
utilizar para definir el HTML del componente
clonando el HTML desde
dentro de las etiquetas y
colocándolo bien directamente en el HTML interno de el componente
o en su sombra DOM. Por último, la
especificación del módulo ES define la inclusión y uso de documentos
JS en
otros documentos de JS. Si bien no es esencial para
construir componentes web, almacenar sus componentes web como código
modular que existe dentro su propio archivo JS puede ser útil
para la estructuración de proyectos, especialmente al traer a
terceros componentes web. La sintaxis para la
especificación es importar su
script externo como de costumbre, excepto esta vez que establece el
módulo como el parámetro type. Después se escribe entrada
seguida de la ruta al archivo. Las capacidades de la especificación de
elementos personalizados, la especificación shadow DOM, la
especificación de plantilla HTML y la especificación del módulo ES funcionan muy bien juntos para
ayudarnos a escribir limpio, elementos HTML
personalizados encapsulados y reutilizables. Teóricamente, es sólo la
especificación de elementos personalizados que se requiere para
crear elementos personalizados, pero como verá
en videos posteriores, combinar capacidades
de cada especificación es a menudo la mejor manera de sacar el
máximo provecho de los componentes web.
4. Elementos personalizados, parte 1: Ahora que hemos cubierto las cuatro
especificaciones de componentes web en el último video, veamos cada una
de estas en profundidad
y en acción dentro de
nuestro editor de código. Lo que voy a hacer es
iniciar un proyecto completamente nuevo. Tengo una carpeta
aquí para mi código. Voy a crear
una nueva carpeta de proyecto y la voy a llamar
componentes web. Puedes llamarlo
como quieras. Entonces voy a arrastrar
esto a mi editor de código, que es Visual Studio Code, y esto
abrirá automáticamente esa carpeta para nosotros. Entonces voy a
cerrar esto hacia abajo, haga clic en nuevo archivo por aquí, y crear un archivo HTML. Lo vamos a llamar
index.html. Ahora usando Emmet dentro de
Visual Studio Code, puedo emitir algún HTML
calderín escribiendo signo de exclamación
y luego golpeando “Enter”. Voy a cambiar el título aquí solo a componentes web. Entonces voy a crear
el archivo JavaScript, voy a llamar component.js
porque vamos
a estar trabajando con un solo componente primero hacia arriba. Voy a hacer el clásico
hola mundo para nuestra consola. Regresar a aquí y luego modificación
final
que necesito hacer para que esto
comience es realmente
vincular ese archivo JavaScript. Ahí vamos. Ahora lo que voy a hacer es
volver a nuestra carpeta y
abrirla en Google Chrome. Es Google Chrome para mí, pero puedes usar cualquier
navegador que te guste. Voy a usar la opción de
comando I para abrir aquí mis herramientas de desarrollador, y si voy a la consola, solo
voy a hacer esto
más grande para ustedes chicos, se puede ver hola mundo, que nos muestra que
estamos enlazando correctamente ese archivo JavaScript
que creamos aquí. Impresionante. Ahora que eso está hecho, vamos a crear en realidad
nuestro primer componente web. De nuevo, hay algo de
calderas a esto. Todo lo que tenemos que hacer, y esto va a ser
lo mismo para cada componente web, aparte de los incorporados
personalizados que veremos más adelante, solo
voy a llamar a
este componente web y como se puede ver aquí, la primera letra de cada una de las palabras en este
nombre de clase aquí están en mayúscula. Esa es la convención que usamos. Después escribimos extiende
y luego elementos HTML. Entonces aquí
necesitamos un constructor. Entonces llamamos a la super función, que vamos a
llamar cada vez que hagamos un componente web
y básicamente lo que esto hace es hereda las funciones constructivas de la clase que es extendiendo. Necesitamos eso
para aprovechar lo que estamos
extendiendo aquí mismo. Entonces vamos a bajar
aquí y terminar esto corriendo el
método define en elementos personalizados. El primer parámetro va a ser cómo va a verse el nombre del
elemento en nuestro documento HTML y luego el segundo argumento es el nombre de clase que
acabamos de crear aquí. Ahí lo tenemos, nuestro
primer componente web. Ahora con el fin de llevar eso nuestro front-end y
ejecutarlo en nuestro HTML, acabamos de tener esta etiqueta personalizada disponible
para nosotros, componente web. Eso por supuesto es igual a lo que dijimos aquí
en este método de definición. A lo mejor voy a correr
estos uno al lado del otro. Aquí vamos. Por último, para que podamos verificar que este componente web se está construyendo
y ejecutando en la página, voy a poner un inicio de sesión
de consola aquí y simplemente escribir
hola mundo de nuevo. Volvamos a
nuestro documento HTML, refrescamos la página y se puede ver el hola mundo es el registro de
consola. Si miramos en nuestra página aquí, se
puede ver eso es porque
hemos llamado a ese elemento personalizado. Ahora hasta ahora eso no parece ser ningún uso práctico de
usar esto pero
a medida que avanzamos a
lo largo de este curso, comenzarás a ver
cómo los componentes web encapsulan cierta
funcionalidad a elementos específicos aquí . Una de las formas en que
podemos ver que es mediante el
uso de la, esta palabra clave. Si acabo de escribir esto en un registro
HTML y consola que, entonces somos capaces de hacer
referencia a lo que
pongamos entre estas etiquetas. Pondré ahí el mundo
hola. Volvamos por
aquí, refresco. Se puede ver que tenemos
algún contenido entre esas
etiquetas de componentes web y luego eso se hace eco aquí
en nuestra consola también. Eso solo te va
a mostrar que podemos tomar el
propio componente web como referencia usando esto y luego hacer cosas
dentro de este componente, que vamos a empezar a
ver muy pronto. Ese es nuestro componente web básico. A continuación, déjame
mostrarte cómo podemos crear HTML interno dentro de
nuestro componente web. Voy a hacer esto dentro del método constructor porque esto se ejecuta cada vez que se construye el
componente. Escribiré algunos comentarios aquí. El primer método es simplemente
estableciendo el HTML interno. Voy a
anotar eso. Podemos ir este
HTML interno igual que lo hicimos antes y en lugar
de salirlo, podemos anularlo. Voy a usar las garrapatas atrás
aquí así que no tengo ningún problema con comillas, ya sea comillas dobles
o citas simples. Lo que voy a hacer es crear
un div y dentro del div crear un span y luego en
el lapso voy a decir, este es un componente web. Nuevamente, si actualizo por aquí y luego voy e
inspecciono este elemento, se
puede ver que
hemos insertado este HTML dentro
del componente web. El segundo modo en que
podemos hacerlo es
creando elementos y
agregándolos al DOM. Te mostraré cómo
lo hacemos ahora mismo. Vamos a comentar esto y te mostraré aquí la
segunda opción. Vamos a pasar esto
para que podamos ver más de ello. Quizá aumente el
tamaño de la pantalla. Ahí vamos. Entonces lo que voy a hacer
es usar documento crea elemento y
literalmente podemos poner en el nombre del elemento aquí
para crear un elemento. Pero tenemos que
guardarlo en alguna parte, así que voy a poner un
const div al frente. Eso almacenará el elemento div recién
creado en esta constante div. Entonces voy a crear el
lapso que teníamos antes. Estoy creando exactamente lo
mismo que aquí arriba. Documento crea tramo de elemento. Entonces ahora tenemos
nuestro div y nuestro lapso. Antes de adjuntar el
div a nuestro documento, voy a actualizar
el HTML interno
del lapso a lo que teníamos antes, este es un componente web. Entonces lo que puedo hacer es usar estos métodos child append para construir básicamente el DOM. Puedo anidar el lapso
dentro del div, y luego puedo anidar el div dentro del propio
componente web, así. Ahora si vuelvo por aquí, tenemos un poco de un tema. Ese tema es que
ponemos contenido aquí. Sólo voy a
quitar eso, salvo eso. Si nos dirigimos hacia atrás, ahí vas, vamos a conseguir div con
el palmo dentro. Esa es otra forma de hacerlo. La forma final de hacerlo
es analizar una cadena HTML. Voy a comentar eso y luego
escribiré el tercer comentario, analizaré una cadena HTML. Digamos por ejemplo, en una situación particular
tenía una cadena HTML, y quería poner la cadena HTML como HTML
dentro de este componente web. Sólo hagamos eso otra vez. Lo mismo otra vez, div
con un span dentro, este es un componente web, cierra el span, cierra el div. Entonces lo que necesito hacer
porque esta es una cadena, necesito analizarla. La forma en que puedo analizarlo
es mediante el uso del analizador DOM. Veamos eso ahora mismo. Puedo establecer const
HTML interno en nuevo analizador DOM, y luego ejecutar el parse
desde el método string, que tomará la
cadena HTML como su primer argumento. Entonces el formato Texto/HTML. Entonces lo que eso va a hacer, es que
me va a dar este DOM analizado. Lo que necesito hacer
es realmente encontrar el cuerpo y luego sacar el HTML
interno de eso. Básicamente estoy creando
un nuevo DOM con esta cadena HTML y
luego estoy sacando el HTML interno del
cuerpo de ese nuevo DOM. Entonces lo que simplemente puedo hacer es decir que este HTML interno es
igual a HTML interno. Siendo este el componente web, estoy configurando el HTML
del componente web el HTML interno de esta cadena HTML
analizada. Todo parece bueno. Refresca aquí y
obtenemos exactamente el mismo resultado. Ahora, no te va a quedar
inmediatamente claro por qué necesitarías usar tres métodos diferentes
o qué método usar. Usa cualquier método que
funcione para ti, si este es el más fácil y
puedes salirte con la suya, definitivamente usa ese. Pero hay ciertas
situaciones en las que tal vez estés obteniendo HTML
devuelto de una API, que es el caso
en los temas de Shopify, entonces necesitas usar
este método de analizador DOM, o tal vez está obteniendo un un poco complicado con la creación nuevos elementos que
se encajan en una estructura HTML más compleja, en cuyo caso, es posible que
desee utilizar este método. En este sencillo ejemplo, parecería que esta es la forma más fácil de
hacerlo, que es. Pero a medida que los ejemplos se
vuelven más complejos, es posible que empieces a necesitar usar una combinación de esto o esto. Lo que quería hacer en
esta pequeña sección era mostrarte cómo
puedes hacer eso. Lo siguiente que quiero
mostrarte son atributos personalizados. Voy a
deshacerme de todo esto. No te preocupes, todo esto
estará en el enlace de GitHub, para que puedas mirar este
código cuando quieras. Lo que quiero mostrarte ahora
es que en realidad podemos crear nuestros propios atributos
personalizados. Aquí en esta etiqueta de componente web, podría escribir algo como texto o cualquier parámetro que
quisiera poner a través. Digamos que esto
es un componente web. Tengo un parámetro
por el nombre del texto y estoy
analizando eso como un valor. ¿ Cómo usamos eso? Bueno, voy a
cerrar esto. Lo que voy a hacer es acceder a ese atributo vía
this.getAttribute. Entonces el argumento para eso es el
propio nombre del atributo, que es texto. Solo consigamos que consigamos
eso para empezar. Entonces encontraremos un uso más
práctico de la misma. Refrescante por aquí, si entro a la consola, se
puede ver que esto es
un componente web, y eso coincide con el
parámetro que establecí por aquí. Eso no es muy útil hasta ahora. Lo que voy a
hacer es el número 1, voy a poner esto
en una variable. Voy a crear una variable
dentro de este componente, así que adjuntándola a esto. Voy a llamarlo contenido de texto
interno. Pero antes de hacer eso,
quiero comprobar si este elemento realmente
tiene ese atributo. Voy a usar el método de atributo has analizando a través del texto
como nombre del atributo. Entonces voy a poner eso
en el bloque if ahí. Nuevamente, esto debería funcionar. Aquí no hay errores, hay registro de consola, pero eso es porque aún no
hemos registrado
nada de la consola ni hemos cambiado
nada. Lo que podría hacer aquí
es igual que antes, usa el método
que teníamos antes este sencillo método de simplemente
configurar el HTML interno. Lo que voy a hacer es usar esa misma estructura de nuevo con el div y el lapso anidado. Pero en el lapso anidado, voy a poner un valor dinámico basado en
ese atributo. Porque establecemos esta
variable aquí mismo, lo que voy a hacer es poner eso aquí
esto.InnerTextContent. Entonces refrescar por aquí. Se puede ver que tenemos el mismo resultado
que el que teníamos antes. Volvamos a nuestro HTML. Si iba a cambiar esto a, este es un componente. Eso es lo que se envía
a través al lapso. Ahora el único tema
con esto es si volvemos aquí
y digamos que tenemos un componente web bastante dinámico aquí
un componente web bastante dinámicodonde este valor
va a cambiar. Si cambio esto a, este es un componente web, de nuevo, simplemente no un
componente.Verás que nada se actualiza. Eso es porque
en realidad tenemos que
observar los cambios en los atributos, para que esto cambie realmente. De vuelta al archivo component.js, vamos a hablar más sobre métodos del ciclo de
vida
en la siguiente sección. Pero por ahora, lo que voy a hacer es mostrarte el método de ciclo de
vida que
podemos usar para comprobar si hay cambio de
atributo. Aquí, nuestro atributo correcto
cambió la devolución de llamada, y toma tres argumentos. El primero es el propio nombre del
atributo. Voy a decir nombre attr. El segundo atributo
es el valor antiguo, y el tercer atributo
es el nuevo valor, el valor al que se
va a cambiar. Entonces voy a
ponerlo en un cheque aquí. Si el nombre atrr es texto, entonces vamos a actualizar
el HTML interno. Mantén esta estructura. En lugar de este contenido de texto
interno, vamos a establecer eso
al nuevo valor que viene
a través de la devolución de llamada. Eso podría
parecer el último paso, pero hay un
paso más que tenemos que hacer, que es decirle
al componente web que cuide
este atributo en particular. Esta es solo una forma de los componentes
web sean
más delgados y se aseguren que no estén
revisando atributos que no importan
al programador. Lo que tenemos que hacer para eso
es simplemente escribir static, obtener atributos observados. Entonces solo vamos
a devolver una matriz con todos los atributos
que queremos ver, que es sólo texto. Vamos a ir a nuestro
navegador aquí, refrescar. Tenemos un error de sintaxis. Eso es porque
necesito poner esto fuera
del constructor. Este es el
método constructor aquí mismo. Necesito poner eso afuera,
refrescar por aquí. Esto debería funcionar. No hay errores. Si entro aquí y cambio, este es un componente a esto es un componente web
o cualquier otra cosa, se
puede ver que el HTML
interno ha cambiado. Hemos ejecutado con éxito
este método aquí porque estamos comprobando cualquier atributo observado
con el nombre del texto. Comprobamos si el nombre del
atributo que viene a través de esta devolución de llamada
es texto, y si es así, actualizamos el HTML interno a esta nueva estructura HTML
con el nuevo valor. Ya hemos cubierto
mucho que ver con la
especificación de elementos personalizados. Voy a romper
la segunda mitad de este video en una parte 2. En la siguiente parte, vamos
a ver los métodos del ciclo de vida
y los eventos personalizados.
5. Elementos personalizados pt 2: En este video de la Parte 2, discutiendo las características de la
especificación de elementos personalizados, vamos a
hablar de métodos del ciclo de vida y elementos personalizados. En el último video, en realidad
vimos uno de estos métodos del ciclo de vida, la devolución de llamada de cambio de atributo. Voy a poner
esto como el número 3, que hablaremos
en tan solo un segundo. Un poco de descargo de responsabilidad
aquí, voy a considerar el constructor número 1 aquí a pesar de que técnicamente no
es un método de ciclo de vida, pero ayuda a mirar constructor en el contexto de la
vida- métodos de ciclo de todos modos. Aquí hay una segunda, que voy a revelar muy pronto, y una cuarta, que voy a revelar aquí. Hablemos primero del
constructor. El constructor, escribiré
algunos aquí y
pondré esto en el
GitHub para ustedes para que puedan referirse a él más tarde. Déjame arreglar este errata. Esto se ejecuta cuando el componente
se crea en memoria, pero no necesariamente
unido al DOM todavía. Según mi investigación, este es el mejor lugar
para la inicialización, pero no el mejor lugar para
interactuar con el DOM. Ahora, la diferencia
entre constructor y el siguiente
es bastante sutil. Pero si alguna vez tienes problemas
con poner algo en esta función constructor
y no funciona, la siguiente es probablemente
donde necesites ponerlo, y esa es la devolución de llamada
conectada. Escribiré eso aquí, devolución de llamada
conectada. Eso se ejecuta cuando el elemento está realmente
unido al DOM. Se ve exactamente
así, devolución de llamada conectada. Este tercero,
como vimos antes, atributo cambiado callback es simplemente verificando si un
atributo ha cambiado. Bastante simple de entender. Esta cuarta que
vamos a mirar es la devolución de llamada desconectada, que es todo lo contrario a la devolución
de llamada conectada. Esto se ejecuta cuando el elemento
se desprende del DOM. Se podría pensar, bueno,
¿por qué necesitamos eso? Es útil para
realizar la limpieza, por lo que procesos que ya no
queremos ejecutar
una vez que nos deshacemos de ella. Se ve exactamente como
la devolución de llamada conectada excepto que es
devuelta de llamada desconectada. Hay uno o dos más, pero estos son los principales. Hemos visto constructor, hemos visto el cambio de atributo callback. Los dos que aún no hemos
mirado hasta que este video estén conectados
y desconectados. Lo que voy a
hacer aquí es poner algunos registros de consola y
luego puedo mostrarte cómo se ve cuando
se ejecuta la devolución de llamada
conectada y
se ejecuta la
devolución de llamada desconectada. Todo lo que voy a hacer es
decir callback conectado, y luego escribir
aquí, callback desconectado. Si ejecuto este código ahora, si entro a mi consola, actualiza la página, puedes ver que se ejecuta la devolución de llamada
conectada. Si pongo en un registro de consola aquí, y digamos constructor, y luego pasamos por aquí, se
puede ver constructor y se ejecuta la devolución de llamada
conectada. Aquí es donde ocurre la sutil
diferencia entre constructor y
callback conectado. La devolución de llamada conectada es
técnicamente cuando el elemento está unido al DOM y constructor
es cuando se crea en la memoria. Pero los dos están
sucediendo automáticamente una vez que ponemos este componente
en nuestro documento. ¿ Cómo puedo
demostrarte la diferencia entre
callback conectado y constructor? Bueno, una de las formas en que
puedo mostrarte esto es mediante eliminación
programática este componente web del DOM, aún teniendo en una memoria
y luego reconectándolo. Eso es lo que voy a hacer
en este ejemplo aquí mismo. Justo por encima de la etiqueta de script
JS componente, voy a crear
otra etiqueta de script. Lo que voy a hacer es agarrar el propio componente
web. Voy a crear un componente web
variable, y luego vamos a usar selector de consultas de
documentos para agarrar el elemento
componente web. Al igual que lo haríamos con
cualquier otro elemento, podemos hacer esto con nuestros propios elementos
personalizados también. Entonces lo que voy a
hacer es simplemente basar esto en el tiempo de espera para los efectos
de este ejemplo. Voy a crear esta función de
tiempo de espera. Vamos a ejecutarlo después de un segundo. Entonces dentro de la función
timeout, lo que voy a hacer
es eliminar child en el cuerpo del documento y eliminar ese HTML
del componente web del cuerpo del documento, sólo para volver a adjuntarlo. DocumentBody.append componente web
hijo. Básicamente, todo esto
está haciendo es después de que se cargue
un segundo de esta
página, vamos a quitar ese componente web
del cuerpo en el que está actualmente encendido y
ponerlo de nuevo en el cuerpo. Refresquemos por aquí
y esperemos un segundo. Se puede ver que la función
constructor se ejecuta una vez porque el componente web
se crea una vez en la memoria. Entonces, por supuesto, la devolución de llamada conectada
ocurre
casi simultáneamente
con el constructor. Pero entonces lo que vemos
después de un segundo, si vuelvo a ejecutar esto,
después de un segundo, que es el parámetro que
ponemos aquí para el tiempo de espera, verás que la devolución de llamada
desconectada se ejecuta porque estamos eliminando
un componente web del DOM y luego lo
estamos devolviendo a poner para que la
devolución de llamada conectada se ejecute de nuevo. Aquí se puede ver la sutil diferencia
entre constructor siendo creado la memoria y la interacción del
componente web con el DOM. A menudo sucede
al mismo tiempo. Pero si tuviéramos que tomar el componente web y
moverlo alrededor de nuestro DOM, entonces la devolución de llamada
conectada y la devolución
de llamada desconectada son útiles. Hemos demostrado
dos en uno allí. Pero si volvemos aquí
y en realidad voy dentro de la sección
de elementos de mis herramientas dev aquí, haga clic en el componente web. En realidad,
aclaremos todo esto. Haga clic en este elemento ahora
y elimínelo de nuestro DOM. Si voy a la pestaña de la consola, se
puede ver que la devolución de
llamada desconectada se ha vuelto a ejecutar. Eso es básicamente llamada
conectada y devolución de llamada
desconectada. Simplemente se ejecuta cuando el
elemento está unido al DOM y cuando el elemento
se desprende del DOM. Veremos cómo necesitamos usar devolución de llamada
conectada
en un ejemplo una vez que lleguemos a
los componentes web en la práctica más adelante en esta
clase, pero por ahora, hasta que tengas un
problema donde tiene que usar la devolución de llamada conectada, probablemente solo
pueda
usar constructor para todas sus inicializaciones
y todo lo que
desea ejecutar cuando se crea este
componente web. Una vez que empiezas a
tener problemas sin embargo con código de
ejecución dentro de
su constructor, es entonces cuando necesita comenzar
a mirar la función de devolución de llamada conectada. Eso son
métodos de ciclo de vida. Por último, en esta
especificación de elementos personalizados, quiero hablar de eventos
personalizados. Lo que voy a hacer es
borrar parte de este código. Voy a deshacerme
de este set Timeout. Todavía voy a mantener mi componente web en
esta constante aquí. Golpea, “Ahorra” en eso,
dirígete por aquí. Lo que voy a hacer es
actualizar este HTML aquí. Voy a tener que hacerlo dos veces porque tenemos esto
por aquí también. Sólo voy a
crear un botón. En este botón,
solo voy a poner el evento
especial desencadenador de contenido. Voy a copiar ese
código hasta aquí. Cuando cambia el atributo, lo que en realidad sucede en la primera vez que el
atributo se establece de todos modos. Si no hacemos esto,
si dejo esto apagado
y ejecuto la página,
verás que el botón
no aparece todos modos porque el cambio de atributo, devolución de llamada se ejecuta tan pronto como
reconozca ese atributo. Este no es el
código más limpio pero vamos a copiar y pegar eso por aquí. Ahora si miro
aquí mi componente y hago clic en este botón, vamos a conseguir que haga
algo muy pronto. Deshaznos de
estos registros de consola. Ya no los necesitamos. Podemos mantener ahí esta devolución de llamada
conectada. Voy a deshacerme de
estos comentarios aquí, los que voy a dejar en
la rama correspondiente del GitHub para que puedas
referenciar eso más adelante. ahora me voy a deshacer de
esos comentarios. Entonces lo que voy a hacer es
crear nuestro propio evento personalizado. Voy a crear un
método que se va a ejecutar en nuestro EventListener, así que desencadenar evento especial. Con el fin de crear
nuestro propio evento personalizado, solo
podemos asignar nuevo evento. En el parámetro aquí, podemos llamar al evento
donde queramos. Sólo voy a
llamarlo Especial. Ahora ese nuevo evento, ese evento especial se almacena en esta constante de evento especial. Cuando se ejecuta este método, lo que podemos hacer es que
podamos despachar ese evento
ejecutando el evento de despacho. Entonces aquí corriendo evento
especial. Entonces lo que vamos a
hacer aquí arriba es ir a nuestra devolución de llamada conectada y agregar un oyente de eventos
al evento click en el botón para ejecutar
este evento especial. Voy a encontrar el botón
dentro de este componente web, que podemos hacer a través de
este selector de consultas. Agregar EventListener,
busque el evento click. Entonces podemos ejecutar este evento especial
disparador. Entonces vamos a vincular esto, por lo tanto, permitiéndonos hacer
referencia a esto como
el componente web. Si el método bind
te confunde un poco, no te preocupes. Me confundió por
un tiempo también. Todo lo que hace es
asegurarse de que esta palabra clave dentro de la función
esté relacionada con esto, el componente web, no esto la función
o cualquier otra cosa. Es sólo un paso extra. Si no lo usamos
terminaremos con este ser no lo que
pretendíamos que sea. Ahora, lo que va a pasar es que cuando hacemos click en el botón, vamos a desencadenar
este evento especial que desplaza nuestro
propio evento personalizado, que se llama evento especial. Pero si hago clic en el botón, realmente
no pasa nada. Técnicamente, este evento
especial se desencadena pero
en realidad no estamos escuchando para
ese evento especial. Nada realmente se
actualiza en la página. Vamos a cambiar eso. Vamos a
entrar en nuestro archivo HTML aquí. Debajo aquí en
nuestra etiqueta de script, voy a agregar ese EventListener
en nuestro componente web. Ya hemos almacenado
nuestro componente web aquí en esta constante, por lo que puedo hacer componente web,
agregar EventListener. Literalmente podemos escuchar el evento especial
que creamos, para que podamos poner en especial. Entonces vamos a poner en esta función anónima que
simplemente se registre la consola. El evento especial
ha sido desencadenado. Aquí tenemos tres pasos. Hemos creado un método de evento
especial el cual despacha un
evento personalizado que llamamos especial. Hemos adjuntado eso al click EventListener
en el botón. Entonces vamos a escuchar
ese evento especial en el
propio componente web y el registro de consola, el evento especial se
ha disparado si ese evento ha
sido despachado. Si volvemos a nuestro
documento aquí y hago clic, “Desencadenar evento especial”, se
puede ver que se va a ejecutar, se
ha disparado
el evento especial. Si hago clic en eso, se puede ver que
el número sube aquí. Obviamente, este sencillo
ejemplo no
comunica realmente la
necesidad de un evento personalizado. Pero cuando empiezas a tener elementos
más complejos puede ser que quieras tener un botón que
desencadena el evento especial. Quieres tener
algo más que desencadena
el evento especial. Simplemente tiene sentido
semánticamente tener un evento especial en
su componente web, entonces esto viene muy bien. Un ejemplo que podrías encontrar en el mundo real es Modals. Es posible que tengas un evento cerrado
en un componente web modal. Ese evento cerrado podría
activarse desde un clic de botón o haciendo clic fuera del modal
o haciendo clic en Cancelar. Tienes tres eventos
separados diferentes que
quieres desencadenar el mismo evento en el propio componente web. A continuación, puede comprobar fuera de
su componente web si se el evento cerrado en ha ejecutadoel evento cerrado en
ese
componente web modal. Ese es un ejemplo que he visto en el mundo real por
usar elementos personalizados. Pero de nuevo, lo he hecho
realmente sencillo en este video, sencillo
posible para que
ustedes lo vean en acción. Nuevamente, si no sientes la
necesidad de usar esta función, no
tienes que usarla. Pero si lo ves en el mundo real y estás
tratando de entender lo que está pasando cuando ves
algo como esto, bueno, esta es la explicación. Podemos crear
eventos personalizados que podamos enviar en nuestro componente web. Eso nos permite buscar eventos que sucedan en el propio componente
web. Es parte de toda esta
mentalidad de encapsular funciones y eventos
dentro de un componente. Eso es todo lo que
quería hablar sobre el tema de la especificación de
elementos personalizados. En el siguiente video,
vamos a hablar del DOM Sombra.
6. El DOM: Bienvenidos de vuelta, chicos. En este video, vamos
a recoger donde lo dejamos con el último video en cuanto
a nuestro pequeño proyecto aquí. Pero vamos a
pasar a algo llamado la especificación Shadow
DOM, que como aprendimos
en la sección de teoría, es una forma en que podemos
adjuntar un sub-árbol DOM a un Componente Web que es
separado del DOM principal. Entonces tenemos nuestro DOM principal aquí como representado por nuestro HTML. Podemos crear lo que
se llama un DOM Sombra en nuestro Componente Web o en cualquier
elemento para ese asunto. Y ese DOM está separado a lo que a
veces se conoce como el Dom de la Luz, que es sombra y
luz son opuestos. Por lo que llamar al DOM Regular el Dom de la Luz es una manera diferenciarlo
del Dom Sombra. Podrías oírme referirme
al DOM Normal como el
Light Dom en este video. Así que sólo una nota ahí. Entonces lo que voy a
hacer es eliminar parte de este código para los eventos personalizados. Es un poco de código tonto de todos modos, eso fue sólo para
demostrar un punto. Entonces voy a deshacerme de
esa devolución de llamada conectada
y ese evento especial. Realmente no necesitamos, dejaré ahí el
Callback desconectado. Y voy a ir por aquí
y simplemente eliminar todo este JavaScript adicional
del documento HTML. Así que vamos a saltar directamente
y adjuntar un Shadow Dom a nuestro Componente Web
personalizado. Cómo hacemos esto es muy sencillo. Lo que hacemos es ejecutar el
método, adjuntar sombra. Y lo hacemos en la palabra clave esta que se refiere al Componente Web, por supuesto. Y todo lo que tenemos que hacer es
pasar en un objeto JavaScript. Y vamos a pasar
en la modalidad de “abierto”. También podemos pasar en
la modalidad de “cerrado”, pero es bastante irrelevante. Se puede mirar hacia arriba por qué
pasaríamos en abierto o cerrado
haciendo alguna investigación, pero no es particularmente
importante en este momento. Entonces lo que voy a hacer
es en lugar de tener nuestro HTML insertado
directamente en el elemento, lo que voy a hacer es
poner aquí sombra Root. Ahora, esta es una palabra clave especial
que nos permite adjuntar este HTML interno a
la raíz de la sombra, que es el inicio
del sub-árbol DOM dentro de
nuestro básicamente Shadow DOM. Permítanme guardar
lo que ya es. Cambia a nuestro HTML. Tengo un diagrama aquí también. Por cierto, se
abrieron entre clases. Te lo mostraré
en tan solo un segundo. Y luego vamos a
refrescarnos por aquí. Entonces vamos a entrar en elementos, y vamos a hacer clic
en ese elemento. Ahora puedes ver que
tenemos lo
mismo que teníamos antes, pero también tenemos
una raíz de sombra. Entonces entonces podemos hacer click
aquí y echar un vistazo, y se puede ver que
tenemos este HTML interno. Ahora la razón por la que tenemos este otro div ahí también, creo es porque no
hemos cambiado esto a la raíz de la sombra. Por lo que voy a cambiar eso,
refrescar por aquí. Y ahora se puede ver si
entramos en nuestro Componente Web, no
tenemos ese
div y span adentro, pero lo que sí tenemos
es un Shadow Dom. Y dentro de ese Shadow Dom, tenemos un div y el lapso, y por supuesto el botón
que
ya no hace nada dentro de ese Shadow Dom. Podrías estar pensando
cuál es la diferencia entre adjuntarlo
al Shadow Dom versus adjuntar este HTML directamente
al Componente Web. Y me alegra que te estés preguntando
eso porque de eso es exactamente de lo voy a hablar ahora
en esta siguiente tabla. Entonces básicamente, lo principal
con Shadow Dom es CSS. Dado que el Shadow Dom está
separado al DOM principal, no hereda el
CSS del Light Dom, como podemos ver aquí
en esta tabla. Si voy al contenido
Shadow Dom, el CSS Light Dom
no aplica. En el otro lado, cualquier CSS
dentro del Shadow Dom no se aplica
al
propio Componente Web ni a ningún contenido externo. Sin embargo, podemos
pasar esto usando el pseudo-selector host de colon, del que hablaremos
en tan solo un segundo. Entonces, básicamente, esta tabla resume la
relación entre Light DOM CSS y Shadow DOM CSS en lo que respecta al propio Componente
Web, contenido
ranurado dentro de
ese Componente Web, y el Sombra contenido DOM. Voy a pasar por cada uno de estos ejemplos muy pronto, pero empecemos
con un ejemplo básico para empezar aquí. Esto es una especie de saltar
adelante en el siguiente video, pero voy a crear una ranura. Así que déjame
entrar en componente aquí. Y en lugar de botón,
lo que voy a hacer es crear una ranura. Sólo voy a
copiarlo aquí abajo también. Por supuesto, cualquier contenido
que me mueva aquí, iremos a donde se ha establecido nuestra etiqueta de
ranura. Entonces lo que voy a hacer es
crear un lapso y decir que esto es un elemento ranurado. Y entonces lo que voy
a hacer es empezar a escribir algún CSS en nuestro Light Dom. Entonces voy a apuntar el lapso y le voy a
dar un color de rojo. Golpea “Guardar” en esa
actualización de aquí. Y se puede ver que esto es un elemento ranurado y
el color es de hecho rojo. Pero lo que puede haber notado
también es que dentro de este div
hay otro lapso. Y ese lapso no
asumió el CSS en nuestro Light Dom y eso es porque es parte
de la raíz de la sombra. Entonces si quisiéramos dar estilo a
esta etiqueta en particular, lo que haríamos es
entrar en el componente aquí, y en cualquier lugar donde
creamos nuestro HTML, creamos una etiqueta de estilo separada. Y luego podemos colorear
nuestro lapso como tal. Hagámoslo verde. Y de nuevo, no el código
más limpio, pero tenemos que copiar
esto aquí también. Le pegaré a “Guardar” en eso y
luego refrescaré por aquí. Se puede ver que el palmo
Shadow Dom es verde y el palmo
ranurado es rojo. Entonces esto es lo básico del
estilo del Shadow Dom. Si tienes un elemento
dentro del Shadow Dom, el estilo normalmente tiene que suceder dentro del
Shadow Dom también. Y eso no afectará ningún
lapso que esté ranurado. Por el contrario, cualquier elemento dentro del Dom Sombra no heredan los estilos
del Dom de la Luz. Entonces como viste aquí, cuando puse una
regla de estilo para el color rojo en tramos dentro
del Light Dom, eso no se aplicaba al
lapso dentro del Dom Sombra. Entonces ese es el ejemplo básico
de estilizar al Shadow Dom. Pero en realidad volvamos a nuestro diagrama aquí y pasemos por todos los
diferentes escenarios. Entonces el primer escenario usando el CSS Light Dom para dar estilo
al propio Componente Web. Lo que quiero decir con eso
es igual que estamos usando el nombre del elemento
para orientar este lapso. También podemos hacer eso
con un Componente Web. Entonces funciona igual que
cualquier otro elemento HTML. Podemos simplemente escribir
Componente Web y
digamos simplemente decoración de texto, subrayar, guardar y actualizar sobre eso
y se puede ver que todo
el Componente Web
tiene un subrayado ahora. Volviendo aquí
al CSS Shadow Dom, en realidad
podemos estilizar el
propio Componente Web desde dentro del Shadow Dom mediante
el un host especial pseudo-selector de
dos puntos. Así que volvamos
y hagamos eso ahora. Entonces Si entro en nuestro
componente aquí, y antes de que hagamos ese lapso
de verde, hagamos hospedaje. Tal vez hagamos que el peso de
la fuente sea negrita de todo lo que hay en
el componente web. Le pegaré a “Guardar” en eso,
refrescaré por aquí. Eso no funciona debido a
este cambio de atributo callback. En realidad limpiemos esto ahora y hagamos este código limpio. En lugar de establecer
exactamente el mismo código dos veces, lo que haré es dirigiré
el span específico aquí y actualizaré ese
valor al nuevo valor. En lugar de establecer
el HTML interno explícitamente en la
raíz de la sombra, volveré aquí,
encontraré ese
lapso particular en la raíz de la sombra, luego apuntaré al
HTML interno de ese lapso, y luego estableceré eso
en el nuevo valor. Eso es mucho más limpio. De esa manera mantenemos la estructura HTML
interna de nuestra raíz de sombra sin tener que actualizar
todo el asunto cada vez. Eso debería hacer que este
trabajo ahora, lo que hace, ahora
tenemos todo el componente
web en negrita, y pudimos hacerlo
dentro de la raíz de la sombra mediante el uso de este
pseudo-selector de host. Volvamos a la mesa aquí. Veamos el contenido
ranurado. El contenido ranurado
en el contexto
del DOM de Luz no se considera parte del DOM
Sombra por lo tanto, los estilos
Light DOM se aplican
aquí. Ya vimos eso. Lo vimos en el caso de este lapso aquí que ha
sido ranurado. El color de ese lapso es rojo. Nuevamente, como no se considera
parte del DOM Sombra, aquí
se aplican los estilos Light DOM. Pero como vimos antes
con el selector de host, hay una manera de que podamos dar estilo este contenido ranurado dentro
del Shadow DOM CSS también. Solo necesitamos usar la pseudo-clase ranurada de
colon y tenemos que pasar
en un parámetro. Vámonos y hagamos eso ahora mismo. Vamos a entrar en nuestro archivo
component.js. Vamos a poner en esta
pseudo-clase ranurada y el parámetro. Vamos a poner en el
lapso para que estemos peinando el ranurado en lapso. Permítanme cambiar el color a, digamos, gris. Entonces si vamos por
aquí y refrescamos, ¿qué crees que
va a pasar? Vamos a averiguarlo. Como se puede ver, no
hay cambio
en estos colores. ¿ Por qué es eso? Si
echamos un vistazo a este segundo elemento aquí, que es el elemento ranurado en, y
miramos los estilos aplicados se puede ver que tenemos
nuestro color rojo aquí, y luego tenemos
nuestro color gris para el lapso pero el color
rojo es sobrescribir. Esto es congruente
con lo que he escrito en la tabla
aquí que es, en el caso de los conflictos, los estilos del
DOM Light tienen prioridad. Se podría pensar, he puesto esto último para que el gris se
apoderara pero, en el caso de que
haya un estilo para ese particular ranurado en
contenido en el DOM Light, el estilo en el DOM Light
llega a controlar el color. Si quisiéramos estilizar este ranurado en lapso dentro de
nuestro DOM Sombra, tenemos
que asegurarnos de que esto no esté ahí. Si comento eso fuera y
luego refresco por aquí, se
puede ver que
podemos darle estilo a gris cuando no se sobrescribe por un estilo que se relaciona con el mismo elemento
dentro de nuestro DOM de Luz. Refrescante por aquí,
mantengámoslo en rojo, y volvamos a
nuestra fila final
aparte de la excepción aquí para contenido
Shadow DOM en nuestra tabla. Cualquier Light DOM CSS
no tendrá ningún efecto en nuestro DOM Sombra. Creo que ya podemos ver
algunos ejemplos de esto. Podemos ver que hay una regla de color para
el rojo en todos los elementos de span. Pero si entramos aquí, tenemos un lapso en
nuestro DOM Sombra y, por
supuesto, sigue siendo verde. Ya hemos visto eso y luego con el Shadow DOM
CSS, obviamente, cualquier CSS que creamos
en el DOM Sombra
va a tener un
efecto directo en el DOM Sombra. Nuevamente, vimos que con estilo de nuestro elemento span
dentro del DOM Sombra, se
puede ver que es verde. Eso es básicamente toda
la mesa. La única excepción es Light DOM Las variables CSS son accesibles dentro
del CSS Shadow DOM. Si has usado
variables CSS antes, básicamente cómo funciona esto es, en nuestro Light DOM, podemos
crear algunas variables CSS. Lo que voy a
hacer es, en root, crear una variable CSS llamada color
BG y lo
estableceremos en negro. Entonces lo que voy a hacer es
entrar a aquí y vamos a establecer el color de fondo a
la variable de color BG, presionar “Guardar” en eso,
refrescar por aquí. Se puede ver que a pesar la variable CSS fue
definida en el DOM Light, todavía
podemos
traerla al DOM Sombra. Es solo que la regla
CSS necesita
estar en el Shadow DOM CSS. Esto nos da cierto control
del contenido Shadow DOM en términos de usar variables
dentro de nuestro DOM de Luz. Si tuviéramos un esquema de color, puedo cambiar esto a, hagamos esto amarillo
y le pegamos a “Guardar” en esto. Ahora, se puede ver podemos
actualizar valores dentro
del DOM de Luz y
eso afectará el DOM Sombra al
usar variables. Pero aparte de eso, si fuéramos a entrar aquí y decir lapso, fondo, color de,
¿qué debemos hacer? Vámonos azules. esta regla de lapso dos veces así solo
voy a
comentar esa. Le pegaré a “Guardar”,
refrescaré por aquí. Se puede ver el fondo azul solo se aplica al contenido
ranurado. No se aplica al
lapso dentro del DOM Sombra. En realidad no podemos cambiar este color a través del DOM de
Luz a menos que, por
supuesto, hagamos referencia a
estas variables. Si alguna vez se pierden, los
vincularé
a esta mesa de aquí mismo. Pondré un enlace en tu pantalla
ahora mismo para que puedas ir a comprobarlo cuando
publique esta clase. Pero esencialmente el
DOM Sombra se trata principalmente de CSS. Es una forma para nosotros
arreglar el CSS de un
elemento quizá si
estuviéramos compartiendo elementos a través de
diferentes proyectos y queríamos que el elemento
luzca exactamente igual, sin importar en qué
proyecto estuviera, el DOM Sombra sería
útil. Pero dentro de tus propias
aplicaciones privadas y páginas web, no
estoy seguro de
que el Shadow
DOM sea demasiado requerido, por eso no lo
vamos a utilizar en el ejemplo práctico al final de esta clase. Pero es popular
dentro de los componentes web por lo que era importante aprender esta lección sobre el DOM Sombra. Como siempre, todo esto va
a estar comprometido con GitHub, por lo que puedes esperar
este código más adelante. Yo, por supuesto,
compartiré esta mesa
contigo pero eso
resume más o menos el DOM Sombra. En el siguiente video,
hablemos de slots y plantillas.
7. Ranuras y plantillas: Bienvenidos de vuelta chicos. En este video
vamos a hablar slots y plantillas,
que son bastante básicas. Ya usamos una ranura
en el video anterior. Lo ranuramos en
algún contenido aquí. Básicamente anidamos
un lapso dentro de este componente web
y luego
pudimos elegir dónde
queríamos que se deslizara hacia esta estructura HTML particular
dentro de nuestro DOM sombra. Al echar un vistazo a eso
en el navegador real, puedes ver que tenemos
nuestra raíz de sombra aquí. Si entro al div y
entro en este
contenido ranurado aquí, se
puede ver que hay un enlace a lo ranurado en contenido
que está aquí mismo. Es una cosa rara donde
técnicamente no es parte
del DOM sombra, pero está ranurado en el DOM sombra aquí
a través de esta etiqueta de ranura. Ahora ya hemos visto
que en
la práctica, lo siguiente a
mirar es nombrar las ranuras, así que si queremos usar múltiples ranuras dentro de un componente web
en particular. Para demostrar esto, voy a eliminar
todo el código que
realmente no necesitamos para
esta demostración. De nuevo, podemos dejar en la devolución de llamada
desconectada, pero voy a deshacerme
de este atributo aquí. Deshazte de eso. Entonces
voy a deshacerme del atributo tal como
existe aquí en el HTML. Voy a crear
otro lapso aquí. Entonces voy a
escribir este lapso también
ha sido ranurado. Si pego, “Ahorra” en eso,
veamos qué pasa ahora. Si refresco la
página se puede ver hay dos tramos
dentro de esta ranura. Pero lo que podemos hacer
a través de ranuras de nombre es encajar estos dos tramos en
diferentes partes de la misma estructura HTML.
¿ A qué me refiero con eso? Bueno, pasemos
a nuestro
archivo component.js aquí y cambiemos esto. Digamos que tenemos dos divs. El primer div va a tener un **** para el primer
lapso y vamos crear otro div que se
separe a ese div y dentro va a ser el segundo lapso que muestro
en mi componente web. Una vez que nombramos estas ranuras, lo que va a pasar es que
este lapso va a entrar en la primera ranura y este lapso va a
entrar en la segunda ranura. Podemos empezar ya sea en el documento HTML o en
el documento JavaScript. Voy a empezar aquí
en el JavaScript, todo lo que tengo que hacer es
nombrar la ranura agregando aquí
el parámetro name y luego aquí solo
voy a llamarlo Ranura 1. Entonces voy a bajar
al segundo slot y
nombrarlo Ranura 2. Entonces más en nuestro index.html
para enlazar estos hacia arriba es que voy a usar
el parámetro slot, y voy a
volver a usar ese nombre,
así que la Ranura 1, y luego slot es igual a Ranura 2. Ahora si pego, “Guardar”
y refrescar por aquí, ¿qué crees
que va a pasar? Vamos a refrescarnos y
echemos un vistazo por dentro. Como pueden ver, tenemos nuestros dos
elementos ranurados por aquí, pero en cuanto a dónde
encajan en nuestra estructura de raíz de sombra, abramos a este chico
malo y
podemos ver que tenemos dos divs. En el primer div, tenemos
el primer contenido ranurado, y en el segundo div,
tenemos el segundo contenido ranurado. Ahora están en divs separados y podríamos necesitar eso para
todo lo que necesitemos hacer
con nuestra estructura HTML, así que estilismo y todo eso. Así es como podemos ranurar
en múltiples cosas en diferentes partes de
nuestra estructura de sombra DOM. Siguiendo con esto, lo
siguiente que quiero mostrarte son las plantillas. Voy a quitar
este código justo aquí [RUIDO] entonces voy
a poner en un HTML, las reglas de estilo y
voy a
volver a index.html aquí. Voy a
dirigirme aquí y eliminar este contenido porque
lo que vamos a hacer es poner contenido dentro de
una plantilla y luego llevar ese contenido
al componente web. Podemos hacer esto una de dos formas. Estoy seguro que podemos
hacerlo de múltiples maneras, pero hay dos formas en que te voy a
mostrar en este video. Podríamos poner la etiqueta de plantilla fuera del componente web. En este caso, vamos
a darle una identificación. Sólo lo voy a llamar
plantilla por el sake de simplicidad. Entonces aquí, vamos a
crear nuestra plantilla. Simplemente haré un h1 y diré que este código de plantilla
conforma el componente web. Entonces voy a crear
una etiqueta de párrafo y usando Emmet dentro de
Visual Studio Code, puedo escribir Lorem hit, “Tab” y generará
Lorem Ipsum automáticamente. Sólo voy a arreglar el espaciado aquí para que ustedes puedan ver
todo el párrafo. Golpe, “Guardar” en eso. Ahora, debido a que esta
es una etiqueta de plantilla, no
se
renderizará en tiempo de ejecución. Si vuelvo aquí, ejecute el código,
verá que tenemos nuestro código de
plantilla aquí. Tenemos este
fragmento de documento aquí, así que sí tenemos el
código en nuestro HTML, pero nada es renderizado y
eso es porque está
dentro de una etiqueta de plantilla, lo
que significa que no va
a renderizar a menos que tomemos ese código de plantilla y
renderizarlo usando JavaScript. Eso es exactamente lo que
estoy a punto de hacer. Voy a volver
a nuestro editor de código aquí y me dirijo
a component.js. Lo que voy a hacer es después de establecer
nuestro HTML interno aquí, que es sólo la etiqueta de estilo, lo que voy a hacer es
encontrar ese código de plantilla. Cómo puedo hacer eso es mediante selector de consultas de
documentos. Básicamente solo quiero
encontrar ese elemento. Era una plantilla con
el ID de plantilla. Por eso he puesto
hachís delante de él. Entonces voy a encontrar el contenido de eso
y luego voy a ejecutar clone Node con
el parámetro de true. Con el parámetro de true
que representa un clon profundo, por lo que cualquier subelemento dentro la plantilla se
renderizará también. Realmente no puedo pensar en
una situación en la que te gustaría correr falso aquí. Sólo mantengámoslo con verdad. Por supuesto que vamos a
necesitar usar eso algo. Voy a guardarlo en una
variable, una constante primero. Ahora, tenemos nuestra plantilla de
const. Parece que
accidentalmente he colocado esto fuera de la función
constructor, así que voy a poner eso de nuevo
ahí. Perdón por eso. Ahora, con esta plantilla,
lo que puedo hacer es que puedo adjuntar ese nodo clonado
a la raíz de sombra. Voy a agarrar
la raíz de sombra aquí y ejecutar anexar a un niño, colocando ese código
de plantilla ahí como argumento. Vamos a refrescar la página por
aquí y ver qué pasa. Ya puedes ver que ahora tenemos el código de plantilla funcionando
dentro de nuestro componente web. Si entro en el código
del componente web aquí, puedes ver que tenemos
nuestra raíz de sombra
y dentro de la raíz de la
sombra tenemos la etiqueta de estilo que configuramos configurando explícitamente
el HTML interno. Entonces tenemos la etiqueta h1 y p que configuramos
en la plantilla. Lo que también podemos hacer para hacer esto un poco más simple y encapsulado es poner
la etiqueta de plantilla dentro del propio componente web. Sólo voy a copiar eso
y luego comentarlo. Vayamos dentro
del componente web. Ahora, porque estamos dentro
del componente web, solo
podemos hacer referencia
al elemento template
en lugar de tener un ID. Voy a golpear,
“Guardar” en eso y luego ir aquí a nuestro código y lo que podemos hacer en su lugar
es quitarle este hash. En lugar de documento,
podemos decir esto. Esto buscará cualquier plantilla
dentro de nuestro componente web. Voy a golpear, “Guardar” en
eso, refrescar por aquí, y ya ves que obtenemos
exactamente el mismo resultado. Se puede ver que la plantilla está
en el componente web y luego el código que teníamos
en esa plantilla ha sido clonado dentro
del DOM sombra. Esto funciona igual que si no
estuviéramos usando el DOM de
sombra en absoluto. Simplemente quitemos la
sombra DOM por completo. En realidad, sólo
voy a comentar
porque creo que podríamos
usarlo en el siguiente video. Vamos a anexarlo
al HTML interno real. Refresca aquí y
verás que no se va añadiendo y eso es porque todavía
tenemos raíz de sombra aquí. Esta
actualización de hijo anexa por aquí. Nuevamente, no funciona.
¿ Qué hemos hecho? No se pueden leer propiedades de null. Creo que el tema
aquí es que hemos establecido en nuestro HTML explícitamente, que está eliminando el contenido HTML dentro del componente web
que hemos puesto aquí, que es solo esta etiqueta de plantilla. En este caso, lo que haría es que me dirigía
por aquí y
simplemente nos deshacemos de esto y su lugar pondría esto directamente
en la plantilla, que es un poco más limpia de todos modos. Vamos a “Guardar” en eso y
luego al lado de la plantilla, pondré la etiqueta de estilo
directamente en nuestro HTML. Golpeé “Guardar” en
esa actualización por aquí y el tema se ha ido ahora. Dependiendo de cómo
quieras hacerlo, esto realmente se ve bastante limpio porque no estamos poniendo ningún HTML dentro del
JavaScript en absoluto. Estamos poniendo todo el
HTML y los estilos que entran dentro de nuestro componente
web. Pero debido a que ya no estamos usando
un DOM de sombra, estos estilos teóricamente
se aplicarán a todo. Si entramos aquí y ponemos un lapso, digamos que esto es un lapso. Refresca por aquí. los estilos de nuestra luz
DOM que tenemos
aquí arriba y nuestros estilos aquí dentro del componente web ambos
se aplicarán. Si le doy un vistazo a esto, echemos un vistazo a este lapso
particular aquí. Se puede ver que el color de fondo azul y el
color de fondo amarillo se están aplicando. Pero debido a que esto está sucediendo
más adelante en el documento, está anulando a
éste de aquí mismo. Esencialmente, no tiene
sentido que tengamos
aquí una etiqueta de estilo si pretendemos que esto solo se aplique
al componente web, en ese caso,
querríamos pegarnos con el DOM sombra. Sólo voy a retroceso
aquí y de vuelta por aquí. Vamos a mantener el
DOM sombra, refrescar por aquí. Entonces si iba a agregar un lapso a nuestra plantilla
aquí, actualízate. Inspeccione ese elemento.
Se puede ver que ninguno de los estilos de la
luz DOM se están aplicando aquí porque este código de
plantilla se está poniendo en una sombra DOM
y luego, solo los estilos que
tenemos en nuestra raíz de sombra se aplicará a ella. Cosas bastante simples
de plantillas aquí, mucha flexibilidad dentro de
esto, pero esencialmente, todo lo que se necesita es crear una etiqueta de
plantilla y entonces lo vamos a hacer es
básicamente encontrar esa plantilla, mira su contenido, y ejecuta clone Node para crear un nodo DOM o un sub árbol DOM basado en esa plantilla y
luego podemos anexarlo donde queramos en
nuestro componente web, ya sea a la raíz de sombra o
a el HTML interno directamente. Eso cubre ranuras y plantillas. En el siguiente video,
vamos a cubrir elementos
incorporados personalizados.
8. Elementos de Built-in personalizados: Muy bien chicos. En este
video vamos a cubrir elementos
incorporados personalizados. Entonces hasta este punto, hemos estado extendiendo
la raíz HTMLElement. Pero ahora vamos a extender
un HTMLElement específico, y esto es lo que se
conoce como construir un elemento incorporado personalizado. Entonces lo que voy a
hacer es eliminar todo este código porque
estamos creando un elemento completamente nuevo y
porque estoy haciendo eso, voy a entrar en
mi índice por aquí y eliminar todo este código también. También podríamos eliminar
cualquier cosa dentro de nuestra etiqueta de estilo. Aquí tenemos una pizarra bastante
limpia. Entonces para demostrar un elemento incorporado
personalizado, voy a extender el elemento de botón
HTML. Entonces lo que vamos
a hacer es crear nuestro propio botón personalizado. Así que a partir de la
misma manera que normalmente lo
haríamos escribiendo
clase y luego
voy a llamar a mi elemento de botón
personalizado, literalmente solo CustomButton. Entonces voy a escribir extiende y en lugar de
escribir HTMLElement, lo que voy a hacer
es HTMLButtonElement. Ahora si estás usando un editor de
código o IDE, como Visual Studio Code, puedes ver después
de escribir HTML, puedes ver una lista completa de todos estos diferentes
elementos que puedo usar. El formato es básicamente HTML, el nombre del elemento
y luego elemento. Para que pueda extender un elemento de
encabezado. Puedo extender un elemento de imagen, un elemento de entrada, una etiqueta, un enlace, tantas opciones
diferentes aquí. Entonces, si necesitas navegar por
las diferentes opciones, no
estás seguro de cuál es
el nombre de la clase, entonces esto realmente ayuda. Pero lo que estoy buscando
es un HTMLButtonElement, así que voy a golpear eso. Entonces vamos a abrirla
como lo hicimos la última vez. Voy a escribir
nuestro método de
definición CustomElements como lo hemos hecho anteriormente para los componentes
web estándar, y voy a hacer que
la etiqueta custom-button. Entonces como segundo
argumento, como de costumbre, vamos a poner
esa clase en pero aquí es donde vuelve a ser
diferente. Tenemos que poner en
un tercer argumento. Tenemos que poner en un objeto
JavaScript con un par de valores clave. La clave va a ser extiende
y el valor es la etiqueta del elemento que estamos
extendiendo así que para un botón HTML, la etiqueta es por supuesto botón. Si tuviera que escribir
esto en el HTML, será así que básicamente
estás tomando la palabra
que está en medio
del menos que y
mayor que firmar
y poniéndola
aquí después de extiende. Si este fue un
enlace personalizado por ejemplo, permítanme engañar usando
auto-completar allí. Si estuviéramos extendiendo
tu elemento de enlace HTML, esto cambiaría a 'a', porque eso
es lo que se representa
la etiqueta de anclaje como en el HTML. Pero estamos haciendo
botón así que voy
a Control Z hasta que
volvamos al botón. Entonces como lo hemos hecho anteriormente con componentes
web estándar, voy a crear aquí
un constructor y luego por supuesto
voy a ejecutar super para que podamos heredar
la función constructor de la clase que
estamos extendiendo, que era HTMLButtonElement. Entonces lo que voy a
hacer es dirigirme a nuestro index.html aquí y
escribir algo de HTML. En realidad vamos a crear ese elemento incorporado
personalizado. La forma en que hacemos eso es diferente a los componentes
web estándar. En realidad vamos a
utilizar el nombre original
del elemento que estamos personalizando.
Va a ser botón. Dentro de este botón, sólo
voy a escribir presionarme y luego aquí para convertirlo en nuestro elemento incorporado personalizado y no sólo un botón estándar, vamos a usar
el atributo de is. Entonces dentro de aquí, botón personalizado, que coincide con lo que
hemos escrito en el primer argumento de
nuestro método definido aquí. Volviendo aquí,
lo que podría hacer por este ejemplo es que
voy a poner en un enlace. Voy a poner en
un atributo personalizado de link y
sólo vamos a conseguirlo para ir a google.com. Entonces esto sería como el comportamiento
estándar de una etiqueta de enlace quizás. Por lo que escribiríamos href, y luego si hacemos
clic en el enlace, iría a
esa URL específica. En este caso, si
acabo de hacer esto en este
momento y vuelvo
a nuestro código por aquí y hago clic en “
Presionarme” nada va a pasar porque este es
un atributo personalizado. No va a hacer
nada a menos que escribimos algún código en nuestro componente
aquí para manejar eso. Entonces eso es exactamente lo
que voy a hacer a continuación. Voy a agarrar ese
valor para que esto.getAttribute. Entonces voy a poner
el nombre del atributo en su link y luego por
supuesto voy a
guardar eso en alguna parte. Voy a almacenarlo en
el propio componente web, así que voy a decir que
esto.link es igual
al valor de
this.getAttribute link. Si quisiera, también
podría hacer si esto tiene atributo
como lo hicimos antes, pero solo voy
a asumir que
sí tiene eso porque tengo el control de escribir este
código y voy a asegúrate de que
tenga ese atributo. Entonces lo que voy a hacer es que
voy a configurar un oyente de
eventos. Si se hace clic en este elemento, así que haga clic en “Evento” entonces
voy a ejecutar este código. Lo que voy a hacer es cambiar la ubicación de la ventana href
al valor de this.link. Lo que hemos hecho
aquí es que hemos tomado el valor dentro
del atributo link, lo
almacenamos en esta variable
y luego hemos hecho un oyente de eventos para el evento click en
este botón personalizado. Cuando se haga clic,
va a redirigir al usuario a lo que almacenamos
en ese atributo link. Entonces probemos si esto funciona. Ahora, voy a refrescar por aquí y voy
a hacer clic en “Presionarme”, y como pueden ver, vamos a google.com. Ahora de nuevo, no es el ejemplo
más práctico porque podríamos haber
utilizado simplemente una etiqueta de enlace para esto. Pero permítanme simplemente extender este
ejemplo un poco más allá. Porque tenemos
aquí un elemento que está heredando todo el comportamiento original
de un elemento de botón, tal vez
tengamos que evitar que se
comporte como un botón. Un ejemplo de esto
sería si estuviera dentro de un formulario. Voy a tener un formulario
aquí y voy a poner la acción a punto final
como ejemplo. Esto obviamente va a enviar el formulario a ninguna parte porque en realidad no
tengo un punto final. Eso se llama punto final. Entonces si presiono “Guardar”
en eso y refresco por aquí y hago
clic en “Presionarme”, verás que hereda el comportamiento de un
botón dentro de un formulario, que es enviar el formulario. Entonces aquí se puede
ver que vamos a este punto final aquí
que no existe. Entonces esto es por supuesto
diferente a si
tuviera una etiqueta de enlace porque
tenemos una etiqueta de enlace, Número 1 no
aparecería luciendo así
porque no es un botón. Número 2, una etiqueta de enlace
no activa una cumbre de una forma
si está dentro de uno. Entonces lo que podemos hacer es que pueda
pasar a component.js aquí y puedo ir
event.preventDefault. Se guarda en esa
actualización de aquí. Si hago clic en esto, aunque esté dentro de un formulario, va a evitar ese comportamiento predeterminado
y luego
va a hacer lo que le
hemos dicho que haga, que es redirigir al usuario a cualquiera que sea la dirección
en el atributo link. Volviendo aquí, sólo
para perforar esta casa, si tuviera que poner en
un botón estándar que no fuera uno de nuestros elementos incorporados
personalizados y decir que me puedes presionar
también y luego me
refresco por aquí. Si hago clic en el me
puedes presionar también, va a actuar como un
botón estándar y enviar el formulario. Pero debido a que hemos personalizado este otro botón para evitar defecto y en su lugar redirigir
al usuario a google.com, se va a
comportar de manera diferente. Por lo que ojalá de nuevo, no el ejemplo
más práctico, pero ojalá esto comunique lo que podemos hacer con los elementos. Podemos tomar parte
del comportamiento y atributos
de un elemento que nos guste, y podemos
modificarlos a nuestros fines. Obviamente, aquí hay
montos locos de flexibilidad. Puedes tomar esto en la dirección
que quieras, pero esto no es algo
que
utilicemos particularmente en la
sección práctica de esta clase, solo algo que tener en
cuenta porque sí cae bajo la especificación del
componente web. Podemos extender
elementos específicos aquí, y esto es lo que se conoce como elementos incorporados
personalizados. Chicos, así que en el siguiente video, lo que vamos a hacer es cubrir la especificación final de la que aún no
hemos hablado, que es la especificación de
módulos ES. Te veré en el siguiente video.
9. ES Modules: Chicos, así que en este video
final antes entrar en nuestro proyecto de
clase práctica, hablemos de los módulos ES, que es la cuarta
especificación dentro la
meta-especificación de componentes web. Los módulos ES es
esencialmente una forma para nosotros estructurar nuestro
proyecto de manera diferente. Podemos poner cada uno de
nuestros componentes en su propio
archivo JavaScript modular y luego llevarlo a otro
archivo JavaScript y luego traer ese archivo JavaScript
a nuestro documento HTML. O alternativamente,
podemos simplemente traer cada componente a nuestro
documento HTML sin ese archivo. Pero en los ejemplos
que te voy a mostrar, voy a importar todos
los componentes en un
solo archivo JavaScript, y luego vamos a colocarlo en nuestro documento HTML. Algunos proyectos, esto
va a ser muy útil, algunos proyectos no va
a tener sentido en absoluto. Vamos a utilizar módulos ES en la práctica que
viene después de esta lección. Esto será algo que
veremos en acción muy pronto pero para esta lección, realidad
demostremos módulos ES. Como dije, lo que voy
a hacer es que voy a importar todos nuestros componentes, ahora mismo hay sólo uno pero voy a
hacer un segundo en un archivo JavaScript central, y voy a llame a
ese index.js. Ahora lo que voy a
hacer para ponernos en marcha, vamos a cerrar esto abajo para que
podamos ver todo el asunto, es que voy a mover este elemento
personalizado define método aquí y pasar
eso a nuestro index.js. Para que tengamos acceso
a esta clase justo aquí, lo que voy a tener que
hacer es exportarla desde aquí y luego
importarla a aquí. En primer lugar, porque
sólo tenemos la clase única aquí, no
voy a
hacer una exportación con nombre, voy a hacer una exportación
sin nombre. Acabo de exportar por defecto y luego el
nombre de clase que quiero exportar. Lo que esto hace es
exportar solo esta clase, así que una vez que la importe aquí, puedo referirla
directamente en nuestro código aquí. Voy a ejecutar la declaración de
importación aquí, estamos buscando
botón personalizado y luego, después de la palabra clave from aquí, puse la ruta al archivo. Ahora, que he hecho eso, lo que necesito hacer es actualizar
el código aquí así que en lugar de component.js, puse index.js. Como vimos en la lección de teoría, necesito cambiar o agregar el atributo aquí
del módulo de tipo. Le pegaré, “Ahorra” en eso. Vamos a refrescarnos por aquí. Deberíamos ver que todavía tenemos estos botones pero si hago
clic en el primero, que es nuestro elemento
incorporado personalizado, se
puede ver que
tenemos la misma funcionalidad que un botón
estándar. Ambos son
exactamente iguales. El motivo está justo aquí
en nuestra Consola JavaScript. Tenemos un error de política CORS
aquí y la razón por la que es porque realmente no podemos hacer esto ejecutando el HTML desde
el sistema de archivos. Lo que tenemos que hacer
es ejecutar un servidor. Eso es muy fácil dentro del código de
Visual Studio. Ojalá también sea fácil y
sencillo en tu IDE. Si no, siempre puedes usar Visual Studio Code y solo
voy a bajar aquí
y hacer click en Go Live. Ahora puedes ver que estamos
ejecutando un servidor. La forma en que puedo ver eso es
porque tenemos
aquí una dirección IP en lugar de una ruta
desde el sistema de archivos. Ahora, si presiono Command Option I para
sacar la consola, no se ven errores
y si hago clic, “Presioname”, me
llevará a Google en lugar de
ese punto final que está buscando aquí. Voy a
cerrar éste en el sistema de archivos y solo
usaremos éste. Aquí, se puede ver todo
esto ya funcionando. Hemos importado código de
component.js a index.js, y luego lo hemos
importado a index.html. Pero esto
realmente no tendrá sentido, y por eso hemos creado
otro componente. Voy a crear un
segundo componente aquí. Esto es terrible nomenclatura
pero sólo voy a llamarlo component-2. ¿ Sabes qué? Solo por diversión, vamos a crear otro elemento incorporado
personalizado. Voy a escribir
clase y vamos a extender el elemento link para
crear un enlace personalizado. Voy a escribir enlace personalizado extiende HTML, elemento de anclaje. Abre eso aquí, obviamente voy a
poner el constructor. Entonces voy a llamar super
como siempre lo hemos hecho. Para esto, lo que podría hacer es agregar event-oyente para click, [RUIDO] esto es
similar a lo que hicimos antes pero ahora tenemos el comportamiento predeterminado
de una etiqueta de anclaje. Lo que voy a hacer es básicamente hacer de esto
un enlace de confirmación. Voy a ejecutar Confirmar y pedirle
al usuario que confirme que
quiere usar Google. Quieres usar Google
y luego si eso vuelve tan falso como puedes ver a partir de este signo de
exclamación aquí, entonces voy a
evitar el default. Voy a evitar que el
usuario use ese enlace. Bastante ejemplo básico ahí. Entonces por supuesto,
voy a exportar eso, y como solo estamos
exportando una clase, puedo usar por defecto aquí. Vamos a
exportar enlace personalizado, y luego vamos
a entrar en index.js y usar el mismo formato. Voy a importar botón
personalizado desde component2.js y luego escribiremos nuestro
método definido aquí abajo,
así que elementos personalizados, definirlo, llámalo enlace de guión
personalizado. Entonces ponemos el nombre de la clase, es el segundo argumento. Entonces en nuestros extiende aquí, vamos a estar extendiendo
el elemento de anclaje estándar, que se acaba de representar
como un en el HTML. Si entonces me dirijo
a mi index.html, ya
estamos importando
todo este código. Todo lo que necesito hacer es simplemente
escribir una etiqueta aquí. Hagámoslo para ir
a Google de nuevo. Entonces por supuesto,
para asumir la funcionalidad de este elemento incorporado
personalizado, voy a tener que escribir es y luego dentro
del atributo is, poner en el nombre que
especifiquemos cuál es enlace personalizado y luego solo
voy a hacer clic derecho en
mí para ir a Google. Golpe, “Guardar” en eso.
Vamos a refrescarnos por aquí. Se puede ver el enlace ahí. Ni siquiera tuvimos que actualizar porque estamos usando Live Server, que es solo una característica
dentro de Visual Studio Code. Esto se llama recarga en caliente. Entonces si hago click en esto me va a preguntar si definitivamente
querría ir a Google. Si hago clic, “Cancelar”, va a evitar el comportamiento predeterminado, que
me está dirigiendo a esa dirección. Pero si hago clic en él y hago clic, “Está bien”, me va
a dirigir ahí. la funcionalidad dentro del componente real Sin embargo,
la funcionalidad dentro del componente real
en sí no es el
punto aquí. El punto es nuestra capacidad
para exportar clases de documentos
JavaScript a
otros documentos JavaScript y
a documentos HTML
mediante el uso de módulos ES. Ojalá, ese es
un concepto genial para ustedes chicos que
acaban de aprender. En el siguiente video, vamos a empezar a
construir esto como una aplicación práctica. En ese video, tal vez múltiples videos
dependiendo del tiempo que vayamos, nos
verás usando
módulos ES en acción y así lo
verás en la práctica un
poco más en los próximos videos. Eso es básicamente
las cuatro especificaciones para la
meta-especificación del componente web. En realidad pongamos
esto en práctica en el siguiente video y
creamos nuestro propio proyecto personalizado.
10. Componentes web en la práctica, parte 1: Muy bien, todos. Bienvenido a la parte práctica
basada en proyectos de la clase. Recibo la retroalimentación con
bastante regularidad de ustedes chicos que quieren
ver ejemplos más prácticos. En este curso hasta ahora, no
hemos visto demasiados de
ellos si estoy siendo honesto. Sin tener unos
pocos componentes web trabajando juntos y
sin un caso de uso, es
difícil demostrar casos prácticos
reales de uso componentes
web y muchas de
estas especificaciones que no necesitas usar
en la única vez. Por ejemplo, en este proyecto
que estamos a punto de crear, no
estoy usando el
Shadow DOM en absoluto porque no siento la
necesidad de usarlo a menos que esté tratando de mantener mi DOM Sombra separada
y lo que quiero decir con separado como en el estilo CSS
separado sabio al resto de mi proyecto. Si estoy en control
de mi propio proyecto, entonces realmente no
siento la necesidad de
tener que crear un
DOM Sombra porque sí,
tal vez sí quiero que los estilos del DOM de Luz
afecten al DOM Sombra. Mezcle y combine
cualquiera de
las características de cualquier especificación
que tenga sentido para usted. Espero que hayan aprendido algunos buenos fundamentos
en esta clase, pero quería incluir una
lección más práctica basada en proyectos para ustedes chicos. Esto probablemente
tendrá que
dividirse en múltiples lecciones, por lo que esto podría aparecer como múltiples videos dentro de
esta clase de Skillshare. Pero lo que quiero hacer es
crear un ejemplo práctico, el
ejemplo más práctico que puedo pensar y usar ese
ejemplo práctico que vimos anteriormente en la clase con el
ejemplo de e-commerce vía Shopify para crear nuestro propio proyecto
inspirado en el comercio electrónico, y si quieres llevar
este proyecto más allá, úsalo como inspiración para algo que quieras
usar en el mundo real. Siéntase libre de hacerlo. Pero en lugar de, yap más sobre ello, quiero simplemente saltar
directamente en él y dejar que ustedes sigan junto con
lo que estoy creando aquí. Para este proyecto, voy
a comprometer todo en Git para que puedas mirar este código más tarde y
comparar tu código con él. Eso ha sido una crítica de algunas de mis clases en
el pasado también, es que ustedes no han podido
realmente
mirar el código en sí
aparte de en los videos. Yo los he escuchado
chicos en eso también,
y así que voy a
estar comprometiendo como voy y ustedes pueden mirar este código en GitHub después se publique
esta clase y
comparar su código con el mío. Sin más preámbulos, vamos a meternos en ello. Voy a crear una carpeta de
proyecto aquí dentro de la carpeta de código donde
creamos la otra carpeta. Voy a llamar a este carro
de compras. Después trae
Visual Studio Code, luego toma esta carpeta, arrástrela a Visual Studio
Code, y por lo tanto, sé que estoy abriendo
esa carpeta en particular. Obviamente,
extenderé esto hasta el ancho completo de su visualización. Ahí vamos, y empecemos con nuestro contenido
de calderas. Entonces voy a crear un
nuevo archivo con index.html. Lo mismo que he
hecho en el pasado, usa el signo de exclamación para generar un documento
HTML de calderas. Llamemos a este carrito de compras. Entonces lo que voy a hacer
es copiar en algunos activos, CSS y activos de imagen porque esta clase no está realmente en CSS, y por supuesto no voy a
ir a conseguir que
consigas tus propias imágenes, así que voy
traen esos ahora mismo. Solo echemos un vistazo rápido que sepas lo que está pasando. Acabo de tener un archivo
styles.css aquí y solo tiene un
montón de código diferente. Este es redundante. Pero tenemos un montón de código
diferente aquí solo para dar estilo a nuestro proyecto muy bien. Nuevamente, realmente no estamos
enfocados en los estilos de esta clase, pero es mucho mejor
tener un proyecto que tenga un estilo agradable
que uno feo. Así que tengo eso
ahí dentro y luego tengo imágenes aquí, productos aleatorios. Estas son
imágenes aleatorias de productos como se puede ver. Todos se ven visualmente similares, pero no hay relación
entre Coca-Cola Cero, y Aceite de Semilla de Cáñamo,
y Pasta de Curry Rojo. Un poco aleatorio, pero solo necesitábamos algunas
imágenes de marcador de posición para este proyecto. También voy a crear
una carpeta JavaScript. Comienza haciendo clic en
“Nueva carpeta”, “js”. Dentro de esta carpeta js, voy a crear un index.js. Lo que voy a hacer
aquí es porque
vamos a estar construyendo
un carrito de compras, voy a crear un
objeto en el objeto ventana. Será un
objeto global llamado cart, y luego voy a
abrir un objeto vacío, y sé que en
este objeto quiero tener una matriz de elementos, así que solo estoy inicializando
eso aquí mismo. Voy a golpear “Guardar” en eso, y este probablemente
será mi primer compromiso. Voy a traer aquí
una terminal, ejecutar git init, git add. y luego git commit
inicial. Claro eso, y entonces
lo que voy a hacer es que
trataré de comprometerme cada
tanto para que ustedes puedan ver
el progreso sucediendo y puedan referirse al
código si lo desean. Tenemos esta ****
DS Store aquí. Sólo voy a descartar
eso, en realidad no necesito eso. De vuelta a nuestro código aquí, demos nuestro primer paso
para crear este proyecto. En realidad, antes de que hagamos eso, hagamos clic en “Go Live”. Ahora verás que estamos ejecutando
nuestro archivo index.html. También necesitamos cargar
en esos estilos, por lo que probablemente debió haber hecho eso antes de
mi compromiso inicial. Pero aquí vamos, enlazamos rel="stylesheet”
y luego el camino a esa hoja de estilo
es css/styles.css. Ahora antes de construir
cualquier funcionalidad, solo
voy a
crear algo de HTML aquí, así que vamos a crear un div con
la clase de contenedor, cosas
bastante estándar, y luego h1 carrito de compras. Entonces lo que voy a hacer es un div con la clase
de productos a la venta, y luego dentro de aquí, lo que voy a hacer
es crear cuatro divs, así div veces 4. Vamos a dar “Guardar” en eso. Vamos a mirar por aquí, entonces se puede ver si hago clic en el click “Inspeccionar en él”
y ver productos a la venta. Tenemos todo el CSS
listo para ir para cuando
insertamos estos elementos de producto
en este div aquí mismo. Antes de hacer nada,
déjame darte una visión general de lo que estamos
tratando de crear aquí. Este será nuestro proyecto
terminado. Como puedes ver aquí, tenemos cuatro productos que
podemos añadir a nuestro carrito, y si hago click en el botón Agregar al carrito debajo de
cualquiera de estos productos, agregará ese artículo a
nuestro pequeño carrito aquí. Si vuelvo a hacer clic en ese botón, aumentará la cantidad,
si voy a hacer clic en el botón Agregar al carrito de otro
producto, agregará esa línea
a la tabla aquí, que es auto
actualizando el total. Piensa que todos estos
son alrededor de 10 dólares, por lo que es matemática bastante fácil, y también puedo actualizar la cantidad a través de estos selectores de
cantidades, y eso actualizará
los totales según corresponda. También puedo entrar aquí y
poner esto a 10 si quiero. Entonces puedo establecer mi propia cantidad
específica. La teoría detrás de esto
es si fuera un verdadero carrito de compras, podría hacer clic en un
botón y se
dirigiría a comprobar hacia fuera
con esa selección. Para nuestros fines, si
refrescamos la página, perderemos nuestro carrito. Podríamos escribir algún
código para persistir eso en almacenamiento local
o almacenamiento de sesión. Pero para los efectos
de este video, no
creo que realmente
necesitemos hacer eso,
eso podría ser una mejora
que usted haga en el futuro. Lo final que hace es, si está en uno y tratas de
reducir la cantidad, solo
quitará ese
artículo del carrito. Si no hay artículos en el carrito, toda
la mesa desaparecerá. Entonces eso es lo que estamos construyendo. Podría dejar esa pestaña
abierta a un costado ahí, volver aquí, y vamos a trabajar. En realidad una cosa más antes de que
empecemos en esto, quiero realmente dar un vistazo cómo vamos a romper
esto en componentes web. Aquí puedes ver que tenemos
cada uno de estos productos aquí y
existe la misma funcionalidad en todos ellos. Si hago clic en el botón Agregar
al carrito, agregará ese
producto en particular al carrito, por lo que cada uno de estos productos va a ser
su propio componente web. Entonces como pueden ver, si refresco aquí, haga clic en “Agregar al carrito” obtenemos
esta otra sección agregada aquí, que es nuestra lista de artículos del carrito, la tabla de artículos del carrito. Eso va a ser un
componente también. Entonces finalmente, dentro de ese componente de tabla de artículos de
carrito, tenemos otro
componente que es nuestro
selector de entrada de cantidad aquí. Así que cada vez que haga clic
más o menos, vamos a establecer una cantidad específica aquí, vamos a configurarla a cero. ver qué pasa, desaparece. Eso también va a ser
un componente. Empecemos con el componente
del producto. Vayamos aquí, y luego diríjase a
nuestro editor de código. En nuestra carpeta js, vamos a crear el archivo para ese componente. Voy a llamarlo product.js. Empecemos con la
calderilla. Voy a llamar a este elemento producto clase. Por supuesto, vamos a extender elemento
HTML como hemos visto a
lo largo de esta clase. Entonces antes de escribir
cualquier código dentro, solo
voy a
exportarlo de inmediato. Debido a que estamos usando
módulos ES con cada componente contenido en su propio archivo
JavaScript, voy a usar export default y luego simplemente escribir el nombre de
clase después de eso. Pulsa “Enter” en eso,
luego cambiando a mi archivo index.js, voy a poner mi
importación al inicio
del elemento file products, y luego derecho desde
la ruta a ese archivo, que ya estaban en
la carpeta JavaScript, por lo que va a ser.product.js. Entonces tenemos que poner aquí
un método definido,
obviamente, los elementos personalizados definen. Solo voy a llamar a ese producto-elementos como
el primer argumento, y luego traer esa clase de elemento de
producto. También tengo que importar ese archivo
index.js a HTML. No olvidemos eso.
Script src=” js/index.js " y luego sin olvidar ese
tipo atributo de módulo. Presione “Guardar” en eso, actualice por aquí, y vea si hay
algún
error de JavaScript que no haya. Perfecto. Regresemos la cabeza. En lugar de estos cuatro
divs lo que quiero hacer es hacer cuatro elementos de producto. Vamos a dar “Save” en eso
y nos dirigimos a aquí. Como de costumbre, voy a agregar el método constructor
y luego ejecutar super. Ahora tenemos que hacer algo
pensando en cómo queremos
construir nuestro componente
web personalizado aquí. Si miro el código
aquí vamos a traer en este componente web
cuatro veces diferentes. No sé si quiero
escribir mi HTML interno dentro de cada uno de
estos porque
va a ser bastante repetitivo. Lo que podría hacer es que podría
poner la estructura HTML dentro de la definición de
clase de componente web justo aquí. De esa manera es lo mismo para cada componente web
que es lo que
queremos y eso
mantendrá limpio nuestro código. Lo que voy a
hacer es que voy a escribir este HTML interno. Esta estructura se basa en el CSS que
ya he configurado. Se está aprovechando las
clases ya en el CSS. Voy a crear un div con la clase
de contenedor de imagen. Cierra eso y luego
por dentro voy a tomar la imagen con una imagen de
clase de producto. Entonces voy a poner en el SRC que en cuanto lleguemos aquí deberíamos empezar
a pensar a nosotros mismos, este tiene que ser
un valor dinámico. Si es un valor dinámico entonces realmente no
podemos establecer
algo explícitamente aquí porque entonces
la imagen del producto va a ser la misma
para cada producto. Obviamente, la estructura de cada elemento de producto
va a ser la misma pero el producto
va a cambiar, y por lo tanto la imagen del producto. Por lo tanto el título y el ID del producto
todos van a cambiar. Ahora llegaremos a cada uno
de esos a medida que venga. Pero para arrancarnos
lo que quiero hacer es crear un atributo personalizado al
menos para la imagen. De esa manera podemos pasar en la imagen en cada uno de
estos componentes web. Vimos esto antes en la
clase cuando miramos atributos
personalizados ahora
llegamos a usarlo en la práctica. Lo que voy a hacer
es poner en un
atributo de imagen y echemos un
vistazo dentro de nuestra carpeta aquí. Hacemos que el camino hacia la
imagen, image/coke-zero.jpg. Vamos a copiar eso a
aquí y aquí y luego
actualizaremos eso. El segundo
será el aceite de semillas de cúñame. El siguiente será
mágico-toque-cuerpo-crema y luego la final será pasta de grosella roja.
Golpea “Guardar” en eso. Entonces lo que podemos hacer es dirigirnos a nuestro componente web aquí. Podemos configurar la imagen
en los componentes web. Estamos configurando una
variable adjunta a este componente web
como lo hicimos antes, obtener atributo y
vamos a obtener el valor de ese atributo de
imagen. Entonces dado que tenemos ese valor podemos
entonces entrar aquí e insertarlo
aquí mismo en este SRC. Voy a golpear “Guardar” en eso, refrescar por aquí y
vamos a ver qué tenemos. Van a
consolarse, sin errores. Pero se puede ver que tampoco se está
encontrando. Sospecho que esto es
por algún error tonto. Sí, es un error tipográfico tonto. Debe ser elemento del producto
no elementos del producto. Simplemente pasa y
deshazte de esos S. Pulsa “Guardar” en eso y luego
si nos
refrescamos por aquí, en realidad ni siquiera tenemos que refrescarnos porque puedes
verlo funcionando para nosotros. Veamos si
todavía podemos ver las cosas. Sí. Vamos a poner esto
por el fondo y luego se puede ver que
tenemos nuestra alineación de las
cuatro imágenes de productos. Tenemos la misma estructura para cada elemento de producto que
almacenamos aquí pero estamos pasando por el valor
dinámico de donde está
la URL de la imagen y luego la estamos poniendo en
nuestra estructura de plantilla aquí. Pero por supuesto, como mencioné
antes la URL de la imagen no es el único
contenido dinámico que necesitamos
pasar a este elemento de producto. Necesitamos el título slash
el nombre del producto. Necesitamos su precio
y necesitamos su DNI. Vamos a crear algunos atributos
para eso también. Continuemos con el siguiente
en la jerarquía visual. Continuemos con el nombre. Voy a hacer exactamente el
mismo formato que he hecho aquí. Cree una variable llamada
this.name y luego obtenga el valor del nombre
del atributo. Obviamente, esto no ha
sido creado todavía. Voy a entrar aquí, voy a cerrar esto para
que podamos ver esto mejor, y luego voy a crear un atributo de nombre para
todos estos elementos de productos. Entonces éste va
a ser coca cero. Voy a poner entre
paréntesis, lata. Entonces aquí
aceite de semilla de cáñamo y luego aquí sólo
voy a
llamarlo crema corporal y luego aquí pasta de curry rojo. Golpea “Guardar” en eso. Vayamos por aquí y entonces realmente
necesitamos usar ese nombre en
algún lugar de nuestro código. Puedo bajar aquí
y luego puedo ir igual que lo hemos
hecho con la imagen, crear un h2 dentro de este h2. Puedo deslizarme en esto.name. Refrescante aquí ya
puedes ver el nombre de cada producto debajo de
la imagen del producto. hay un
poco de problemas CSS Aquíhay un
poco de problemas CSSy eso es porque no se supone que esté dentro del contenedor de imágenes.
Déjame arreglar eso. Se supone que está
fuera de este div. Golpeé “Guardar” en esa
actualización de aquí entonces ya puedes ver que ya no
tenemos ese tema. Dulce. Eso conforma
nuestra jerarquía visual. Pero lo otro que
tenemos que hacer es realmente almacenar algunos datos en
este elemento producto para cuando hacemos clic en “Agregar al carrito” porque
dependiendo de qué botón o qué elemento hacemos
clic en “Agregar al carrito” on va a tener
un valor diferente. La forma en que voy a
hacer esto es en lugar de agregarlo al HTML interno voy a crear un elemento y luego
anexarlo al DOM. El motivo por el que
voy a hacerlo de esta manera es para que pueda adjuntarle un oyente de eventos antes de
que lo añada al DOM. Lo que voy a hacer es crear
un elemento para el botón. Sólo va a ser botón y luego
por supuesto que tengo que
guardar eso en alguna parte, así que voy a guardar eso en el botón constante
llamado. Voy a configurar el HTML
interno del botón para agregar al carrito y luego voy a
agregar un oyente de eventos. En realidad, vamos a comentar
eso por ahora. Vuelve a ella en un segundo. Sólo voy a anexar
eso para agregar documento primero. Pulsa “Guardar” en eso, refresca
aquí y puedes ver tenemos nuestros
botones Agregar al carrito y su estilo, igual que en nuestro ejemplo por el CSS que
ya hemos llegado allí. Ahora para que esto funcione,
necesitamos poder saber cuál es el nombre y el id del producto que estamos
agregando al carrito? Porque esto
actualmente no está haciendo nada, y ahí es donde
vamos a pasar en el id Pero también necesitamos saber cuál es
el precio de cada producto, por lo que podemos añadir eso a
nuestra mesa de carrito también. Vamos a pasar
en id y precio. Vamos a crear atributos
para ellos también. Voy a empezar
dentro del componente, y digo this.id es igual a
this.getAttribute, no animaciones atributos, id, y luego this.price,
this.getAttribute price. Entonces voy a ir
a los elementos aquí. Agreguemos un id para cada uno. El primero
vamos a hacer 1,
2, 3, y 4. Sólo hay productos completos,
por lo que sólo necesitamos identificaciones simples. Entonces voy a
sumar el precio. Vamos a mantenerlo simple
y hacer que cada uno de ellos $10. Simplemente pasaremos estos como dígitos ahora y los
convertiremos
en números
enteros o flotadores más tarde. Ahora volviendo a
nuestro componente web, esta es la parte donde realmente
construimos en alguna funcionalidad y nos complicamos un
poco más. Como puedes ver aquí, tengo un
EventListener comentada. Lo que quiero hacer antes de
construir eso es crear el método que este
EventListener va a desencadenar. Fuera del constructor, vamos a crear nuestro propio
método llamado AddToCart. En AddToCart, lo que
vamos a hacer es construir un objeto con todos los atributos
que queremos
agregar a un objeto item cart. Voy a crear
un objeto const item y deberías ver a qué me
refiero con esto muy pronto. Por supuesto voy
a agregar una clave de id, y sólo voy a tomar el id que se almacena
en este componente web. Voy a cerrar esto
para que puedas ver más. Entonces voy a tomar el nombre y eso va a ser
igual al nombre tal y como se establece
en el componente web. Cantidad siempre va
a igualar a uno porque el botón Agregar al carrito sólo
va a agregar uno por defecto. Puedes añadir en un selector de
cantidad a este elemento más adelante si quisieras como mejora. Pero por ahora, en cualquier momento que haga clic en “Añadir al carrito” sólo
va a agregar uno. Voy a arreglar eso al número 1, y luego el precio va
a ser esto.precio. Echemos un vistazo. Cuando realmente ejecutamos esto, todo lo que voy
a hacer para empezar con sólo para verlo es ejecutar el log de consola, y luego ItemObject, el objeto que acabamos de crear. Aquí arriba en AddVentListener, obviamente
voy a
buscar el click “Evento”, y luego voy a ejecutar
este método addToCart, y luego voy a enlazar esto, que cuando estoy
aquí abajo en este método, cada vez que haga referencia a esto, voy a estar haciendo referencia al componente web,
no al evento. Golpea “Guardar” en eso,
refrescar por aquí. Vamos a abrir nuestra consola, y si hago click en “Añadir al
carrito” en el Aceite de Semilla de Cáñamo, se
puede ver que
envía a través de los datos. Podemos ver que el id del
producto es 2, el nombre es Aceite de Semilla de Cáñamo. Estamos agregando uno y el
precio de cada uno es de 10. Si lo hago en la Coca Cero Can, obtengo un poquito
de datos diferentes. Si lo hago en la
Crema Corporal y Pasta de Curry Rojo, se
puede ver que consigo un
objeto diferente cada vez. Eso es confirmar que
estamos enviando a través de
un objeto con toda la
información que necesitamos. Ahora lo que tenemos que hacer
es escribir un poco de lógica con el fin de
agregarlo a este array items
dentro de nuestro objeto carro. Vayamos por aquí y te
mostraré cómo podemos
acceder a ese objeto de carro. Porque está en
el objeto ventana, podemos escribir window.cart para echarle un
vistazo o simplemente
podemos escribir carro porque ya estamos en
el contexto de ventana. Como se puede ver, no importa de
qué manera lo hagamos, podemos ver que tenemos un objeto con una matriz de ítems
vacíos. Lo que queremos ver cuando
volvamos a emitir eso, después de añadir al carrito, es que tenemos un nuevo elemento en esa matriz de ítems.
Eso lo aclararé. Vamos a hacer eso ahora mismo. Voy a comentar
ese registro de consola, y lo que tenemos que hacer
en la mayoría de los casos es agregar ese objeto simplemente a la matriz de
ese elemento. Vamos a hacer
window.cart.items.push para agregar ese objeto item
a la matriz item, y luego vamos a poner en el objeto item como
argumento ahí. Vamos a dar “Guardar” en eso. Refresca por aquí. Si escribo en carro en este momento, se
puede ver que tenemos una matriz de
artículos que está vacía. Consigamos un poco
más específicos y digamos artículos del carrito específicamente. Tenemos una matriz vacía
que está clara de ver. Déjame hacer eso
una vez más. Tenemos el antes, entonces si hago clic en “Agregar
al carrito” y
escribimos en cart.items ahora, verás que tenemos un
objeto en nuestra matriz, y si miro dentro, es nuestro Aceite de Semilla de Cáñamo
con el cantidad de uno. Si hago click en “Añadir al carrito” en Body Cream y luego
voy cart.items, ya
deberías ver que
tenemos dos artículos en nuestra matriz con cada uno
de esos productos. Ahora tenemos un tema que no sé si
pensaste en esto o no, pero pronto descubrirás
que este es un tema. Si agrego otro
del mismo producto que
ya tenemos en nuestro carrito, digamos de nuevo Aceite de Semilla de Cáñamo, y luego me voy a
aquí y voy carrito.artículos, verás tenemos tres
artículos en el carrito, y tenemos Aceite de
Semilla de Cáñamo dos veces, pero con una cantidad cada uno. Queremos ver un elemento en
la matriz para Aceite de Semilla de Cáñamo, pero queremos que este
número sea dos. Necesitamos escribir un
poco de lógica extra para eso. Volvamos a aquí y
utilicemos el método find dentro de JavaScript para averiguar si el elemento ya
existe en la matriz. Voy a crear un artículo
constante en el carrito. Entonces vamos a
buscar window.cart.items, entonces vamos
a usar el método encontrar pasando por el ítem. Si el id del elemento es igual
al id del objeto del elemento, entonces hemos encontrado una coincidencia, y ese va
a ser el objeto. Antes de escribir algo más, vamos a hacer console.log
item_in_cart. Debería
pasar como indefinido o algún otro valor nulo si realmente
puede encontrar algo, pero si encuentra algo, en realidad
obtendremos
el objeto en sí. Refrescante por aquí. Hagamos clic en “Añadir al carrito” y
saldrá como indefinido. Pero si volvemos
a hacer clic en “Añadir al carrito”, verás que tenemos ese producto existente
ya en el carrito. Si vas cart.items, puedes ver que
tenemos el mismo artículo dos veces en el carrito.
Tenemos que arreglar esto. Lo que vamos a hacer
es ejecutar si item_in_cart, entonces todo lo que queremos hacer
es tomar ese artículo que
ya está en el carrito y simplemente aumentar su
cantidad en uno. Pero si no está en el carro, así que si sale
indefinido, por ejemplo, vamos a entonces ejecutar este código aquí abajo para empujar
ese artículo al carrito. Vamos a guardar eso y veamos si eso
soluciona nuestro problema aquí. Voy a añadir
en Aceite de Semilla de Cáñamo, voy a añadir en Crema Corporal. Echemos un vistazo a
nuestros artículos de carrito ahora. Tenemos un
Aceite de Semilla de Cáñamo y una Crema Corporal. Si vuelvo a añadir uno del
mismo producto, el Aceite de Semilla de Cáñamo y luego vamos a echar un vistazo a la carta.items, puedes ver solo tenemos
dos artículos en nuestra matriz ahora, y si hago click en ellos, tú puede ver haciendo clic en “Añadir al carrito”
en el Aceite de Semilla de Cáñamo, realidad no ha creado
un nuevo elemento en nuestra matriz, pero es simplemente aumentar la cantidad de
ese artículo existente, que es exactamente lo que queremos. Regresando aquí, esa es esencialmente toda la
funcionalidad que necesitamos, específicamente desde
el elemento producto. Sólo para resumir en este
punto antes de seguir adelante, hemos creado un
elemento de producto componente web. Hemos pasado en
cuatro parámetros. Dentro del propio componente web, tenemos una
estructura estándar que es común a todos los componentes web del
elemento del producto, y una funcionalidad común
de AddToCart, que podemos ver aquí mismo. Voy a quitar ese registro de consola porque todo esto está funcionando, y ahora se puede ver, pesar de que no tenemos carta.items visualmente
representados en la página todavía, podemos agregar elementos
a nuestro carro artículos array. El objeto carro aquí es
básicamente nuestro objeto estatal, y lo que
vamos a hacer es usar ese objeto carro para crear nuestra
tabla de artículos de carro en el siguiente video. Según lo prometido, voy a
cometer este código y descartaré. Probablemente debería haber puesto
eso en el get ignore. Unstage, entra aquí, descarta eso, y luego voy a comprometer nuestros
cambios a index.html, index.js, y luego, por supuesto, la creación de product.js. Voy a poner en escena todos esos cambios y agregaré el mensaje de confirmación, crearé elemento de producto componente
web. Barrido. Voy a pegar commit en eso, nuevo, descartar esos cambios. Voy a
romper esto en otro video. En el siguiente video, veremos el componente
de artículos del carrito.
11. Componentes web en la práctica, parte 2: Muy bien, chicos.
En el último video, configuramos un index.js, que tiene nuestros objetos cortados
con la matriz items, y aprendimos cómo podemos
poblar esa matriz de artículos a través de este elemento de producto que creamos en
el video anterior, y obviamente, eso tiene un componente visual
a ella también. Contamos con cada uno de estos productos elementos con
estos botones de añadir al carrito. Si hago clic en alguno de estos botones de
añadir al carrito, se actualizará nuestro cart.items
que tenemos aquí, pero eso no está realmente representado
visualmente en
la pantalla hasta el momento. Eso es lo que
haremos en este video. Vamos a crear
un nuevo componente llamado artículos de
carrito.
Hagámoslo ahora mismo. Vamos a entrar en nuestra carpeta JS, crear un nuevo archivo
llamado cart-items.js. Vamos a conseguir que nuestro código de
calderas de componentes vaya aquí. Artículos del carrito es lo que
voy a llamarlo, y vamos a extender
la clase de elemento HTML. Ahí vamos. Estoy tentado aquí solo a escribir elementos
personalizados definidos, pero recuerda que estamos
usando módulos ES. En lugar de eso,
lo que voy a hacer es exportar artículos del carrito, y luego voy a
hacer mi método definido aquí en el archivo de índice. Definir artículos de
carrito, artículos del carrito aquí. Lo y he aquí, el
código de Visual Studio sabe lo que estoy
tratando de importar y automáticamente agrega la
declaración de entrada aquí arriba. Pero si tu editor de código
no hace eso por cualquier razón, simplemente
puedes
escribir este código. Es el mismo formato que
el que teníamos antes. Dulce. Para conseguir este componente de artículos de carrito
en un documento, simplemente
voy a ir por
aquí dentro de nuestro contenedor, por lo que todo está contenido, voy a agregar en nuestro componente web personalizado
de artículos del carrito. Se va a
poner automáticamente en la etiqueta de cierre ahí. Ahora, si
refresco mi página por aquí
y no hay errores, puedo decir confiablemente que
tenemos eso en nuestro documento aquí. Si entro aquí, puedes ver que tenemos nuestro componente
web de artículos de carrito vacíos aquí. En realidad vamos a agregarle
algunas cosas. Cerremos productos
por el momento. Vamos a pasar a dentro de
nuestra definición de clase aquí. Obviamente, como siempre, vamos a necesitar
nuestro constructor, y dentro de nuestro constructor
vamos a poner en nuestro super método. Ahora, a diferencia de todos
los otros componentes que
hemos hecho en el pasado, realidad lo
voy a dejar ahí para el método
constructor. Voy a poner todo
nuestro renderizado dentro de otra
función llamada render. Ahora, ¿por qué haría eso? El motivo por el cual es
porque cuando agregamos un nuevo producto al carrito a
través de este elemento de producto, vamos a necesitar
renderizar por primera vez o volver a renderizar nuestra tabla de artículos del carrito. Va a ser útil
tener nuestra función de render aquí
para que con eso podamos volver a renderizar
siempre que lo necesitemos. Todo el código dentro de esta función de
render no se ejecutará cuando el
componente de artículos de carro esté incluido
en la página, como lo tenemos aquí, se
va a ejecutar realmente una vez que específicamente
le pedimos que se renderice. Esto va a ser mucho
código y no voy
a ir súper profundo
en todo ello, pero voy a explicar a medida que voy. Lo que voy a hacer es crear un punto de partida para este componente de artículos de
carrito. Voy a establecer el HTML interno a nada cuando ejecutemos render. Ahora, la intención de esto es cuando ejecutamos render
en el futuro, necesitamos borrar el
contenido que teníamos antes, lo contrario podríamos tener algo
del antiguo HTML interno dentro nuestro componente cuando tienen que volver
a renderizar el carrito. Entonces lo que voy
a hacer es construir un HTML usando document create, el segundo método que vimos
en el video anterior en tres formas de crear HTML
dentro de nuestro componente web. Olvidé poner aquí el
nombre de la variable. Voy a llamar a este
contenedor de mesa. Entonces voy a agregar la clase de contenedor de tabla a este contenedor de tabla div, y luego el segundo
elemento que voy a crear se llama tabla. Esta es nuestra tabla real de artículos de
carrito. ir a crear un elemento de tabla, asígnelo a la constante de la
tabla aquí. Entonces lo que vamos
a hacer es que vamos a recorrer todos los artículos
del carrito. Voy a correr un
cuatro cada uno en estos. Voy a tener
dos argumentos aquí, uno para el elemento en sí para que
sea el elemento en sí, y luego el segundo
será el índice. Déjame volver
a eso en un segundo antes de entrar en ese código profundo. Lo que voy a hacer
es table_container. Lo que quiero hacer es anexar nuestra tabla a ese contenedor de
tabla, y luego vamos a anexar contenedor de
la tabla
a nuestro componente web. Aquí está pasando un poco, pero ten cuidado conmigo. Lo que estamos haciendo es que básicamente
creamos si guardo y
luego refresco aquí. Ahora, en realidad no es
renderizado porque, recuerda, esto está en el método render, no
está en el constructor
como teníamos antes. Lo que vamos a
tener que hacer es ejecutar algún código para encontrar el componente web que
estamos buscando, que es cart-items, y luego ejecutar el método
render en eso. Si vuelvo aquí ahora, se
puede ver que dentro
de nuestros artículos de carro, vamos a tener un
div con la clase de contenedor de mesa y dentro
vamos a tener la mesa. Eso es lo que estamos haciendo aquí, estamos creando esta estructura
HTML. Ahora, lo que vamos a hacer es por cada ítem de la matriz, vamos a sumar. Voy a agarrar
el HTML interno, y voy a
usar el plus igual para anexar a nuestra cadena aquí, vamos a abrir esto, y voy a
agregar en una fila por cada artículo del carrito en
nuestro cart.items array. Veamos esto en
acción. Si pego
“Guardar” y voy por aquí, y volvamos a ejecutar
ese método render, volver a entrar aquí, encontrar nuestro
contenedor de mesa de artículos de carro y dentro de nuestra mesa, verás que no hay
filas en la tabla todavía, pero eso es porque
en realidad
no tenemos nada en nuestra matriz cart.items. Si voy cart.items, no
hay nada ahí dentro. Si tuviera que añadir, digamos, dos ítems a nuestra matriz, echemos un vistazo
ahora, cart.items. Definitivamente tenemos dos
artículos en nuestra matriz ahora. Si iba a ejecutar
render en artículos del carro, volver a
la cabeza a elementos aquí, ir dentro de nuestra mesa, se
puede ver que tenemos dos filas. Ahora, obviamente, necesitamos poblar
cada una de estas filas con los datos de cada uno de
esos artículos del carrito, y eso es lo que
vamos a hacer en este momento. De nuevo, va
a haber bastante código aquí pero ten cuidado conmigo. Necesitamos tres celdas de mesa. En la primera celda de tabla, vamos a poner
el nombre del artículo. Entonces por supuesto que tenemos acceso a cada ítem a medida que lo
recorremos, porque eso es lo que
hemos puesto aquí. Voy a decir nombre del artículo. Entonces aquí vamos
a tener una entrada de cantidad. Llegaremos a eso un
poco más tarde. En éste, vamos a tener $sign y luego vamos
a tener nuestro artículo dot precio. Arreglaremos esto en un segundo porque este tiene que
ser el precio de línea. Entonces si la cantidad
es mayor que una, entonces necesitamos actualizar esto. Entonces lo que voy a hacer
es sólo un poco de formateo. El primer td. Quiero que el texto
esté alineado a la izquierda, pero eso es por defecto, así que no
voy a
cambiar nada ahí. En el segundo,
voy a hacer que el texto se alinee al centro. Entonces el último
voy a establecer el texto alinear a la derecha. Ahora si pego “Guardar” en esto, creo que automáticamente se recarga
caliente de todos modos. Golpeé “Añadir al carrito” en
dos de estos botones. Entonces ejecuto la función render. Puedes ver aquí tenemos los
inicios de nuestra mesa. Tenemos el nombre del producto que está en el recorte y el precio. Pero por supuesto, si vuelvo a
golpear éste, sólo
tenemos dos
ítems en la matriz. No actualiza la
cantidad ni el precio de línea. Entonces antes de que realmente creamos
la cantidad seleccionada aquí, solo
puedo poner en
la cantidad del artículo. Mientras estamos aquí, vamos a arreglar este precio, el precio de línea. Llamemos a este precio de línea. Eso va a ser igual a asegurarnos de poner
esto dentro del bucle. El precio de línea va a
ser igual a los tiempos del
precio del punto del artículo por la cantidad
del artículo. Le pegaré a “Guardar” en eso. Refresca aquí,
agreguemos algunos artículos al carrito. Acabo de presionar “Añadir al
carrito” en aceite de semilla de cáñamo, luego en crema corporal, luego volver a aceite de
semilla de cáñamo de nuevo, por lo que deberíamos ver dos
artículos en nuestra matriz. Si voy aquí abajo, se puede ver que nuestra selección se
ha salvado. Si corremos render, podemos ver que está
apareciendo en nuestra mesa aquí abajo. Ahora claro, cada
vez que tenemos que ejecutar la
función render nosotros mismos, obviamente no
queremos hacer eso. No vamos a esperar que
el usuario entre en su consola y sepa
qué comando ejecutar. Así que vamos a configurar eso para que se ejecute en nuestro producto dot js. Después de sumar al carrito, así que aquí mismo
voy a añadir una línea. Literalmente podemos tomar
esta línea y colocarla ahí. Golpea” Guardar” en eso,
refresca por aquí. Cada vez que hacemos clic en
“Agregar al carrito”, volverá a renderizar el carrito. Esto me molesta un poco. Quiero almacenar este componente
web en sus propias variables así que voy a crear una variable para esto. Voy a subir
aquí y hacer este punto carrito artículos iguales y luego
tomar ese elemento del DOM. Esto me siento como si estuviera
un poco más limpio. Nuevamente, no hay
que hacerlo de esta manera, pero me gusta un
poco mejor. La siguiente parte que
voy a hacer antes pasar a codificar la entrada de cantidad es
crear el pie de página de tabla. Entonces si lo miro ahora, en realidad no
tenemos
el total y para eso vamos a crear
un pie de página de tabla. Sólo voy a
quitar eso ahí. Vamos a entrar en artículos de carrito dot
js. Ya estamos ahí. Entonces después de este código, lo que voy a hacer es crear un nuevo elemento llamado
documento pie de página crea elemento. Esto va a ser un div. Entonces también voy a tener que
averiguar el total del carrito. Entonces voy
a tener que usar un poco de un método complicado aquí, ventana dot cart dot items, y luego ejecutar el método
reduce en él para contabilizar todo. Por lo que el ítem total, si
esto te confunde, solo estudia
el método reducido, pero es una manera para nosotros de
sumar todos los valores
hasta crear un total. Lo que voy a hacer es porque los precios van a
pasar como cadenas, porque
los hemos puesto a través como una cadena en nuestro HTML aquí, sólo
tenemos que
pasarlos a enteros. Ahora, podríamos querer pasar
estos a flotadores si tuviéramos valores
decimales pero
para este proyecto, no
vamos a tener
ningún valor decimal. El monto más bajo va a ser uno y va
a subir en uno, así que nada va a ser
2.75 dólares ni nada de eso. Sólo vamos
a mantenerlo simple. Van a ser $10 o $20. En realidad, todo en
este proyecto va a ser $10 así que
lo estamos manteniendo muy sencillo. Pero para que lo
sepas, es posible que necesites cambiar esto. Pero para nuestros fines, todo va
a ser un entero, así que podemos hacer pars int. Déjame abrir esto
un poco más para ti. Entonces en el pars int, vamos a tomar el total add item dot price times by the
item dot quantity, que es por supuesto
el precio de línea, que calculamos
antes aquí arriba. En el segundo parámetro
vamos a poner a través de cero. Entonces lo que podemos hacer es establecer el HTML interno del pie de página en, pongamos aquí algún código
HTML. Vamos a poner en otra mesa, que se va a
alinear con la primera mesa. Va a darle a esto una
clase de pie de carro. Entonces vamos a
poner en una nueva fila. Entonces aquí, vamos a
poner en una celda, que sólo va a
tener la palabra total. Entonces vamos a poner en otra
celda para el total en sí. Voy a poner en el
estilo de texto, alinear. Se alinea con el precio
de línea por aquí. Entonces aquí podemos
poner nuestro valor dinámico. Entonces voy a poner en
un signo $ real primero, y luego $ firmar llaves rizadas
para poner en nuestro carrito total, que acabamos de calcular. Entonces aquí abajo, este punto
anexar pie de página hijo. Le pegaré a “Guardar” en eso y
luego nos refrescaremos por aquí. Si hago clic en “Agregar al carrito”, puedes ver que tenemos nuestro
total apareciendo aquí. Todavía no puedo reducir
las cantidades,
pero se puede ver que
al menos podemos añadir artículos al carrito. Nuestra
tabla de artículos de carrito se está actualizando, completa con el total para
que apenas alrededor nos cubra para los artículos del carrito, componentes de
mesa aquí. El último componente
va a ser el componente de entrada de cantidad, que
se va a anidar dentro del componente de elementos curt. Voy a
romper eso en su propio video, así que lo cubriremos
en el siguiente video. Entonces haremos nuestras modificaciones
finales para completar este proyecto. Los atraparé
en la siguiente.
12. Componentes web en la práctica, parte 3: En este tercero y ojalá
el video final esta serie en el que
estamos construyendo esta funcionalidad de
carrito de compras personalizado, voy a codificar hasta
la entrada de cantidad. Ahora una cosa que olvidé
hacer antes de cerrar el último video fue cometer
este código para ustedes, así que voy a hacer eso ahora. Simplemente descartaré
esta tienda DS de nuevo y solo echando un
vistazo a los cambios aquí. Siempre me gusta hacer
esto antes de comprometerme. Voy a escenificar todos esos y el mensaje commit
será crear ítems cortados.
Eso está comprometido. Descarta esa otra vez. Permítanme cerrar algunos de estos. Probablemente tenga que
abrirlas de nuevo, pero aquí está pasando
demasiado. Vamos a entrar en nuestra
carpeta js aquí y crear el componente de entrada de cantidad. Nuevamente, comenzando con
el código de calderas, ustedes deberían estar bastante
familiarizados con esto por ahora. La entrada de cantidad extiende elementos
HTML. Entonces lo vamos a
exportar de inmediato. Exportar valor predeterminado, entrada de cantidad, luego entrar en index.js. Voy a escribir mis
elementos personalizados define el método primero porque sé que va
a importarlo automáticamente. Llamemos a esto con el nombre
extendido cantidad-entrada. Magic VS Code ha puesto esa declaración de entrada ahí para nosotros para que pueda cerrar eso hacia abajo. Para este elemento en particular, lo que voy a
hacer es básicamente construirlo todo en
el constructor, como hemos visto
anteriormente en esta clase. preguntando de Aquí va a
haber bastante
código y si te estás dónde sacé
todas las ideas para esto, en realidad
tomé el tema del amanecer de Shopify como inspiración. Gran parte de este código
está inspirado en el mismo código dentro este componente dentro
del tema Shopify dawn. Si quieres hacer referencia a
esto en contra de eso, o preguntarte de dónde viene mi
proceso de pensamiento, puedes echar un
vistazo a ese tema. Como de costumbre, vamos a
poner
aquí el super método y luego lo que
voy a hacer es, vamos a escribir todo el HTML dentro del
cart-items.js aquí. Desplazarse aquí, todo lo que estamos
haciendo hasta ahora es solo escribir la cantidad del artículo tal y como está en esta
segunda columna aquí, pero por supuesto que no podemos
actualizarlo no hay entrada ahí. Vamos a reemplazar esto por
nuestro nuevo elemento personalizado, entrada de
cantidad para
la etiqueta de cierre. Voy a crear todo el HTML interno
dentro de las etiquetas mismas. No hicimos esto obviamente
por el elemento producto aquí, porque no queríamos tener que escribirlo cuatro veces
diferentes. Aquí, en el caso
de la entrada de cantidad, vamos a estar
escribiéndola cada vez que haya una
fila en la tabla, y cada fila va a
verse prácticamente igual. La única diferencia son los datos que vienen
a través del ítem. Podemos colocarlo aquí y
todavía va a ser código DRY. Aquí, sólo voy a
poner una clase de cantidad. Si me ves escribiendo
clases como esta, está relacionada con el CSS, así que no te
preocupes demasiado por las clases. Entonces vamos a crear
nuestros dos botones, nuestro botón menos,
nuestra propia entrada. Obviamente hay
muchas más cosas que hay que ir aquí, pero yo sólo voy a empezar con la estructura básica primero. Tenemos botón de entrada. Solo echemos un
vistazo a cómo se ve eso. Se puede ver la
estructura básica ahí, pero por supuesto que vamos a
necesitar poner el menos en entre esas etiquetas de botón y luego el plus in-between
estas etiquetas de botón. Para los atributos,
vamos a darle una clase, vamos a ponerla
en ambos botones aquí, clase de cantidad__button. Ir a cerrar esto
para que podamos ver mejor. Botón de tipo. Podemos poner eso en
ambos, teclear botón, y luego el nombre se va a basar de donde
sea menos o más. Me escaparé de eso y
luego pondré menos en el primero y luego
más en el segundo. Vamos a dar “Guardar” en eso y veamos cómo se ve eso hasta ahora. Parece que tenemos
un hit “Guardar” en eso. De todos modos no debería ser tan
relevante. Golpea “Añadir al carrito” y
como puedes ver ahora, tenemos nuestros estilos viniendo por el
plus y los menos. Necesitamos agregar algún código aquí
dentro de nuestras etiquetas de entrada aquí. Agreguemos algunos atributos. Queremos que el tipo sea
números para que la gente use carrito inserte texto
aquí aparte de dígitos. El valor va a ser
igual al item.quantity. El mínimo va a ser cero. No queremos valores
negativos. Vamos a darle un
ID y el ID va a empezar con cantidad y luego vamos a poner
un guión y luego usar el índice para diferenciar
cada una de las entradas. Entonces voy a poner aquí también un índice de
datos, que va a
ser lo mismo. Vamos a usar el
I como índice de datos. Le pegaré a “Guardar” en eso. Refresca aquí, haz clic en “Agregar al carrito” y
como puedes ver, esto parece que está funcionando. Lo único que
no está funcionando es no
podemos sumar y restar. Si cambio esto a dos, en realidad no va
a cambiar los dos. Si cambio esto a cero, en
realidad no
cambia el cero. Ahí es donde necesitamos
empezar a codificar realmente nuestra entrada de cantidad aquí dentro
de su definición de clase. Vamos a configurar algunas cosas
en nuestro constructor. Quiero primero traer la
entrada a su propia variable. Vamos a encontrar
eso dentro del DOM, dentro de nuestro componente web. Entonces lo que voy a hacer
es crear un onButtonClick, que va a ser la
devolución de llamada para nuestro EventListener. Voy a añadir en el evento como el único
parámetro. Voy a evitar
cualquier comportamiento predeterminado, y luego voy
a escribir alguna lógica aquí para que esto funcione. Lo primero que quiero hacer
es agarrar el valor anterior, el valor antes de cambiarlo, y eso sólo
va a ser igual al valor de entrada en el
momento de esta ejecución. This.input representa el elemento de
entrada en sí, y por supuesto podemos
agarrar el valor de cualquier entrada con solo
mirar su propiedad de valor de punto. Se va a agarrar el valor antes de
cambiarlo y luego vamos a echar un vistazo al evento y
mirar los objetivos del evento. El objetivo del evento en
esta instancia va
a ser el botón en el que hacemos clic. Entonces vamos a
mirar el nombre del objetivo
del evento, es decir, el botón y si es plus, solo
estamos usando aquí un operador
ternario, para aumentar para correr de
paso hacia arriba en la entrada. Step-up es solo un
método que nos
permite aumentar el valor
de esta entrada por uno. Si no es plus, lo
que significa que
definitivamente es menos porque solo
hay dos opciones, vamos a correr
paso abajo en su lugar. Ahora si pego “Guardar” en eso, ahora que tenemos aquí nuestro manejador de
eventos, en realidad
vamos a
adjuntar eso a todos los botones. Para esto porque hay
múltiples botones, vamos a usar un
QuerySelectorAll para cada botón, que está en los dos y
al final pero aún
necesitamos usar QuerySelectorAll. Eso
nos va a dar una matriz y luego necesitamos hacer un bucle a través de ellos. Para cada botón, vamos a agregar un EventListener de click. Si se hace clic en el botón, entonces vamos a ejecutar ese manejador de eventos al pulsar
el botón. Al igual que antes,
vamos a enlazar esto para
que esto represente el
componente web y no el evento. Quita
ahí ese punto y coma y póngalo ahí. Si pego “Guardar ahora” y
refresco por aquí, haga clic en “Agregar al carrito”, puedo conseguir que esto dé
un paso arriba y abajo, pero ¿qué no está pasando? En realidad, si presiono
menos, va a bajar. Eso no es muy útil, ¿verdad? Creo que eso probablemente esté
relacionado con este error tipográfico aquí. Esto no es una comparación, esto es una tarea, así que permítanme hacer de eso
una asignación adecuada. Volvamos por aquí, haga clic en “Agregar al carrito”. Ahora, si presiono,
debería funcionar. Ahora la cosa es con esto es, el valor dentro de esta entrada va
subiendo y bajando con
estas pulsaciones de botón, lo cual es bueno, pero
en realidad no está cambiando el valor en
nuestros datos estructura. Digamos que pongo
esto hasta siete, y luego vamos en realidad ir a nuestra matriz de artículos del carro
y echar un vistazo en el interior, se
puede ver que la
cantidad sigue siendo una. Podemos aumentar la cantidad
presionando aquí el añadir al carrito y como se puede ver, se actualiza a dos ahora. Entonces si entro en artículos del carrito, puedo ir aquí y
es la cantidad 2, pero poner esto arriba y abajo no
cambia realmente nada. Vamos a arreglar eso ahora mismo. La forma en que voy a arreglar eso
es mediante el uso de un evento personalizado. Ahora, ¿por qué voy a
usar aquí un evento personalizado? Bueno, quiero desencadenar un evento de
cambio en la cantidad. Lo que voy a hacer
es que voy a
pasar por la línea del artículo que quiero cambiar y su
nueva cantidad a un método, y luego ese método
va a actualizar cart.items. Ahora podemos poner este método
dentro de entrada de cantidad, pero creo que
tiene más sentido ponerlo en cart-items porque literalmente está
actualizando cart.items, el objeto con el que se relaciona este
componente. Voy a ponerlo
aquí antes de render. Qué va a hacer este método, lo voy a llamar
update quantity. Se va a llevar un
índice que se va a relacionar con la línea de ítem aquí. Como puedes ver aquí, estamos bicicleta a través de una
matriz y estamos almacenando en la cantidad seleccionar qué número
en la matriz es. Puedo utilizar eso para
averiguar el número de línea. Entonces el segundo parámetro
va a ser el nuevo valor, que solo voy a llamar
valor como parámetro. Entonces cuando esto se ejecute con
esos dos parámetros, lo que voy a
hacer es entonces
buscar el ítem a través de su índice, y luego simplemente tomar
la cantidad de ese artículo y luego cambiarlo a sea cual sea
el valor que pasemos. Entonces cuando eso se actualice, lo que vamos a hacer es
volver a renderizar la tabla de artículos del carrito, porque obviamente necesitamos
volver a renderizar el precio de línea y
necesitamos volver a renderizar el total cuando estemos haciendo estas actualizaciones, por lo que es mejor solo
volver a renderizar toda la mesa. Voy a golpear “Guardar” en esto, y entonces lo que
voy a hacer es hacer referencia a artículos del carrito. Como vimos antes con el producto, cuando hacemos referencia a artículos del carrito, lo puse en su
propia variable primero antes de ejecutar el método
aleatorio en ella. Porque vamos a estar
ejecutando un método en esto, quiero hacer algo similar, configurar esto en el constructor, así que voy a
poner esto aquí arriba. Entonces cuando nos ejecutemos
en el botón click, obviamente
vamos a estar
cambiando el valor de la cantidad. Ahora porque hemos asignado ese componente web
a esta variable aquí, puedo ir this.cart items y ejecutar el método en esos componentes web,
por lo
que puedo hacer actualizar cantidad, y para esto sólo hay que
averiguar cuál es el índice. Voy a ir a este índice de conjunto de datos de
entrada, por lo que eso me va a permitir
acceder a este justo
aquí, índice de datos. Eso está disponible en
la matriz de conjuntos de datos. Voy a agarrar ese índice. Entonces como segundo argumento, voy a poner
esto.input.value. Le pegaré a “Guardar” en eso. Ahora vamos a refrescarnos por aquí. Haga clic en “Agregar al carrito”. Ahora como se puede ver, medida que disminuyo y aumente esto, va a volver a renderizar toda
la tabla de artículos del carrito y cambiar el total
y el precio de línea. Ahora falta una
cosa más aquí, y eso es si
cambio esto a dos, no
va a
cambiar nada. Si vuelvo a esto,
lo va a cambiar, pero si pongo en un valor
específico, no
va a cambiar eso. Permítanme refactorizar este
código un poco más. Lo que quiero hacer
aquí es que quiero
crear un evento personalizado. Ahora recuerda cuando
hablamos de eventos personalizados antes, realmente no tenía sentido
porque solo estábamos vinculando un click y transformando eso
en otro evento personalizado. Pero esta vez tenemos dos formas de cambiar
el valor de entrada, es decir, la cantidad en este caso. Podemos establecer un valor de
cantidad específico, o podemos usar botones más y
menos aquí. Lo que quiero hacer
es combinar
ambos eventos en su propio evento, que voy a
llamar evento de cambio. Eso tiene sentido.
Veámoslo en acción. En primer lugar, voy a
crear este evento personalizado. Voy a ir esto.changed
evento va a ser, como vimos anteriormente con la
creación de eventos personalizados, creamos un nuevo evento,
le damos un nombre, y luego esta vez quiero agregar un objeto JavaScript
para burbujeante. Quiero poner burbujas a verdad. Lo que esto va a hacer
es que se va a registrar un evento de cambio en el componente
web de padres también, porque quiero que
se registre aquí. Entonces aquí voy a
crear un oyente de eventos para el evento de cambio en estos componentes web en
particular. Voy a poner en cambio aquí, crear una función aquí. Voy a agarrar la entrada. Va a ser el evento de
cambio aquí. Entonces lo que voy
a hacer es que voy
a poner aquí la cantidad de actualización. En lugar de tener que
ejecutar este método cuando
ejecutamos el botón click
event handler, y luego también el
manejador de eventos para cuando
cambiamos el elemento explícitamente, como lo hicimos antes, como esto, voy a
despachar este evento de cambio tanto
en el botón click
como en ese cambio de entrada. Déjame apenas escribir aquí esto, y voy a cavar
en la entrada porque necesitamos usar algunos de
sus atributos allí. Entonces voy a despachar
este evento personalizado, por lo que este evento de cambio. Entonces porque estamos mirando la entrada específica,
en lugar de no tener nada aquí lo que puedo hacer es
pasar por el evento, y luego en lugar de
mirar esta entrada, puedo crear una
referencia a la aquí basada en el objetivo actual del
evento. Lo siento, se me olvidó poner ahí
la asignación. Entonces podemos quitar este
punto de cada uno de estos. Vamos a dar “Guardar” en eso y
veamos si eso funciona. Voy a abrir mi
consola por si acaso haya errores. Añadir al carrito. Pon esto, baja esto. No está funcionando
porque estamos comprobando los eventos en el
componente web no en la entrada. Lo que voy a hacer es solo agregar un parámetro extra aquí
con un objeto JavaScript, y voy a poner
burbujas a true. De esa manera, el
evento de cambio va a
burbujear hasta el propio componente
de entrada de cantidad. Vamos a golpear “Guardar” en eso, refrescarnos por aquí, y veamos si esto funciona ahora. No se pueden establecer propiedades de la
cantidad de configuración indefinida, vamos a echar un vistazo. Echemos un vistazo a
lo que está pasando por aquí, entrada de registro de consola. Echemos un vistazo.
Eso es pasar por el propio
componente web. Eso debe ser porque
estamos burbujeando hasta el componente web que está
desencadenando el cambio y
luego el objetivo actual del evento en esa instancia se convierte en
el
propio componente web no en la entrada. Podemos arreglarlo con solo usar nuestra consulta seleccionada para
entrar y seleccionar esa entrada. Vamos a golpear “Guardar” en
eso, refrescar por aquí, golpear “Añadir al carrito”, y luego tenemos el mismo
resultado que teníamos antes. Esto es realmente actualizar nuestras cantidades y
actualizar nuestro carrito también. Como se puede ver, esto no
está funcionando. Permítanme simplemente cambiar esto a
dos y luego golpear “Tab”. Como se puede ver, eso es
cambiarlo al valor explícito. Como se puede ver, porque el cambio ya es
un evento sobre ese insumo, también
estamos aprovechando el evento existente que se
dispararía cuando
lo cambiemos explícitamente. Básicamente estamos
agregando nuestro botón click en el evento de cambio. Esto es algo que
sucede automáticamente, ni siquiera
tenemos que
registrar un evento de cambio cuando cambiamos este
valor explícitamente, esto simplemente sucede automáticamente. Este es un buen ejemplo
de cómo podemos etiquetar en un evento personalizado en
algo que ya existe. Ahora sólo para limpiar
esto, tenemos este valor anterior aquí. Se supone que si hacemos clic en un botón
estamos cambiando un valor, pero sólo para estar seguro voy a añadir aquí una declaración if. Sólo vamos a comprobar
si el valor anterior
no es igual al nuevo valor. Si guardo, refresco, debemos obtener el mismo
resultado que hacemos. Eso es sólo un cheque extra. Eso es básicamente todo chicos. Tenemos nuestros tres componentes
web aquí. Tenemos nuestro elemento producto, y si hago clic en “Agregar al
carrito” en cualquiera de estos, va a interactuar con nuestro componente de artículos de
carrito. Puedo utilizar estos insumos de cantidad para cambiar los precios aquí. En realidad una cosa que
no hicimos es si golpea cero queremos quitar eso, y si el total hit cero queremos quitar por completo
la mesa. Pensé que habíamos terminado pero
sólo nos queda una
cosa más por hacer, es por eso que siempre debes jugar con tus
proyectos y ver. Vamos a entrar en cartitems.js, y vamos a escribir en
algún código extra aquí. Voy a desplazarse hacia
abajo hasta el fondo. Lo primero que
voy a hacer es si el total del carrito es cero, bueno, en realidad voy
a hacer lo inverso. Si el total del carrito no es cero, entonces vamos a
renderizar el pie de página. Pero si el total del carrito es cero, entonces este código
no se ejecutará en absoluto, lo que significa que no
tendremos un pie de carro cuando se ejecute esta
función render. Ahorraré en eso.
Entonces lo que también voy a hacer es pondré un cheque
similar aquí arriba. Justo después del precio de línea aquí, no
agregaré la línea
a la tabla a menos que la cantidad del artículo sea
mayor que cero. Si no es cero, entonces vamos a ejecutar este código, así que agarra eso, y ponlo aquí. Golpea “Guardar” en eso. Ahora cuando agregamos algo al carrito, aumentar
su cantidad, pero luego volver a cero, eso eliminará eso. Digamos que tenemos
varios aquí y
quitamos todos uno de
ellos del carro, entonces toda la mesa del carro
no desaparece, es sólo esa línea. Podemos sumar todos ellos, quitar algunos de ellos,
aumentar la cantidad. Si esta fuera una app en pleno
funcionamiento con
funcionalidades de checkout como reales habilitadas, podríamos tener
aquí un botón que envíe esa matriz de carrito a
una página de checkout, y luego el usuario
podría para completar ese orden. Eso concluye este
pequeño proyecto de clase. Permítanme simplemente comprometer este
código antes de que me olvide. Nuevamente, descartando la Tienda DS. Echemos un vistazo rápido
a lo que cambiamos aquí. Todo se ve bien. Si detectas algún error
con cualquiera de esto, solo avísame. Comentarios a continuación pero voy a
escenificar todos esos y luego completar el proyecto
con entrada de cantidad. Descartaré esta otra vez. Eso es más o menos chicos. Tendré este código
en GitHub para ti. Simplemente búscalo
en mi página de GitHub, que es
github.com/christopherdodd. Déjame deshacerme de esto.
Consulta mis repositorios, mira si puedes encontrarlo ahí dentro. Cualquier pregunta. Déjalos
en los comentarios a continuación. Espero que hayas disfrutado de esta
práctica aplicación de usar Componentes Web. Ojalá en esta clase, pareciendo que hemos empezado con la teoría y hemos
entrado en lo práctico, puede empezar a solidificar lo que hace
Web Components y
por qué es importante. Te veré en el siguiente video donde
concluiremos la clase, y
te hablaré sobre cómo puedes extender este proyecto de clase
aún más si quieres. Gracias por verlo, te
veré en el próximo video.
13. Conclusión: Esto concluye nuestra clase
sobre componentes web. Para tu proyecto de clase, te
animo a crear tu propio componente
web en pleno funcionamiento. Para inspirarte,
puedes tomar lo que hemos hecho hasta ahora en esta clase con el ejemplo de e-commerce y agregar funcionalidades
adicionales como filtrado de
productos o
la selección de varianza. Como siempre, si tienes alguna
pregunta o inquietud, deja un comentario en el cuadro de
discusión a continuación, y haré todo lo posible para
apuntarte en la dirección correcta. Gracias como siempre por ver
y espero
volver a verte en algunos de
mis otros cursos.