2023年了该了解下WebComponent使用教程

正文

WebComponent 是官方定义的自定义组件实现方式,它可以让开发者不依赖任何第三方框架(如Vue,React)来实现自定义页面组件;达到组件复用效果

一个简单例子,让页面显示 hello world:

1
2
3
4
5
6
7
8
class MyText extends HTMLElement {
  constructor() {
    super();
    this.append("hello world");
  }
}
window.customElements.define("my-text", MyText);

三项主要技术

1、Custom elements (自定义元素)

  • 一组 JavaScript API,允许您定义 custom elements 及其行为,然后可以在您的用户界面中按照需要使用它们

分为两种形式:

自主定制元素:是独立的元素,它不继承其他内建的 HTML 元素,可以直接把它们写成 HTML 标签的形式,来在页面上使用,例如我们刚才自定义的

自定义内置元素:继承自内置的 HTML 元素。指定所需扩展的元素

  • 使用时需通过 is 属性指定 custom element 的名称,必须包含一个短横线
  • 注册的时候必须使用 extends 的属性
1
2
3
4
5
6
7
8
9
10
<p>云牧</p>
 
  class ColorP extends HTMLParagraphElement {
    constructor() {
      super();
      this.style.color = this.getAttribute("color");
    }
  }
  window.customElements.define("color-p", ColorP, { extends: "p" });

推荐在 connectedCallback 生命周期函数,处理节点操作

1
2
3
4
5
6
7
8
9
10
class MyText extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback() {
    this.append("hello world");
  }
}
window.customElements.define("my-text", MyText);

生命周期函数

connectedCallback:插入文档时,可能被多次触发,比如删除后又添加到文档

disconnectedCallback:从文档删除时,可配置做清理工作

adoptedCallback:被移动新文档时

attributeChangedCallback:属性变化时

  • 配合 observedAttributess 属性一起使用,指定监听的属性
  • 使用 setAttribute 方法更新属性

不同操作触发的生命周期函数:

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<div id="container">
  <p id="myText"></p>
</div>
<button id="btnUpdateText">更新属性</button>
<button id="btnRemove">删除节点</button>
<button id="btnRestore">恢复节点</button>
<button id="btnAdopt">移动节点</button>
 
 
  class MyText extends HTMLParagraphElement {
    constructor() {
      super();
    }
    connectedCallback() {
      console.log("生命周期:connectedCallback");
      this.append("你好:" + this.getAttribute("text"));
    }
    disconnectedCallback() {
      console.log("生命周期:disconnectedCallback");
      this.innerHTML = "";
    }
    // 监测的属性
    static get observedAttributes() {
      return ["text"];
    }
    attributeChangedCallback(name, oldValue, newValue) {
      console.log("生命周期:attributeChangedCallback", name, oldValue, newValue);
      // 最先触发是此函数,判断是不是第一次触发,第一次的话,只由 connectedCallback 处理
      if (oldValue != null) {
        this.replaceChildren("你好:" + newValue);
      }
    }
    adoptedCallback() {
      console.log("生命周期:adoptedCallback");
    }
  }
  window.customElements.define("my-text", MyText, { extends: "p" });
  const myText = document.getElementById("myText");
  btnUpdateText.addEventListener("click", function (e) {
    myText.setAttribute("text", "黛玉");
  });
  btnRemove.addEventListener("click", function (e) {
    myText.remove();
  });
  btnRestore.addEventListener("click", function (e) {
    container.appendChild(myText);
  });
  btnAdopt.addEventListener("click", () => {
    const textNode = ifr.contentWindow.document.getElementById("myText");
    container.appendChild(document.adoptNode(textNode));
  });

2、HTML templates(HTML 模板)

  • 使用 JS 模板字串符的方式创建模板,提示不友好,复用性差
1
2
3
4
5
6
7
8
class ProductItem extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback() {
    const content = `
              <img decoding="async" class="img" src="https://misc.360buyimg.com/lib/skin/e/i/error-jd.gif">
              <div class="name"></div>

`;
this.innerHTML = content;
this.querySelector(“.img”).src = this.getAttribute(“img”);
this.querySelector(“.name”).innerText = this.getAttribute(“name”);
this.querySelector(“.price”).innerText = this.getAttribute(“price”);
}
}
window.customElements.define(“product-item”, ProductItem);

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/5425.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部