Web Components使用分享

267 阅读4分钟

Web Components

三个主要组成部分:

  • Custom Elements(自定义元素)
  • Shadow DOM(影子DOM)
  • HTML Templates(HTML模板)

与Vue自定义组件的区别

image.png

Custom Elements

允许开发者创建新的 HTML 元素,并且可以定义它的行为和样式

image.png

创建自定义元素

class MyButton extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = `
      <style>
        button {
          background-color: #4CAF50;
          border: none;
          color: white;
          text-align: center;
          text-decoration: none;
          display: inline-block;
          font-size: 16px;
          margin: 4px 2px;
          cursor: pointer;
          padding: 10px 24px;
          border-radius: 4px;
        }
      </style>
      <button>Click Me!</button>
    `;
  }
}
customElements.define('my-button', MyButton);

image.png

生命周期回调方法

Custom Elements 也有一组生命周期回调方法,这些方法在元素的不同生命周期阶段被调用。这些生命周期方法允许你在元素的创建、插入文档、更新和删除等时刻执行操作。

image.png 以下是自定义元素的一些主要生命周期回调方法

constructor() : 构造函数,在创建元素实例时调用。适用于执行初始化操作,例如设置初始属性、添加事件监听器或创建 Shadow DOM。

connectedCallback() : 当自定义元素被插入到上下文时调用。适用于元素被插入到 DOM 时执行的操作,例如获取数据、渲染内容或启动定时器。

disconnectedCallback() : 当自定义元素从文档中移除时调用。适用于元素从 DOM 中移除时执行的操作,例如移除事件监听器或停止定时器。

attributeChangedCallback(attributeName, oldValue, newValue) : 当自定义元素的属性被添加、移除或更改时调用。要使用这个回调,你需要在类中定义一个静态的 observedAttributes 属性,列出你想要监听的属性。

  constructor() {
    super();
    // 初始化操作,例如创建 Shadow DOM
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = '<p>这是一个自定义元素</p>';
  }
  connectedCallback() {
    // 元素被插入到 DOM 时执行的操作
    console.log('Custom element connected to the DOM');
  }
  disconnectedCallback() {
    // 元素从 DOM 中移除时执行的操作
    console.log('Custom element disconnected from the DOM');
  }
  attributeChangedCallback(name, oldValue, newValue) {
    // 监听的属性发生变化时执行的操作
    console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`);
  }
  static get observedAttributes() {
    // 返回一个数组,包含需要监听的属性
    return ['my-attribute'];
  }
}
customElements.define('my-custom-element', MyCustomElement);
<my-custom-element my-attribute="value"></my-custom-element>

image.png

在一个组件中,插槽将会照常使用 <slot/> 渲染。然而,当使用最终的元素时,它只接受原生插槽的语法:

  • 不支持作用域插槽
  • 当传递具名插槽时,应使用 slot attribute 而不是 v-slot 指令

Shadow DOM

允许将一个独立的DOM树附加到某个元素上,这个DOM树与主文档DOM分开呈现,从而实现了元素内部结构和样式的封装。

创建流程

Shadow DOM 是一种在一个 DOM 节点内部创建独立的、封装的 DOM 子树。 这使得一个元素定义独立的 UI 结构和样式,而不会影响到页面上的其他部分。 隔离性:内部的 CSS 样式不会泄漏到外部 DOM

image.png

隔离性

shadow dom是游离在 DOM 树之外的节点树,但是它是基于普通 DOM 元素(非 document)创建的,并且创建后的 Shadow-dom 节点可以从界面上直观的看到。最重要的一点是Shadow-dom 具有良好的密封性。

image.png image.png image.png

自定义元素外的 wx_name并没有应用颜色样式效果,因为整个 shadowRoot 对象和文档对象完全隔离的

mode

mode: 'open':允许外部通过宿主元素的shadowRoot属性,通过 Element.shadowRoot 属性访问Shadow DOM。 mode: 'closed':禁止外部访问Shadow DOM,增强了封装性。 image.png

image.png

image.png

image.png

当一个元素使用 Shadow DOM 创建时,它会包含一个 Shadow Root,这是一个独立的 DOM 子树,与文档中的其他部分相互隔离,可以在其中定义和控制样式和行为。

HTML Templates(HTML模板)

HTML Templates 是一种用于定义可复用的 HTML 结构的技术。模板中的内容不会立即渲染到页面上,而是可以在需要时通过 JavaScript 动态插入到文档中

基本用法

使用 <template> 标签定义模板。

  <div>
    <h1>Hello, Template!</h1>
    <p>This is a reusable template.</p>
  </div>
</template>

通过 JavaScript 将模板内容插入到文档中。

const clone = template.content.cloneNode(true);
document.body.appendChild(clone);

WebComponents例子

举个例子:创建一个自定义元素,然后将其挂载到真实 DOM 或者 shadow DOM 上

image.png

image.png

image.png

extends

options:【可选】控制元素如何定义,只支持一个选项 extends,用于指明定义的元素继承自何种类型元素。

(例如:{ extends: 'p’ }) 这里 extends 指明的元素是 HTMLParagraphElement,在调用 define 方法的时候 extends 必须指明为 p,同时组件也只能用在 p 元素上,方式上有别于一般的自定义元素 image.png