赞
踩
Web Components 是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的 web 应用中使用它们。
-- Web Components | MDN[1]
关于它的其它介绍:
组件是前端的发展方向,现在流行的 React 和 Vue 都是组件框架。而 Web Component 相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。目前,已经发展的比较成熟,并用于生产环境。
组件化开发使得我们可以将页面切割成模块便于封装和开发,而 Web Component 在此基础上,可以将每个组件渲染在独立的 DOM 树中,天然支持模块间样式和逻辑的隔离。
这里会对 Web Component 的相关属性做一个简单介绍。
Web Component 特性完整代码:
https://codesandbox.io/s/snowy-darkness-jmdip7
一组 Javascript API,允许您定义 Custom Elements 及其行为,然后在您的用户界面中按照需要使用它们。
- // custom button
- class CustomButton extends HTMLElement {
- constructor() {
- super();
- const button = document.createElement("button");
- button.innerText = this.getAttribute("name") || "custom button";
- button.disabled = true;
- this.appendChild(button);
- }
- }
-
- window.customElements.define("custom-button", CustomButton);
window.customElements.get
该方法用来获取自定义组件的构造函数,接收一个参数,即声明的自定义组件的 name,返回构造函数。
- const getCustomConstructorBefore = customElements.get('custom-button');
- // getCustomConstructorBefore before: undefined
- console.log('getCustomConstructorBefore before: ', getCustomConstructorBefore);
- customElements.define("custom-button", CustomButton);
- const getCustomConstructorAfter = customElements.get('custom-button');
- // getCustomConstructorAfter after: ƒ CustomButton() {}
- console.log('getCustomConstructorAfter after: ', getCustomConstructorAfter);
window.customElements.upgrade
customElements upgrade() 方法升级节点子树中文档的所有包含 shadow dom 的(亲测,可以不包含 shadow dom)自定义元素,甚至在它们连接到主文档之前。接收一个参数,即一个自定义组件节点,无返回值。
- // 先创建自定义标签
- const el = document.createElement("spider-man");
-
- class SpiderMan extends HTMLElement {}
- // 后声明构造函数
- customElements.define("spider-man", SpiderMan);
-
- // false
- console.log(el instanceof SpiderMan);
- // 建立自定义标签与构造函数之间的绑定关系
- customElements.upgrade(el);
- // true
- console.log(el instanceof SpiderMan);
window.customElements.whenDefined
该方法用来检测并提供自定义组件被定义声明完毕的时机,接收一个参数,即自定义元素的 name,返回值是一个 Promise,若提供的 name 无效,则触发 Promise 的 catch,可以用来判断是否定义了同名的 Custom Element。
Custom Element 重复定义的报错:
我们可以用这个方法来捕获重复定义的报错,最推荐 define 之前先 get 一下~
- customElements.whenDefined('custom-button').then(() => {
- customElements.define('custom-button', CustomButton);
- }).catch((err) => {
- console.log(err, 'err-----')
- });
捕获的报错信息:
Custom Elements
提供了一些生命周期函数,使得我们能在自定义元素在 DOM 中的行为变化后执行相关逻辑。
ConnectedCallback:当自定义元素第一次被连接到文档 DOM 时调用(类似组件 Mounted);
attributeChangedCallback:当自定义元素的一个属性被增加、移除或更改时被调用,需要配合静态方法 observedAttributes 来使用,设置只有注册在 observedAttributes 中的属性才被监听;
disconnectedCallback:当自定元素与文档 DOM 断开连接时调用(类似 Unmount);
adoptedCallback:当自定义元素被移动到新文档时被调用;
示例代码:
- class CustomButton extends HTMLElement {
- constructor() {
- super();
- const button = document.createElement("button");
- button.innerText = "custom button";
- button.addEventListener("click", this.changeAttribute.bind(this));
-
- const textSpan = document.createElement("span");
- textSpan.innerText = this.getAttribute("text") || "default";
- textSpan.className = "info";
- this.appendChild(button);
- this.appendChild(textSpan);
- }
- connectedCallback() {
- console.log("自定义button被连接到DOM啦~");
- }
- // observedAttributes,定义特定属性变化时,触发attributeChangedCallback函数
- // 未定义的属性改变,则不会触发回调
- static get observedAttributes() {
- return ["style", "text"];
- }
- // 与observedAttributes结合使用
- attributeChangedCallback(name, oldValue, newValue) {
- if (
- name === "text" &&
- oldValue !== newValue &&
- this.querySelector(".info")
- ) {
- this.querySelector(".info").innerText = newValue;
- }
- }
- changeAttribute() {
- this.setAttribute("text", "sfsdfd");
- }
- disconnectedCallback() {
- console.log("自定义button与DOM断开连接啦~");
- }
- adoptedCallback() {
- // 创建一个iframe的document,并移动进去
- console.log("自定义button移动到新文档啦~");
- }
- clickToRemove() {
- // 从DOM中移除自身
- this.parentNode.removeChild(this);
- }
- }
-
- window.customElements.define("custom-button", CustomButton);
一组 Javascript API,可以将封装的“Shadow DOM”树附加到元素(与主文档分开呈现),并控制其关联的功能。通过这种方式,您可以拥有一个天然的沙箱环境,保持元素的功能私有,实现样式和脚本的隔离,不用担心与文档的其他部分发生冲突。
示例代码:
- class CustomShadowDOM extends HTMLElement {
- constructor() {
- super();
-
- // 创建一个shadowDOM
- const shadow = this.attachShadow({ mode: "open" });
- const info = document.createElement("span");
- const style = document.createElement("style");
- const css = "span { color: red; }";
- style.type = "text/css";
- style.appendChild(document.createTextNode(css));
-
- info.setAttribute("class", "info");
- info.textContent = this.getAttribute("text") || "default";
- // shadow可以创建一个不受外部影响,切拥有内部js运行逻辑,拥有独立的
- // css的自定义元素(也就是web component),
- shadow.appendChild(style);
- shadow.appendChild(info);
- }
- }
-
- window.customElements.define("custom-shadow-dom", CustomShadowDOM);
并非只能在 CustomElement 下使用,即便是普通的 HTMLElement 也能使用这一技术来实现样式保护,详见
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。