我正在尝试在不使用 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>
有什么建议吗?
不,
<slot>
是shadowDOM API的一部分
你可以伪造它,但由于没有shadowDOM,你必须将该内容存储在其他地方。
可能是您读取并解析(轻)DOM 内容的
<template>
。
这是 DOM 突变的 sh*load。
学习使用 ShadowDOM 样式可能会更容易: