我有一个 web 组件,它应该接受一个任意元素来包装它的内容。虽然我可以在 Chrome 开发工具中看到插槽被正确分配,但 DOM 中什么也没有出现。有人以前见过这个问题吗?
class ExampleParent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<slot name="as">
<slot name="prefix"></slot>
<slot></slot>
</slot>
`;
}
}
customElements.define('example-parent', ExampleParent);
<example-parent
style="
min-width: 100px;
height: 40px;
border: 1px solid red;
display: inline-block;
"
>
<button slot="as"></button>
<div slot="prefix">Prefix slot</div>
Default
</example-parent>
https://stackblitz.com/edit/nested-slots-ahtfyf?file=index.html
你不能嵌套
<slot>
元素有点就像你不能嵌套<li>
元素一样。
就像
<li>
一样,你添加一个额外的<ul>
容器,更新:添加了
exportparts
和 part
来展示如何 global CSS 样式 nested shadowDOMs
class MyCoolBaseClass extends HTMLElement {
constructor( html ) {
let style = "<style>:host{display:inline-block;background:pink}</style>";
super().attachShadow({mode:'open'}).innerHTML = style + html;
}
}
customElements.define('el-one', class extends MyCoolBaseClass {
constructor() {
super(`<el-two exportparts="title"><slot name="ONE" slot="TWO"></slot></el-two>`);
}
});
customElements.define('el-two', class extends MyCoolBaseClass {
constructor() {
super(`Hello <slot name="TWO"></slot> <b part="title">Web Components</b>`);
}
});
el-one { display:block; font-size:21px }
el-one::part(title){ color:green }
<el-one><b slot="ONE">Fantastic!</b></el-one>
<el-one><b slot="ONE">Great!</b></el-one>
我可以看到你想做什么,那就是你想让影子 DOM 包含
<button>
<div>Prefix</div>
Default
</button>
但不幸的是,通过
<slot>
元素这是不可能的。
槽元素表示其分配的节点(如果有),否则表示其内容。
这意味着整个
<slot name="as">
元素及其内容被<button slot="as">
元素替换,而<slot>
的内容被丢弃。
这样做的原因是浏览器无法知道如何将后代添加到提供的替换中,因为空元素(例如
<img>
),或者可以为插槽替换提供深层嵌套结构。