什么是 Custom Elements
Custom Elements 是 Web Components 的一种技术,它使得开发者能够创建自定义的 HTML 元素,这些元素可以添加自己的属性和方法,形成独立的组件,方便复用和维护。Custom Elements 是由 W3C 官方标准化的,因此它具有跨浏览器兼容性,并且可以不依赖于任何框架,单独使用。同时,使用 Custom Elements 还可以让代码更加规范化和可维护。
如何创建 Custom Elements
定义元素
定义元素的方式有两种:
通过类和继承
<template id="hello-world"> <style>h1 { color: red; }</style> <h1>Hello World!</h1> </template>
class HelloWorld extends HTMLElement { constructor() { super(); const template = document.getElementById('hello-world').content; this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true)); } } customElements.define('hello-world', HelloWorld);
这段代码中,我们通过 ES6 的类语法来创建一个名为 HelloWorld
的元素,并继承了 HTMLElement
类。在 constructor
函数中,我们首先调用父类 HTMLElement
的 constructor
方法,在方法内部,创建了 template
模板元素,并通过 attachShadow
方法创建了新的 shadow root,将模板元素添加到 shadow root 中。
最后,我们通过 customElements.define
方法定义了 hello-world
,这个名称会在我们使用时派上用场。
通过原型对象
<template id="hello-world"> <style>h1 { color: red; }</style> <h1>Hello World!</h1> </template>
const HelloWorldProto = Object.create(HTMLElement.prototype, { constructor: { value: function () { const template = document.getElementById('hello-world').content; const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.cloneNode(true)); }, writable: true, configurable: true } }); customElements.define('hello-world', HelloWorldProto);
这段代码中,我们通过 Object.create
方法创建了一个原型对象,并继承了 HTMLElement.prototype
,之后给该原型对象添加了 constructor
方法,并将其传递了一个函数。在构造函数中,我们按照上述内容创建了元素,并将其添加到 shadow root 中。
使用元素
使用刚刚定义的元素非常简单,只需要在 HTML 中使用它的标签名即可:
<hello-world></hello-world>
此时,浏览器会自动创建我们定义的 HelloWorld
元素。
Custom Elements 的实践
组合元素
在实际开发中,我们有时需要将多个元素组合成一个新的元素,方便复用和维护。在 Custom Elements 中,我们可以通过组合使用 div
和 slot
元素来实现元素的组合。
<!-- 定义一个可复用的 card 组件 --> <template id="card-template"> <style> .card { border: 1px solid #ddd; padding: 10px; } </style> <div class="card"> <h2></h2> <p></p> </div> </template> <card-el> <h2>Custom Elements 实践</h2> <p>这是一个基于 Custom Elements 创建的 card 组件。</p> </card-el>
class CardElement extends HTMLElement { constructor() { super(); const template = document.getElementById('card-template').content; const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.cloneNode(true)); const titleElement = this.shadowRoot.querySelector('h2'); const contentElement = this.shadowRoot.querySelector('p'); titleElement.innerText = this.getAttribute('title'); contentElement.innerText = this.innerHTML; } } customElements.define('card-el', CardElement);
在上面的代码中,我们定义了一个名为 CardElement
的元素,并组合使用了一个 div
标签和两个 slot
标签。在构造函数中,我们通过 getAttribute
和 innerHTML
方法来获取 title 和 content,分别赋值到 card 组件中的 h2
和 p
元素上。这样,我们就创建了一个灵活且可复用的 card 组件!
监听属性变化
在 Web 组件中,我们经常需要监听属性的变化。在 Custom Elements 中,我们可以使用 attributeChangedCallback
方法来监听自定义属性的变化。
class HelloWorld extends HTMLElement { static get observedAttributes() { return ['name']; } constructor() { super(); const template = document.createElement('template'); template.innerHTML = ` <div>Hello, <span></span>!</div> `; this.attachShadow({ mode: 'open' }).appendChild(template.content.cloneNode(true)); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'name') { this.shadowRoot.querySelector('span').innerText = newValue; } } } customElements.define('hello-world', HelloWorld);
在上面的代码中,我们首先通过 static get observedAttributes
方法定义监测的属性名数组,然后在 constructor
函数中创建了 template
模板元素,并将其添加到了 shadow root 中。
最后,我们定义了 attributeChangedCallback
方法来监听 name 属性的变化,如果属性变化,则修改页面上的文字信息。
生命周期方法
Custom Elements 提供了一些生命周期方法来监听元素在生命周期中的变化,它们分别是:
connectedCallback
: 元素被插入到文档时调用。disconnectedCallback
: 元素从文档中删除时调用。adoptedCallback
: 元素被移动到新的文档时调用。attributeChangedCallback
: 自定义属性被添加、删除、更新时调用。
在实际开发中,我们可以使用这些生命周期方法来完成一些特殊的需求。
总结
Custom Elements 是一种非常适合组件化开发的技术,它提供了一种标准化的、可扩展的、独立于框架的定义和使用 Web 组件的方法。在使用 Custom Elements 进行组件开发时,我们需要重点关注元素的定义、使用、组合和监听属性等特殊需求。Custom Elements 的出现,有助于使 Web 组件的开发更加规范、高效,降低前端开发的复杂度,提高开发效率和代码质量。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6590e40feb4cecbf2d627eb9