【问题标题】:Contents of nested slots in web component are not visibleWeb 组件中嵌套插槽的内容不可见
【发布时间】:2022-09-16 15:59:43
【问题描述】:

我有一个应该接受任意元素来包装其内容的 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


    【解决方案1】:

    我可以看到您要执行的操作,即您希望影子 DOM 包含

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

    但不幸的是,这是不可能通过&lt;slot&gt; 元素实现的。

    Per the HTML spec

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

    这意味着整个&lt;slot name="as"&gt; 元素及其内容被&lt;button slot="as"&gt; 元素替换,&lt;slot&gt; 的内容被丢弃。

    这样做的原因是浏览器无法知道如何将后代添加到提供的替换中,因为可能已经为插槽替换提供了 void 元素(例如&lt;img&gt;),或者深度嵌套的结构。

    【讨论】:

      【解决方案2】:

      您不能嵌套 &lt;slot&gt; 元素有点就像你不能嵌套 &lt;li&gt; 元素一样。

      就像&lt;li&gt; 一样,您可以在其中添加一个额外的&lt;ul&gt; 容器,
      您必须添加一个额外的 Web 组件传下去插槽内容:

      更新:添加了exportpartspart 以显示如何全球的CSS 样式嵌套的shadowDOM

      <script>
      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>`);
        }
      });
      </script>
      
      <style>
        *::part(title){
          color:green;
        }
      </style>
      <el-one>
        <b slot="ONE">Fantastic!</b>
      </el-one>
      
      <script>
      customElements.define('el-two', class extends MyCoolBaseClass {
        constructor() {
          super(`Hello <slot   name="TWO"   ></slot> <b part="title">Web Components</b>`);
        }
      });
      </script>

      【讨论】:

      • 这很棒!我最终偶然发现了类似的东西,但您的回答清楚地说明了它为什么有效。我最终放弃了这种方法,因为虽然这种方法有效,但在基类上设置的样式不再影响填充在中间组件中的内容。
      • 见 CSS ::part
      • 我在示例中添加了exportpartspart,因此请展示如何'出口' 嵌套的 shadowDOM 内容全局 CSS造型
      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2021-07-08
      • 2021-10-16
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      相关资源
      最近更新 更多