Shadow DOM 的 mode 属性在 attachShadow 时一次性指定且不可更改:open 模式允许外部通过 .shadowRoot 访问和调试影子树,closed 模式则始终返回 null 以隐藏实现细节但不提升安全性;两者均阻止外部 CSS 穿透,仅支持 :host 和 ::slotted 进行有限样式控制。

Shadow DOM 的 mode 属性决定影子根是否对外部 JavaScript 可见,它不是开关式配置,而是创建时一次性指定、不可更改的选项。关键在于:选对 mode,才能匹配调试需求与封装强度。
open 模式:默认推荐,调试友好
使用 { mode: 'open' } 时,宿主元素的 .shadowRoot 属性会返回一个可读写的 ShadowRoot 对象,开发者能直接查询结构、修改样式、监听内部事件。
- DevTools 中启用“Show user agent shadow DOM”后,可展开查看完整影子树
- 适合绝大多数自定义组件,比如按钮、输入框、卡片等需要集成和调试的场景
- 示例:
const root = host.attachShadow({ mode: 'open' }); root.innerHTML = '内容
';
closed 模式:强封装,但放弃直接访问
{ mode: 'closed' } 会让 .shadowRoot 始终返回 null,外部脚本无法获取影子根,也无法遍历或操作内部节点。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 不等于“更安全”,只是隐藏实现细节;真正的安全性仍需靠逻辑控制和 API 设计
- 仅适用于极少数强审计要求的场景(如金融级 UI 组件),且必须配套暴露明确方法(如
getInternalState())供可控交互 - 调试困难:无法在 DevTools 中查看结构,只能依赖组件自身日志或暴露的调试接口
mode 必须在 attachShadow 调用时传入
不能事后修改,也不能通过属性或方法切换。一旦挂载,mode 就固定了。
- 错误写法:
host.attachShadow({}); host.shadowRoot.mode = 'closed';—— 无效 - 正确做法:只在首次调用
attachShadow时指定,例如host.attachShadow({ mode: 'open' }) - 若已存在 shadowRoot,再次调用会抛出
InvalidStateError
:host 是唯一合法的跨边界样式入口
无论 open 还是 closed,外部 CSS 都无法穿透影子边界影响内部元素。但你可以用 :host 在影子内部为宿主元素设置样式,实现“组件对外观的响应”。
- 例如:
:host([disabled]) { opacity: 0.5; }让宿主在 disabled 属性存在时变灰 -
::slotted(*)可样式化通过 slot 插入的外部内容,但仅限继承性属性(如 color、font)生效 - 布局类属性(如 display、margin)不会从外部继承,必须在影子内显式定义










