Web 组件中嵌套插槽的内容不可见

问题描述 投票:0回答:2

我有一个 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

javascript web-component lit
2个回答
1
投票

你不能嵌套

<slot>
元素有点就像你不能嵌套
<li>
元素一样。

就像

<li>
一样,你添加一个额外的
<ul>
容器,
您必须添加一个额外的 Web 组件,它传递 插槽内容:

更新:添加了

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>


1
投票

我可以看到你想做什么,那就是你想让影子 DOM 包含

<button>
  <div>Prefix</div>
  Default
</button>

但不幸的是,通过

<slot>
元素这是不可能的。

根据 HTML 规范

槽元素表示其分配的节点(如果有),否则表示其内容。

这意味着整个

<slot name="as">
元素及其内容被
<button slot="as">
元素替换,而
<slot>
的内容被丢弃。

这样做的原因是浏览器无法知道如何将后代添加到提供的替换中,因为空元素(例如

<img>
),或者可以为插槽替换提供深层嵌套结构。

© www.soinside.com 2019 - 2024. All rights reserved.