Web Components

2021-03-25  本文已影响0人  cd2001cjm

定义

浏览器原生支持的一套组件封装技术。这里有两个关键字:

组件化一直是前端完善的方向,从早期jquery组件(easyui),到现在vue组件(elementUI,Vant等),不管如何进步,本质上还是在组合HTML的 input,button,a等等的标签。

但Web Componets除了组合外:

技术组成

Custom elements(自定义元素):一组JavaScript API,允许您定义custom elements及其行为,然后可以在您的用户界面中按照需要使用它们。

HTML templates(HTML模板): <template> 和 <slot> 元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。

Shadow DOM(影子DOM):一组JavaScript API,用于将封装的“影子”DOM树附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,您可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。

定义&注册&使用

前面我们说了,支持定义和扩展两种方式,具体体现在代码上:

完全自定义模式:

定义:class PopUpInfo extends HTMLElement
注册:customElements.define('popup-info', PopUpInfo);
使用:<popup-info></popup-info>

扩展模式:

定义: class ExpandingList extends HTMLUListElement
注册:customElements.define('expanding-list', ExpandingList, { extends: 'ul' });
使用:<ul is="expanding-list">

有图例子中,定义和注册都在main.js,使用则直接在html上


image.png

生命周期

首次加载时的处理,会调用connectedCallback

如果想监听属性的变化,触发attributeChangedCallback(name, oldValue, newValue),
还需要先监听属性,类似vue的Watcher:
static get observedAttributes() {
return ['attr1', 'attr2'];
}

Demo

class PopUpInfo extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();
    // Create a shadow root
    const shadow =  this.attachShadow({mode: 'open'});
   // Create spans
    const wrapper = document.createElement('span');
    wrapper.setAttribute('class', 'wrapper');
    const icon = document.createElement('span');
    icon.setAttribute('class', 'icon');
    icon.setAttribute('tabindex', 0);
     
    略。。。。

    wrapper.appendChild(icon);
  }
}
// Define the new element
customElements.define('popup-info', PopUpInfo);

createElement的方式,如果文档比较多怎么办?

模板

1,在html中定义template,同样也有类似的slot概念

 <template id="my-paragraph">
    <style>
      p {
        color: white;
        background-color: #666;
        padding: 5px;
      }
    </style>
    <p>
      <slot name="my-text">My default text</slot>
    </p>
  </template>

2,在组件中:

      const template = document.getElementById('my-paragraph');
      const templateContent = template.content;

      this.attachShadow({mode: 'open'}).appendChild(
        templateContent.cloneNode(true)
      );

Shadow Dom

Shadow Dom可以说是该技术的精华。

组件封装我们一直追求样式隔离,脚本隔离。
比如:
样式的scoped
Window的代理以及备份还原

而Shadow Dom是天然隔离的,也就是说,组件内的样式,对象只在组件内有效。有点iframe的感觉。

image.png

优缺点以及应用场景

我们总结一下它的优点:

浏览器标准
可以扩展HTML标签
天然各种隔离,真正的组件化
对单元测试友好

哪有没有短板呢?

其实从Web Components提出到现在已经近8年。在该套理论体系下,诞生了三大框架。
现在不能不讨论的就是,该组件和三大框架组件库(比如ElementUI)是一个什么样的关系?

上一篇 下一篇

猜你喜欢

热点阅读