Web Components

Web Components是一系列技术的组成。旨在解决页面代码复用的问题。

主要由三项技术组成:

  • Custom Elements
  • Shadow DOM
  • HTML template & slot

Custom ELements - 自定义元素

自定义元素提供了定义元素行为和注册的接口。

CustomElementRegistry

通过 CustomElementRegistry 实例的 define() 方法定义 自定义元素。window上天然的提供了一个实例 - customElements

自定义元素分为两种。

Autonomous custom elements - 独立的元素

class CustomElement extends HTMLElement {
  constructor() {
    super()
    const div = document.createElement('div')
    div.textContent = 'This is a custom element.'
    console.log(this)
    this.appendChild(div)
  }
}

customElements.define('custom-element', CustomElement)
<custom-element></custom-element>

如示例展示的一般, 独立的元素通过customElements.define注册后具体的类之后即可直接使用**<custom-element>**。

Customized built-in elements - 定制的内置元素

class LogButton extends HTMLButtonElement {
  constructor() {
    super()
    this.addEventListener('click', () => {
      const log = document.createElement('div')
      log.textContent = 'log:' + new Date()
      document.body.appendChild(log)
    })
  }
}

customElements.define('log-button', LogButton, { extends: 'button' })
<button is="log-button">print</button>

定制的内置元素在使用define方法时会额外多一个选项,同时实现的类是继承自扩展的元素类,而不是基本的HTMLElement。

在使用方法上,则是在原生元素上使用is属性来指定使用哪个定制的内置元素。

Shadow DOM - 影子DOM

在上文的示例中, 所有的DOM都是直白的展开在自定义元素内。也就是在主文档上,而组件化有一个很大的特性就是具有私有化。

Shadow DOM 就可以用来实现这一目的。

class CustomElement extends HTMLElement {
  constructor() {
    super()
    const shadowRoot = this.attachShadow({mode: 'open'})
    const div = document.createElement('div')
    div.textContent = 'This is a custom element.'
    console.log(this)
    this.appendChild(div)
  }
}

customElements.define('custom-element', CustomElement)

通过 attachShadow() 方法来获取当前自定义元素的 shadow dom root元素, 当使用了ShadowDOM后,之前填充在<custom-element>的内容就无法再显示出来,这个时候需要去填充Shadow DOM的内容。

而Shadow DOM可以有自己的style节点。所有它可以拥有自己独立的样式与节点。

HTML template & Slot

无论是自定义元素还是影子DOM都是一组JS接口,它们描述 UI(文档)的能力很差。

<template>

template标签的元素不会呈现在文档上,它拥有自己独立的document fragment节点。

这样就可以提前在html上提前描述好ui,然后通过复制template的节点到自定义元素中进行呈现。

<slot>

slot 是一个占位符,有了slot, Web Components更加灵活。例如一个展示文档的组件, 在自定义元素中留下了title,content等<slot>占位符。

在使用组建的时候 只需要使用slot包裹对应的元素就可以让它们填充占位符的内容。

优势

  • 原生支持,无依赖,简单易上手
  • 非侵入式,具有良好的私有性

劣势

  • 描述ui的能力不强。
  • API 相对成熟的框架 是低级和简单的。 对于逻辑和ui处理更加复杂。
  • 各个浏览器兼容性不同

使用场景

  • 组件库
  • 跨端