Web Components才是组件化的未来
上一时代的
牺牲品
是jQuery,如今Web Components被越来越多的浏览器所支持,React,Vue或许是下一个“祭品”。
组件化、复用,这几乎是所有开发者追求的东西。Web Components就是为此而提出。可以使用来创建封装功能的定制元素,可以在你喜欢的任何地方重用,不必担心代码冲突。
这样的理念和Vue十分相似,专注于组件。所以Web Components或许是未来的方向!
组件是 Web 开发的方向,现在的热点是 JavaScript 组件,但是 HTML 组件未来可能更有希望。
浏览器将自定义元素保留在 DOM 之中,但不会任何语义。除此之外,自定义元素与标准元素都一致
事实上,浏览器提供了一个HTMLUnknownElement
,HTMLElement
对象,所有自定义元素都是该对象的实例。
1 | var tabs=document.createElement("tabs"); |
Custom Elements 标准: 自定义元素的名字必须包含一个破折号(-)
一旦名字之中使用了破折号,自定义元素就不是HTMLUnknownElement的实例了。1
2
3var tabs=document.createElement("my-tabs");
console.log(tabs instanceof HTMLUnknownElement); //false
console.log(tabs instanceof HTMLElement); //true
Custom Elements 标准规定了,自定义元素的定义可以使用 ES6 的class语法
1 |
|
自定义elements
Web Components通过CustomElementRegistry.define()来定义elements,目前有两种elements,独立的element与继承自基本的HTML element
独立的element
独立的element像1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21customElements.define('custom-element',
class MyCustomElement extends HTMLElement {
constructor() {
super();
//创建<p stype='color:red'></p>
const pElem = document.createElement('p');
pElem.textContent = this.textContent;
pElem.style.color = 'red';
//加入根节点
const shadowRoot = this.attachShadow({mode: 'closed'});
shadowRoot.appendChild(pElem);
}
}
)
...
<custom-element>红色字体的段落!</custom-element>
生命周期回调函数
在自定义的element的构造函数中,可以指定多个不同的回调函数,它们将会在元素的不同生命时期被调用:
- connectedCallback:当 custom element首次被插入文档DOM时,被调用。
- disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
- adoptedCallback:当 custom element被移动到新的文档时,被调用。
- attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。
例如:
1 | customElements.define('other-custom-element', |
Shadow DOM
如图,Shadow DOM会在自定义标签解析时,加载到普通的DOM上。内部可以通过Element.attachShadow()来获取shadow root。它有一个mode属性,值可以是open或者closed,表示能否在外部获取Shadow DOM对象,一般而言应当为closed,内部实现不应该对外可见。
HTML templates
如果你熟悉Vue的话,这块与它很相似,是template与slot。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<template id="person-template">
<div>
<h2>Personal ID Card</h2>
<slot name="person-name">NAME MISSING</slot>
<ul>
<li><slot name="person-age">AGE MISSING</slot></li>
<li><slot name="person-occupation">OCCUPATION MISSING</slot></li>
</ul>
</div>
</template>
<person-details>
<!-- 官方例子p slot="person-name",由于hexo对p的解析会出错,这里改成了<span> -->
<span slot="person-name">Morgan Stanley</span>
<span slot="person-age">36</span>
<span slot="person-occupation">Accountant</span>
</person-details>
1 | customElements.define('person-details', |
HTML Imports
这块存在争议,Mozilla认为将来应该用更合适的方式。不多做介绍。
Web Components视频播放器
1 | class Eplayer extends HTMLElement { |