Web Components尝试

在Web开发组件化的今天,React、Angular,Vue等主流框架都支持组件化的开发。Web Components的出现,使得浏览器可以原生支持组件化的开发。目前Web Components的支持程度如下图:

《Web Components尝试》

通过Web Components,我们可以封装自己的html、js、css,不必担心会影响到其他页面。下面通过一个自己定义的文件上传按钮来展示如何创建一个Web Components。

1. 创建Web Components

首先,我们需要定义一个类并继承自HtmlElement。

//define web component
class MyFileInput extends HTMLElement {
    constructor() {
        super();
        const template = document.getElementById('myFileInputTemplate');
        const templateContent = template.content;
        //方法给指定的元素挂载一个Shadow DOM,并且返回它的 ShadowRoot.
        //open 指定为开放的封装模式。
        //closed 指定为关闭的封装模式。
        //如果你将一个 Shadow root 添加到一个 Custom element 
        //将mode设置为closed,那么就不可以在外部获取 Shadow DOM了——myCustomElem.shadowRoot 将会返回 null。
        this.attachShadow({ mode: 'open' }).appendChild(
            templateContent.cloneNode(true)
        );
    }
}

在构造函数中获取了我们自定义元素的模板内容,并为元素挂载一个Shadow DOM。同时将模板内容添加到了Shadow DOM中。

定义好元素后,我们需要先注册自定义的元素,然后才能使用。通过window.customElements.define来注册元素,该方法的定一个参数可以指定元素的标签名称。

//register web componnet
window.customElements.define('my-file-input', MyFileInput);

然后就可以通过以下方式使用该自定义元素:

<my-file-input id="myFileInput">
    <span slot="btnText">
        Browse
    </span>
</my-file-input>

HTML模板的定义如下:

<template id="myFileInputTemplate">
    <style>
        :host {
            font-family: Helvetica, sans-serif;
        }

        .btn-browser {
            position: relative;
            display: inline-block;
            line-height: 30px;
            text-decoration: none;
            text-align: center;
            cursor: pointer;
            border: 1px solid transparent;
            border-radius: 4px;
            padding: 6px 12px;
            font-size: 14px;
            color: #fff;
            background-color: #337ab7;
            border-color: #2e6da4;
        }

        input[type="file"] {
            position: absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            opacity: 0;
            font-size: 100px;
            cursor: pointer;
        }
    </style>
    <div class="my-input-container">
        <a href="javascript:;" class="btn-browser">
            <input type="file" />
            <slot name="btnText"></slot>
        </a>
    </div>
</template>

在HTML模板中,可以定义元素的样式,元素的HTML内容。 :host代表元素本身。

2. slot 插槽

在上述的模板中,可以看到按钮的文本是通过插槽的方式填充到元素中的。通过插槽,可以将自己的HTML内容插入到Web Components的指定位置。

创建name为btnText的插槽:

<span slot="btnText">
    Browse
</span>

引用了name为btnText的插槽:

<slot name="btnText"></slot>

3. Web Components 生命周期函数

Web Components包含以下生命周期函数:

  • connectedCallback: 当自定义元素第一次被加入到文档时被调用。
  • disconnectedCallback: 当自定义元素与文档DOM断开连接时被调用。(从文档中移除)
  • adoptedCallback: 当自定义元素被移动到新文档时被调用。(调用adoptNode方法)
  • attributeChangedCallback: 当自定义元素的一个属性被增加、移除或更改时被调用。
connectedCallback() {
    console.log('connected');
}

//will trigger if element is removed
disconnectedCallback() {
    console.log('disconnected');
}

//tirgger if adoptNode is called
adoptedCallback() {

}

attributeChangedCallback(attrName, oldVal, newVal) {
    console.log(arguments);
}

以上。

参考

Web Components-MDN

    原文作者:ckllj
    原文地址: https://segmentfault.com/a/1190000020118679
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞