Web Components

Intro and in-practice

VB is a js developer at U-Next, and is enthusiastic about current and emerging web-dev ecosystem

🙋

@vaibhav_kumar

@vb86596

🔖

Agenda

  • Web components

    • 4 Basic apis

    • Code
       

  • Stencil JS

    • Intro

    • Code

Component-based web development

  • Encapsulated

    • Separation of concerns
    • Enables abstraction

  • Manage HTML-hell

  • Composable

  • Re-usable, ...

Why ❤️ Components?

Framework agnostic components?

Migrate components from one library/framework to another?

Component-level styles encapsulation?

 Web components api

Shadow dom

Custom elements

<my-component></my-component>

create new or extend existing HTML/custom-elements

scoped HTML and Styles aka component-level encapsulation 

HTML templates

enables to write HTML fragments not to be rendered (used to compose custom-elements)

<!DOCTYPE html>
<html>
  <body>
    <template id="fancy-af-button-template">
      <style></style>
      <button><slot /></button>
    </template>

    <fancy-af-button>
      <span>I'm fancy!</span>
    </fancy-af-button>
  </body>
</html>

customElements.define(
  "fancy-af-button",
  class extends HTMLElement {
    constructor() {
      super(); // always call super() first in the constructor.
      
      // reading custom-element's template
      const template = document.getElementById("fancy-af-button-template");
      const templateContent = template.content;

      // creates a shadow root
      const shadow = this.attachShadow({ mode: "open" });
      // attaching template to shadow-root
      shadow.appendChild(templateContent.cloneNode(true));
    }
  }
);

Dev. Exp.? Too much Boiler-plate?
Type-safety?  Reactive data-binding? 

Stencil is a compiler that generates Web Component, developed by
Ionic Framework Team

  • Virtual DOM

  • Async rendering (inspired by React Fiber)

  • Reactive data-binding (props/state)

  • JSX

  • TypeScript

  • Prerendering support

import { Component, Prop, h, Listen, State } from "@stencil/core";

@Component({
  tag: "fancy-af-button",
  styleUrl: "fancy-af-button.css"
  shadow: true
})
export class FancyAFButton {
  @State() clickedCount: number = 0;

  @Prop() title: string;

  @Listen("click", { capture: true })
  handleClick() {
    this.clickedCount += 1;
  }
  render() {
    return (
      <button>
        <span>{this.title}</span>
        <span> {this.clickedCount}</span>
      </button>
    );
  }
}

👋

Web-Components-webhack-2019-12-17

By Vaibhav Kumar

Web-Components-webhack-2019-12-17

Web Components: Intro and in practice

  • 373