编辑--我在这个问题中遗漏了一些细节,但假设这两个元素已经定义了。另外,在实际问题中,DOM树更大,子组件是将开槽到父组件中。找到子组件没有问题。
我有两个web组件:Parent和Child。
我可以在标记中使用如下这些组件:
<parent-element>
<child-element></child-element>
</parent-element>Child组件具有我想向父组件公开的逻辑。
class Child extends HTMLElement {
constructor() {
...
}
publicMethod() {
console.log('call me from the parent component');
}
}理想情况下,我希望像这样从父方法调用子方法:
class Parent extends HTMLElement {
constructor() {
...
}
someTrigger() {
const child = this.shadowRoot.querySelector('child-element');
child.publicMethod();
}
}但是,这是行不通的,因为child是一个HTMLElement,因为querySelector() API返回的是一个HTMLElement,而不是web组件实例。
有办法以类似的方式获得组件的实例吗?我希望能够遍历Parent组件阴影树来找到特定的组件实例。
发布于 2022-03-05 11:52:16
小心whenDefined;
它告诉您Web组件是定义的,而不是当在DOM中解析时:
只要您将<child-element>保存在lightDOM中,<slot>和shadowDOM就与它们无关。
.as-console-wrapper {max-height:100%!important;top:0;zoom:.88}
.as-console-row:nth-child(n-6) {background:#0057B7!important;color:#FFD500!important}
.as-console-row:nth-child(n+6) {background:#FFD500!important;color:#0057B7!important}
.as-console-row-code{padding:0!important}<script>
console.clear();
class Component extends HTMLElement {
constructor() {
super();
console.log(this.nodeName, "constructor")
}
connectedCallback(){
console.log("connectedCallback", this.nodeName, this.children.length, "children");
}
}
customElements.define("child-component", class extends Component {
foo() {
console.log("Executed <child-element>.foo()");
}
});
customElements.define("parent-component", class extends Component {
connectedCallback() {
super.connectedCallback();
customElements.whenDefined('child-component')
.then(() => console.log("Promise resolved, <child-component> IS defined!"));
setTimeout(() => { // wait till lightDOM is parsed
console.log("After setTimeout",this.nodeName,"has", this.children.length, "children");
this.querySelectorAll("child-component").forEach(child => child.foo());
})
}
})
</script>
<parent-component>
<child-component></child-component>
<child-component></child-component>
</parent-component>
https://stackoverflow.com/questions/71358910
复制相似问题