前言
Web Components 是一种用于创建可复用的自定义 HTML 元素的技术。它由四个主要的技术组成:Custom Elements、Shadow DOM、HTML Templates 和 ES Modules。使用 Web Components,我们可以创建可复用的模块化 UI 组件,这些组件可以在任何网页中使用,而且不需要其他的框架或库的支持。在本文中,我们将介绍如何使用 Web Components 构建可复用的模块化 UI 组件,以及如何将它们集成到现有的网页中。
Custom Elements
Custom Elements 允许我们创建自定义的 HTML 元素。这些元素可以具有任何名称,并且可以包含自己的属性和方法。要创建自定义元素,我们需要使用 window.customElements.define()
方法。这个方法需要两个参数:元素名称和元素定义对象。元素定义对象包含 extends
属性,该属性指定自定义元素的基类。我们可以将自定义元素继承自任何 HTML 元素,例如 HTMLDivElement
或 HTMLButtonElement
。
以下是一个简单的示例,其中我们创建了一个名为 my-button
的自定义元素,它继承自 HTMLButtonElement
,并添加了一个名为 color
的属性:
-- -------------------- ---- ------- ---------- ----------------- -------------- -------- ----- -------- ------- ----------------- - ------------- - -------- ------------------------------ -- -- - ------------- --------- --- - ------ --- -------------------- - ------ ---------- - ------------------------------ --------- --------- - -- ----- --- -------- - ---------------- - --------- - - - ----------------------------------------- --------- - -------- -------- --- ---------
在这个示例中,我们创建了一个名为 MyButton
的类,它继承自 HTMLButtonElement
。我们在构造函数中添加了一个点击事件监听器,当用户点击按钮时,会弹出一个对话框。我们还定义了一个名为 color
的属性,并在 observedAttributes
方法中声明,以便在属性值发生变化时进行处理。在 attributeChangedCallback
方法中,我们检查属性名称是否为 color
,如果是,则将按钮的文本颜色设置为属性值。最后,我们使用 window.customElements.define()
方法将 MyButton
类定义为名为 my-button
的自定义元素,并继承自 button
元素。
Shadow DOM
Shadow DOM 允许我们将元素的样式和行为封装在一个独立的 DOM 树中,从而避免与其他元素的样式和行为发生冲突。要创建 Shadow DOM,我们需要使用 Element.attachShadow()
方法。这个方法接受一个 ShadowRootInit
对象作为参数,该对象包含 mode
属性,指定 Shadow DOM 的模式。有两种模式可用:open
和 closed
。open
模式允许外部代码访问 Shadow DOM,而 closed
模式不允许。
以下是一个示例,其中我们创建了一个名为 my-dialog
的自定义元素,它包含一个名为 header
的插槽和一个名为 content
的 Shadow DOM:
-- -------------------- ---- ------- ----------- --- -------------------- ----------- -- ------------------- -- - ------ -------- ------------ -------- ----- -------- ------- ----------- - ------------- - -------- ----- ------ - ------------------- ----- -------- --- ----- -------- - ----------------------------------- ------------------ - - ------- ----- - -------- ------ --------- ------ ---- -- ----- -- ------ ----- ------- ----- ----------------- ------- -- -- ----- -------- -- - ------- - --------- --------- ---- ---- ----- ---- ---------- --------------- ------ ------ ------ ----------------- ------ -------- ----- -------------- ---- ----------- - --- --- ------- -- -- ----- - -------------------------- - ---------- ----- ------------ ----- ------- - - ---- -- - --------------------------- - ---------- ----- ------- -- - -------- ---- --------------- ----- --------------------- ----- ---------------------- ------ -- ----------------------------------------------------- - - ----------------------------------------- ---------- ---------
在这个示例中,我们创建了一个名为 MyDialog
的类,它继承自 HTMLElement
。在构造函数中,我们使用 Element.attachShadow()
方法创建了一个 Shadow DOM,并将一个名为 template
的模板元素添加到 Shadow DOM 中。模板元素包含了一些 CSS 样式和 HTML 标记,用于渲染对话框。我们通过 ::slotted()
伪元素选择器对插槽内容进行样式设置,从而将其样式与对话框的样式分离。最后,我们使用 window.customElements.define()
方法将 MyDialog
类定义为名为 my-dialog
的自定义元素。
HTML Templates
HTML Templates 允许我们创建可重复使用的 HTML 片段。这些片段可以包含任何 HTML 标记和文本,并可以在需要时动态地插入到文档中。要创建 HTML 模板,我们可以使用 <template>
标记。
以下是一个示例,其中我们创建了一个名为 my-list
的自定义元素,它使用 HTML 模板来渲染列表项:
-- -------------------- ---- ------- --------- ------------------ ---------------- ------------------ ---------------- ------------------ ---------------- ---------- -------- ----- ------ ------- ----------- - ------------- - -------- ----- -------- - ----------------------------------- ------------------ - - ------- ----- - -------- ------ - -- - ----------- ----- -------- -- ------- -- - -------- --------- -- ----- ------ - ------------------- ----- ------ --- ----------------------------------------------------- ---------- - --------------------------- - ------------------- - ----- -------- - -------------------------- ---------------------- -- - -- -------------- --- --------------- - ----- -- - ----------------------------- ------------ - ---------------- --------------------------- - --- - - ----- ---------- ------- ----------- -- --------------------------------------- -------- -------------------------------------------- ------------ ---------
在这个示例中,我们创建了一个名为 MyList
的类,它继承自 HTMLElement
。在构造函数中,我们创建了一个名为 template
的 HTML 模板,并将其添加到 Shadow DOM 中。模板元素包含了一些 CSS 样式和一个空的 <ul>
元素。我们在 connectedCallback()
方法中遍历子元素,如果子元素是一个名为 my-list-item
的自定义元素,则创建一个 <li>
元素,并将其添加到 <ul>
元素中。最后,我们使用 window.customElements.define()
方法将 MyList
和 MyListItem
类定义为名为 my-list
和 my-list-item
的自定义元素。
ES Modules
ES Modules 允许我们在 JavaScript 中使用模块化的语法。我们可以使用 import
和 export
关键字来导入和导出模块。要使用 ES Modules,我们需要在 HTML 中使用 <script type="module">
标记,以便浏览器知道我们正在使用模块化的 JavaScript。
以下是一个示例,其中我们创建了一个名为 my-clock
的自定义元素,它使用 ES Modules 来导入和使用 Moment.js 库来显示当前时间:
-- -------------------- ---- ------- --------------------- ------- -------------- ------ ------ ---- ----------------------------------------------------- ----- ------- ------- ----------- - ------------- - -------- ---------------- - ----- ------------ - --------------------------- -- ----------- ---------- - ---------------------- - ------------------- - ------------- ---------------- - ----------------------- ------ - ---------------------- - -------------------------------- - ------- - ----- --- - --------- ----- --------- - ------------------------- -------------- - ---------- - - ---------------------------------------- --------- ---------
在这个示例中,我们创建了一个名为 MyClock
的类,它继承自 HTMLElement
。在构造函数中,我们初始化了一些变量,包括一个名为 _intervalId
的变量,用于存储 setInterval()
方法返回的 ID。我们还使用 import
关键字导入了 Moment.js 库,并在 connectedCallback()
方法中启动了一个定时器,每秒钟调用一次 _tick()
方法。在 _tick()
方法中,我们使用 Moment.js 库来获取当前时间,并将其格式化为指定的格式。最后,我们将格式化后的时间设置为元素的 innerHTML
。
结论
使用 Web Components,我们可以创建可复用的模块化 UI 组件,这些组件可以在任何网页中使用,而且不需要其他的框架或库的支持。在本文中,我们介绍了四个主要的技术:Custom Elements、Shadow DOM、HTML Templates 和 ES Modules。我们还提供了一些示例代码,以便读者更好地理解这些技术。如果您想深入学习 Web Components,请查看官方文档和示例代码库。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67403a1f5ade33eb72329e86