exportparts 是 web components 中 shadow dom 的 html 属性,用于显式声明内部子元素的 part 名称别名,使外部样式可通过 ::part() 安全穿透定制 ui;仅在 open mode 下有效,需在宿主元素上以空格分隔的“partname:exportedname”格式声明。

exportparts 是什么,它能解决什么问题
exportparts 是 Web Components 中 shadow DOM 的一个属性,用于显式声明「哪些内部子元素的 part 名称可以被外部样式穿透控制」。它不传递样式本身,而是开放接口——让父容器能用 ::part(...) 选择器安全地定制嵌套组件的局部 UI 元素(比如按钮图标、输入框边框),而无需打破 shadow boundary 或依赖 slot 投影结构。
怎么在自定义元素中正确声明 exportparts
必须在宿主元素(即自定义标签)上设置 exportparts 属性,值为以空格分隔的 partname=exportedname 映射对。注意不是 JS 属性,是 HTML attribute:
<my-input exportparts="input:field icon:indicator"></my-input>
其中 input 和 icon 是组件内部子元素的 part 值(如 <input part="input">),field 和 indicator 是对外暴露的别名。外部样式只能通过 ::part(field) 影响该 input,不能直接写 ::part(input)。
- 别名(
exportedname)必须合法 CSS 标识符(不能含空格、点、冒号等) - 同一个
part可多次映射,但重复别名会覆盖前一个 - 未出现在
exportparts列表中的part,外部无法访问,即使写了::part(unknown)也无效
外部样式如何调用 ::part() 并避开常见错误
使用 ::part() 时,选择器必须作用于宿主元素本身,且只接受单层匹配:
my-input::part(field) { border-color: blue; }
以下写法全部无效:
-
my-input ::part(field)(中间有空格 → 变成后代选择器,失效) -
my-input::part(field) input(试图再选内部元素 → 不支持嵌套) -
my-input::part(field)::before(伪元素链式调用 → 不支持) -
my-input:not([disabled])::part(field)(带条件伪类 → 大部分浏览器暂不支持复合逻辑)
目前仅 Chromium 系(Chrome/Edge 105+、Safari 16.4+)稳定支持;Firefox 尚未实现,需降级 fallback。
和 :export / CSS @layer / slot 比较时的关键差异
exportparts 不是 CSS 模块导出机制,也不涉及样式层叠顺序或内容投影逻辑:
- 它和
:export(CSS Modules)无关,后者是构建时静态导出变量,exportparts是运行时 DOM 接口 - 不改变
@layer的层叠优先级,::part()样式默认权重等同于普通类选择器 - 不同于
slot,它不移动 DOM 节点,只是开放样式钩子;哪怕子元素被slot投影进来,只要它有part且被exportparts显式导出,就能被外部控制
真正容易被忽略的是:如果组件内部用 attachShadow({mode: 'closed'}),exportparts 就完全失效——它只在 open mode 下起作用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











