Web Component 技术(笔记)

文章目录

      • 1. 概念
      • 2. 属性及方法
        • 2.1 添加方式
        • 2.2 生命周期
        • 2.3 CSS 伪类
        • 2.4 HTML template
      • 3. 示例
        • 3.1 自主定制元素
        • 3.2 自定义内置元素(扩展内置元素)

1. 概念

  • Web Component 是一套不同的技术,可以使用原生 js 的方式去定制不同的组件
  • 组件内部可以使用 shadow DOM 模式,与外界样式隔离
  • 组件内部也存在生命周期,感觉和 React 的类式组件很相似,也是组件继承,继承后还具有原来元素的特征

2. 属性及方法

2.1 添加方式

  • customElements:返回 CustomElementRegistry 对象引用 CustomElementRegistry.prototype === customElements.__proto__
  • customElements.define(name, constructor, options);
    • name:自定义组件名称
    • constructor:构造的组件类
    • options[可选]:目前只有一个属性,extends:继承已经创建的元素/内置元素

2.2 生命周期

  • connectedCallback:当自定义元素第一次被连接到文档 DOM 时被调用。
  • disconnectedCallback:当自定义元素与文档 DOM 断开连接时被调用。
  • adoptedCallback:当自定义元素被移动到新文档时被调用。
  • attributeChangedCallback:当自定义元素的一个属性被增加、移除或更改时被调用。

2.3 CSS 伪类

  • 与自定义元素特别相关的伪类,这些我都没用过,直接从 MDN 上拷贝下来的,感兴趣的可以去看一下
  • :defined:匹配任何已定义的元素,包括内置元素和使用 CustomElementRegistry.define() 定义的自定义元素。
  • :host:选择 shadow DOM 的 shadow host,内容是它内部使用的 CSS(containing the CSS it is used inside)。
  • :host():选择 shadow DOM 的 shadow host,内容是它内部使用的 CSS(这样您可以从 shadow DOM 内部选择自定义元素)— 但只匹配给定方法的选择器的 shadow host 元素。
  • :host-context():选择 shadow DOM 的 shadow host,内容是它内部使用的 CSS(这样您可以从 shadow DOM 内部选择自定义元素)— 但只匹配给定方法的选择器匹配元素的子 shadow host 元素。

2.4 HTML template

  • 不会在文档初始化时渲染。但是可以在运行时使用 JavaScript 显示,可用于添加到自定义组件中(下面示例中可以看到)

3. 示例

3.1 自主定制元素

<div>hello WebComponentdiv>
<my-box>my-box>

<template id="my-box-tem">
  <div>我是一个自定义组件,我的样式会被隔离div>
template>

<script>
// 当继承任意 HTML 元素时,该元素可以当做组件使用
class myBox extends HTMLElement {
  constructor() {
    // this指向自定义组件
    super();
    // 影子模式,与主文档分开呈现,保持元素的私有功能
    const shadowRoot = this.attachShadow({ mode: "open" });

    let box = document.querySelector("#my-box-tem");
    // content:template 的属性,返回模板内容
    let templateContent = box.content;

    shadowRoot.appendChild(templateContent);

	// 也可以直接在 template 中使用 style 标签
    let style = document.createElement("style");
    style.textContent = `
      div {
        background-color: red;
        color: white;
        font-size: 24px;
          }
      `;

    shadowRoot.appendChild(style);
  }
  // 在元素被添加到文档之后调用,会调用多次
  connectedCallback() {
    // console.log("我被添加了");
  }

  // 在元素被移除文档之后调用,会调用多次
  disconnectedCallback() {
    // console.log("我被移除了");
  }

  static get observedAttributes() {
    return ["test"];
  }

  // 在 observedAttributes 数组中的值,可以监听标签上的属性,当对应的属性值发生改变时调用
  // 在组件标签上设置对应属性时会调用一次
  attributeChangedCallback(name, oldValue, newValue) {
    console.log(name, oldValue, newValue);
  }

  // 在元素被移动到新的文档时调用,比如 document.adoptNode
  adoptedCallback() {
    console.log(11);
  }
}

customElements.define("my-box", myBox);
script>

3.2 自定义内置元素(扩展内置元素)

<button is="my-button">button>

<script>
// 当继承指定 HTML 元素时,该元素需要继承使用(is="自定义元素名")
class myButton extends HTMLButtonElement { }

customElements.define("my-button", myButton, { extends: "button" });
script>

你可能感兴趣的:(JS,前端,javascript,WebComponent)