Web Components 开发中的 shadow dom 坑

· 约 7 分钟读完

Web Components 开发中的 Shadow DOM 坑

在当前前端开发技术中,Web Components 已经成为开发高度复用的组件的重要手段。而 Shadow DOM 是其中最重要的一部分,它能使 Web Components 实现真正的封装以及样式隔离。但是,并不是每个人都能够顺利地在开发过程中使用好 Shadow DOM,下面我们将会深入探讨在 Web Components 开发中遇到的 Shadow DOM 坑以及如何避免它们。

一、Shadow DOM 基本概念与实现方法

Shadow DOM 是一个独立于主文档 DOM 树的一组 DOM 树,这个组件内部的样式和脚本代码都只在组件内部生效,不会影响页面的其他部分。其实现方式通常包括两部分:

  1. 在组件内部创建 Shadow DOM,可以使用 createElement 方法创建元素,在元素上设置 shadowRoot 属性即可创建 Shadow DOM。如下所示:
  1. 使用 CSS 规则在 Shadow DOM 中设置样式。Shadow DOM 中的样式不会对页面中其他部分生效。如下所示:

二、Shadow DOM 坑

  1. 无法继承父元素样式

因为 Shadow DOM 是独立于主文档 DOM 树的,所以它无法继承主文档中元素的样式,例如:

即使页面中存在样式 div { color: red; },但是在 Shadow DOM 中的 div 元素却不会继承该样式,必须在 Shadow DOM 中重新定义样式。

  1. 需要使用 /deep/ 或者 ::slotted

如果 Shadow DOM 中嵌套了组件,并且这个组件也使用了 Shadow DOM,则不能直接在这个组件内使用样式。需要使用 /deep/ 或者 ::slotted 来访问 Shadow DOM 中的元素。

  1. slot 不能嵌套

slot 是自定义元素与其 Shadow DOM 之间的通信机制,允许父组件向子组件插入内容。但是,slot 不允许嵌套。

  1. 禁止给 Shadow DOM 根节点添加事件

Shadow DOM 根节点与主文档根节点不是同一个节点,因此禁止直接在 Shadow DOM 根节点上添加事件。如果需要添加事件,可以尝试使用宿主元素来代理。

三、如何避免 Shadow DOM 坑

  1. 使用 ::part 和 ::theme

::part 和 ::theme 是 Shadow DOM 规范中两个比较新的伪类,主要作用是用来给组件的内部元素打标签或者添加 CSS 主题。通过使用 ::part 和 ::theme,可以避免使用 /deep/ 或者 ::slotted 来解决 CSS 样式的问题,使得组件更加清晰、易于维护。

  1. 建议使用 slot 和组件通信

在 Web Components 开发中,建议使用 slot 作为组件通信的主要方式,而不要使用直接在 Shadow DOM 根节点上添加事件的方式。同时,为了避免子组件在 slot 之中使用 slot,可以使用 HTML Template 元素,例如:

这样,就可以避免 slot 的嵌套问题。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cf91ece46428fe9eb1ecbc