为了更好的阅读体验,可以点击阅读原文进行阅读
尽量复用已有代码是每个开发者无师自通的本领,在前端领域,所有热门的框架无疑都拥有一个共同的特点:组件化开发。因为在Web Component之前并没有原生的组件化解决方案,所以我们不得不依赖一些工程化手段来做到这一点。而目前主流浏览器都已很好地支持了Web Component标准,这是一种原生的组件化开发方案。它允许我们创建一个包含html结构、js脚本和css样式的可复用组件,而不用担心冲突问题。
自定义元素和扩展内置元素
我们可以通过两种方式来创建一个封装的组件:自定义元素和扩展内置元素。两者的区别就是我们需要从头开始完整的实现自定义元素的行为,而扩展内置元素会使得组件继承内置元素已有的特性,例如继承自li元素就会有相应的list-style,但是要定义它们的话都需要使用window.customElements.define方法,该方法接受三个参数,分别组件名称、组件实现类及继承的元素(可选),下面是简单的示例:
// 自定义元素类继承自HTMLElement,且在define时不需要传入第三个参数
class MyElement extends HTMLElement {
}
window.customElements.define("my-component", MyElement)
// 扩展内置元素继承自对应的DOM类,并且在define时需要传入第三个参数声明继承自哪个内置元素
class MySpan extends HTMLSpanElement {
}
window.customElements.define("my-span", MySpan, {
extends: "span" })
接下来在html文件中引入这个js文件就可以使用组件了:
<!-- 直接以标签的形式使用自定义元素即可 -->
<my-element />
<!-- 通过指定is属性来声明需要使用的扩展内置元素 -->
<span is="my-span"></span>
生命周期回调
每个自定义组件都有自己的生命周期,以下是4个主要的生命周期回调方法:
connectedCallback:当自定义元素第一次被连接到文档 DOM 时被调用。disconnectedCallback:当自定义元素与文档 DOM 断开连接时被调用。adoptedCallback:当自定义元素被移动到新文档时被调用。attributeChangedCallback:当自定义元素的一个属性被增加、移除或更改时被调用。
其中有一点需要注意的是,如果要使用attributeChangedCallback监听属性的变化,需要在类中使用observedAttributes属性声明要监听的属性列表,就像下面这样:
class MyElement extends HTMLElement {
// 通过attributesChangedCallback监听组件的size和color属性的变化
static observedAttributes = ["size", "color"]
connectedCallback() {
console.log("自定义组件已被连接到DOM")
}
disconnectedCallback() {
console.log("自定义组件已断开和DOM的连接")
}
adoptedCallback() {
console.log("自定义组件已被移动到新文档")
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`${
name}属性已由${
oldValue}变更为${
newValue}`)
}
}
使用Shadow DOM
和其他框架一样,Web Component最重要的目标就是封装,那么封装好的组件就不应该被外部环境所影响,这就需要有一种机制来完成自定义元素的结构和样式隔离。Shdow Root就很好地做到了这一点,简单直译的话,我们可以称之为影子根,我们可以在这个影子根中添加任意的HTML结构和css样式而不受外部的影响,先来看一个简单的使用示例:
class CustomComponent extends HTMLElement {
// 一般我们在自定义元素连接到DOM的回调中创建影子根并添加结构与样式等而不是在constructor中
// 在此回调中,可以通过this.attachShadow创建一个影子根元素,之后就可以像普通DOM节点一样操作它
connectedCallback() {
const shadow = this.attachShadow({
mode: "open" })
const span = document


9405

被折叠的 条评论
为什么被折叠?



