配了三年 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+ 均已支持,生产可用。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 18 阅读