引言
自定义元素是Web组件的一个子集,在我看来这是web 开发中最酷的概念之一,自定义元素让我们能够通过原生的 web 平台来构建组件,而不是依赖于 React、Angular Vue 或者其他的中间库或者框架。
在这篇文章中,我会向你阐述什么是自定义元素、如何创建以及如何在页面上展示。
Web组件的基础
所有自定义元素都将共享一些常用方法,可以在下面的代码示例中看到:
class MyComponent extends HTMLElement { static get observedAttributes() { return []; } constructor(...args) { super(...args); } connectedCallback() {} disconnectedCallback() {} adoptedCallback() {} attributeChangedCallback(attrName, oldVal, newVal) {}}window.customElements.define('my-component', MyComponent);
让我们分解一下这个组件里面做了哪些事情。
constructor() - 构造函数
构造函数是最先声明的,并将所有参数通过 super 方法传递给父级。
通常情况下,构造函数里可以放置一些事件侦听的代码,例如:
...constructor(...args) { super(...args); this.addEventListener('click', this.handleClick); }handleClick(event) {}...
connectedCallback()
每次将元素插入DOM时调用。
每次将组件添加到文档中的任何位置时,它都会立即触发此方法
disconnectedCallback()
每次从DOM中删除元素时调用。
例如,当我们删除DOM树中的该节点或该节点的父节点时,则此函数将触发,因为该节点本身也将从上述 DOM 树中删除。
当元素被移动到文档的其他地方或新页面的时候,disconnectedCallback 也会被调用。
adoptedCallback()
每次将自定义元素移动到新文档时调用。
如果将自定义元素移动到新页面或文档中的其他位置,则将触发此回调。
attributeChangedCallback(attrName, oldVal, newVal)
添加,删除,更新或替换元素的属性时会调用该方法
每当元素的属性变化时,attributeChangedCallback()回调函数就会执行,除非当前属性的改变是已经被监听着的,这个时候就会调用 observedAttributes 方法。
observedAttributes()
我们实际想要观察的自定义元素的属性会发生变化
如您所见,observedAttributes 被设计成是一个静态方法,这明显不同于其他方法的声明,这是因为我们希望能够被任何子类/组件继承,而且我们只想声明它一次引用,注意,它是静态的(为所有继承者包括它自己)和 gettable(供参考)。
这个方法返回一个字符串数组,数组中的每个字符串是你想要监听的属性的名称,例如:
...static get observedAttributes() { return ['id', 'my-custom-attribute', 'data-something', 'disabled']; } ...
自定义元素规范中还有一些其他的方法,但以上这些是我们日常主要使用的方法。
基本组件
让我们构建一个向用户打招呼的基本组件。
html 部分
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Custom Elements 101</title></head><body> <hello-component data-name="James"></hello-component> <script src="./hello-component.js"></script></body></html>
javascript 部分
class HelloComponent extends HTMLElement { static get observedAttributes() { return ['data-name']; } // custom methods render() { this.innerHTML = Hello ${this.name}; } get name() { return this.getAttribute('data-name'); } // lifecycle hooks connectedCallback() { this.render(); } attributeChangedCallback(attrName, oldVal, newVal) { this.render(); } }// add into the 'real' dom as a valid tagwindow.customElements.define('hello-component', HelloComponent);
加载index.html,我们可以在页面上看到“Hello James”。
现在,打开浏览器的开发者工具并将data-name属性更改为除James 之外的其他值。你会发现我们有内置的反应!是不是很棒?!
当然,这只是一个非常基本的、非最佳实践、0用例,默认教程的实现,但他给了你一个基本的入门介绍,以便我们在后面的文章中做更详细的深入。
浏览器支持
以下是当前对Web组件的支持以及所有支持它们的API,包括Shadow DOM,自定义元素(我们刚刚查看的内容),HTML模板和插槽以及HTML导入:
总结
自定义元素让我们有能力在无需借助框架的情况下实现反应式的 UI 开发。它们确实为我们提供了许多挑战,其中许多将在未来展望, 但是我们可以先去尝试一下,并把其他的「Web Component 」相关规范的 API 放在一起看下,它们真的让我们能够制作出很酷、很强大、反应灵敏的元素,让我们可以用很少的东西做很多事。
资料
译文出处:https://www.zcfy.cc/article/an-introduction-to-custom-elements-dev-community