web Component - 技术指南

06-02 1304阅读

什么是web Component ?

mdn 官方定义: Web Component

Web Component 是一套不同的技术,允许你创建可重用的定制元素(它们的功能封装在你的代码之外)并且在你的 web 应用中使用它们。

简单来说他是一组标准化的web技术,允许开发者来创建可重用的自定义标签,并且这些标签可以在不同的web应用中使用,并且可以封装内部逻辑和样式避免与使用页面的其他部门发生冲突。

Web Component主要有以下3个规范组成:

  • Custom element(自定义元素):自定义标签以及行为

  • Shadow DOM(影子 DOM):  提供DOM树与页面其余部分隔离的方法,确保样式不会泄露到全局。

  • HTML template(HTML 模板): 用于定义可重复使用的 HTML 片段,这些片段在初始加载时不会被渲染,但可以在需要时插入文档

    Web Components 解决了什么问题?

    1. 可重用性:开发者可以创建一次组件并在多个项目中重复使用,减少了代码冗余,提高了开发效率。

    2. 封装性:使用 Shadow DOM 封装样式和逻辑,确保组件内部的样式和脚本不会影响页面的其他部分,反之亦然。这有助于构建更稳定、更易于维护的应用程序。

    3. 互操作性:Web Components 是基于标准的,因此可以在不同的框架和库之间无缝工作。无论你使用的是 React、Vue 还是纯 JavaScript,都可以轻松集成 Web Components。

    4. 模块化:组件化的开发方式使得代码更加模块化,便于团队协作和代码管理。每个组件可以独立开发、测试和部署。

    5. 简化前端开发:Web Components 提供了一种简单而强大的方法来构建复杂的用户界面,降低了前端开发的复杂度,尤其是对于大型应用。

    实现 Web Components ?

    通过Web Component实现一个自定义元素,通常需要一下5步骤:

    步骤一: 创建一个类或函数来指定 web 组件的功能,

    步骤二:使用 CustomElementRegistry.define() 方法注册你的新自定义元素。

    步骤三:使用 Element.attachShadow() 方法将一个 shadow DOM 附加到自定义元素上,可以根据需求是否添加。

    步骤四:使用 "> 和 "> 定义一个 HTML 模板。可以根据需求是否定义。

    步骤五:页面中使用。uabn

    使用自定义元素:

    自定义元素类型:

    • 自定义内置元素:继承自标准的HTML元素,如HTMLImageElement、 HTMLParagraphElement,已经实现了标准元素的行为。
    • 独立自定义元素: 继承HTML元素基类HTMLElement, 必须从头实现行为。

      实现:以独立自定义元素为案例:(在构造函数中不能检查元素的属性或子元素,也不应添加新的属性或子元素 )构造函数如下

      // 自定义内置
      class WordCount extends HTMLParagraphElement {
        constructor() {
          super();
        }
        // 此处编写元素功能
      }
      // 独立自定义元素
      class PopupInfo extends HTMLElement {
        constructor() {
          super();
        }
        // 声明周期回调
        connectedCallback() {
          console.log("自定义元素添加至页面。");
        }
        disconnectedCallback() {
          console.log("自定义元素从页面中移除。");
        }
        adoptedCallback() {
          console.log("自定义元素移动至新页面。");
        }
        attributeChangedCallback(name, oldValue, newValue) {
          console.log(`属性 ${name} 已变更。`);
        }
      }

      注册:使用Window.customElements 的 define() 方法注册自定义元素, 方法参数如下:

      • name: 元素名称, 命名必须小写字母开头包含一个连字符
      • constructor: 自定义元素的构造函数
      • options: 仅对自定义内置元素生效,配置要拓展的元素

        自定义内置元素注册和使用:

        // 注册:
        customElements.define("word-count", WordCount, { extends: "p" });
        // 使用:作为is属性的值
        

        独立自定义元素注册和使用:

        // 注册:
        customElements.define("popup-info", PopupInfo);
        // 使用:
        
          
        
        

        响应属性变化:与内置元素一样, 自定义元素可以使用HTML来配置元素的行为, 为此可以添加如下属性:

        • observedAttributes:静态属性,包含变更通知的所有属性数组。
        • attributeChangedCallback():生命周期回调实现。(此方法在observedAttributes属性变动时调用)

          例如: 观察size属性,并在变化时记录新旧值。

          // 为这个元素创建类
          class MyCustomElement extends HTMLElement {
            static observedAttributes = ["size"];
            constructor() {
              super();
            }
            attributeChangedCallback(name, oldValue, newValue) {
              console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}。`);
            }
          }
          customElements.define("my-custom-element", MyCustomElement);

          请注意,如果元素的 HTML 声明包含一个被观察的属性,那么在属性被初始化后,attributeChangedCallback() 将在元素的声明首次解析时被调用。

          使用影子DOM: 

          影子 DOM(Shadow DOM)允许你将一个 DOM 树附加到一个元素上,并且使该树的内部对于在页面中运行的 JavaScript 和 CSS 是隐藏的。在其之下你可以用与普通 DOM 相同的方式附加任何元素

          web Component - 技术指南

          1、创建:调用影子宿主DOM上的 attachShadow() 来创建影子 DOM

                  参数说明:{mode: "open"}: 页面中可通过影子宿主的 shadowRoot 属性访问影子 DOM 的内部,如果不希望破坏影子 DOM 封装,可设置{mode: "closed"} 

          const host = document.querySelector("#host");
          const shadow = host.attachShadow({ mode: "open" });
          const span = document.createElement("span");
          span.textContent = "I'm in the shadow DOM";
          shadow.appendChild(span);

            页面展示看起来是这样

          web Component - 技术指南

          2、CSS样式应用:

          • 编程式:构建 CSSStyleSheet 附加到影子根。
          • 声明式:在template声明中添加style元素

            编程式实现:1.创建一个空的CSSStyleSheet对象,2.使用replace()/replaceSync()设置内容,3.通过ShadowRoot.adoptedStyleSheets来添加到影子根:,

            const sheet = new CSSStyleSheet();
            sheet.replaceSync("span { color: red; border: 2px dotted black;}");
            const host = document.querySelector("#host");
            const shadow = host.attachShadow({ mode: "open" });
            shadow.adoptedStyleSheets = [sheet];
            const span = document.createElement("span");
            span.textContent = "I'm in the shadow DOM";
            shadow.appendChild(span);

            声明式实现:1.创建template,并添加style标签和样式内容,2.创建影子dom,并将template的内容添加到影子Dom

              
                span {
                  color: red;
                  border: 2px dotted black;
                }
              
              I'm in the shadow DOM
            
            // 创建影子 DOM 并将  的内容添加到其中:
            const host = document.querySelector("#host");
            const shadow = host.attachShadow({ mode: "open" });
            const template = document.getElementById("my-element");
            shadow.appendChild(template.content);

            以上两种方式使用选择推荐:

            编程式:样式表需要与多个dom树共享时推荐使用。

            声明式:需要较少的样式并且不需要在不同组件之间共享样式的时候

            3. 影子DOM和自定义元素:

            如果没有影子DOM提供封装,自定义元素将无法使用,页面上运行的其他js或css,可能无意间破坏自定义元素的行为或布局。

            自定义元素被实现为一个类,它可以继承内置 HTML 元素。通常,自定义元素本身是一个影子宿主,该元素在其根节点下创建多个元素,以提供元素的内部实现。

            例如: 创建自定义元素,仅渲染一个实心颜色圆形。

            class FilledCircle extends HTMLElement {
              constructor() {
                super();
              }
              connectedCallback() {
                // 创建一个影子根
                // 自定义元素自身是影子宿主
                const shadow = this.attachShadow({ mode: "open" });
                // 创建内部实现
                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                const circle = document.createElementNS(
                  "http://www.w3.org/2000/svg",
                  "circle",
                );
                circle.setAttribute("cx", "50");
                circle.setAttribute("cy", "50");
                circle.setAttribute("r", "50");
                circle.setAttribute("fill", this.getAttribute("color"));
                svg.appendChild(circle);
                shadow.appendChild(svg);
              }
            }
            customElements.define("filled-circle", FilledCircle);

            使用模版和插槽:

            如何使用和元素创建一个灵活填充web组件的影子DOM的模版。

            当你必须在网页上复用相同的标记结构时,使用某种模板而不是一遍又一遍地重复相同的结构是有意义的。以前也可以实现这一点,但 HTML "> 元素使得这个过程更加简单。此元素及其内容不会在 DOM 中渲染,但仍可使用 JavaScript 引用它。

            1.使用模版:(相较于原生创建dom追加元素更便捷,并且复用性高)

            customElements.define(
              "my-paragraph",
              class extends HTMLElement {
                constructor() {
                  super();
                  let template = document.getElementById("my-paragraph");
                  let templateContent = template.content;
                  const shadowRoot = this.attachShadow({ mode: "open" });
                  shadowRoot.appendChild(templateContent.cloneNode(true));
                }
              },
            );

            2. 使用插槽:使用slot通过声明式语法在实例中展示不同文本。

            模版改造:

              

            我的默认文本

            使用:

              让我们使用一些不同的文本!
            
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码