配了三年 Shadow DOM,每次想用手动槽位分配都要靠 JS——今天一个 HTML 属性全包了
写过 Shadow DOM 的都知道,<template shadowrootmode="open"> 让你不用 JS 就能声明影子根——但有一件事例外:手动槽位分配(manual slot assignment)。
以前想用手动槽位,唯一的办法是:
this.attachShadow({ mode: open, slotAssignment: manual });
这一行 JS,破坏了”声明式 Shadow DOM”的纯粹性。很多组件库想用 <template> 声明影子根又需要手动分配槽位,结果要么放弃声明式、要么自己绕路。
Chrome 151 把这个口堵上了——<template> 新增 shadowrootslotassignment 属性:
<template id="my-component" shadowrootmode="open" shadowrootslotassignment="manual">
<slot></slot>
</template>
shadowrootslotassignment="manual" 等价于 attachShadow({ slotAssignment: manual }),但完全不需要 JS。Firefox 151 和 Safari 27 TP 已经先行支持,Chrome 151 这次完成三端对齐,跨浏览器兼容风险已经很低。
有什么用?当你需要根据元素的 id 或其他属性动态选择要插入哪个槽位时,手动分配比命名匹配更灵活。比如一个选项卡组件,切换面板不是靠 slot="content" 匹配,而是按 data-panel-id 指定——这在声明式 Shadow DOM 里以前根本做不到。
怎么用:
<template id="tab-panel" shadowrootmode="open" shadowrootslotassignment="manual">
<slot></slot>
</template>
<script>
const template = document.getElementById(tab-panel);
const shadow = template.attachShadow({ mode: open });
// 现在用 slot.assign(element) 手动分配
slot.assign(panels[activeIndex]);
</script>
需要注意:shadowrootslotassignment 只在声明式影子根(有 shadowrootmode 的 <template>)上有意义;用 JS attachShadow() 创建的影子根,slotAssignment 只能在 JS 里指定。这个属性不影响默认行为(默认是 "named" 自动分配),是纯增量改动,已有代码不受影响。
下一步:如果你的 Web Components 用到了手动槽位分配,现在可以把 attachShadow({ slotAssignment: manual }) 删掉,改成 <template shadowrootslotassignment="manual">。Firefox 151+ 和 Safari 27+ 均已支持,生产可用。
评论区
登录后可评论。