搜索

首页  >  问答  >  正文

在 WebComponents 中使用槽而不使用 Shadow DOM

我正在尝试在不使用 ShadowDOM 的情况下构建一个 WebComponent - 到目前为止它基本上只是工作,但现在我想构建一个包装其他组件的组件,就像使用 Angular 的 @ViewChild / @ViewChildren 一样。 (我在这里用来渲染的库是uhtml,类似于lit-html)

export class Dropdown extends HTMLElement {

    private open: boolean = false;

    static observedAttributes = ["open"]

    constructor() {
        super();
    }

    attributeChangedCallback(name: string, oldValue: string, newValue: string) {
        switch (name) {
            case "open":
                this.open = Boolean(newValue);
                break;
        }
        this.display()
    }

    connectedCallback() {
        this.display()
    }

    display = () => {
        render(this, html`
            <div>
                <slot name="item">

                </slot>
            </div>
        `)
    }

    static register = () => customElements.define("my-dropdown", Dropdown)

}

如果我现在使用这个组件

Dropdown.register();


render(document.body, html`
    <my-dropdown open="true">
        <strong slot="item">test</strong>
    </my-dropdown>

`)

我期待看到

<my-dropdown>
    <div>
        <strong>test</test>
    </div>
</my-dropdown>

但是插槽部分不起作用。

如果我切换到 ShadowDOM,它就可以工作,但现在我必须处理 ShadowDOM 的沙箱,而我不想这样做。

constructor() {
    super();
    this.attachShadow({mode: "open"})
}
display = () => {
    render(this.shadowRoot as Node, html`

是否可以在没有 ShadowDOM 的情况下使插槽工作? 如果没有,是否有不同的方法来获取组件内部定义的内容并在显示内部使用它?

<my-component>
    <div>some content here</div>
</my-component>

应呈现为

<my-component>
    <header>
        random header
    </header>
    <section>
        <!-- my custom content -->
        <div>some content here</div>
    </section>
</my-component>

有什么建议吗?

P粉936568533P粉936568533244 天前406

全部回复(1)我来回复

  • P粉696605833

    P粉6966058332024-03-29 12:12:36

    不,<slot> 是 ShadowDOM API 的一部分

    你可以伪造它,但由于没有shadowDOM,你必须将该内容存储在其他地方。
    可能是您读取并解析(轻)DOM 内容的 <template>

    这是一堆 DOM 突变。
    学习使用 ShadowDOM 样式可能会更容易:

    • CSS 属性
    • 可继承的样式
    • ::部分
    • 可构造的样式表

    回复
    0
  • 取消回复