0

我有两个最小的 HTMLElement:一个AppRoot和一个SubElement. 元素的 innerHTML 是通过 lit-htmlrenderhtml模板函数生成的。

AppRoot的 HTML 模板是 a div,其中包含两个段落:一个显示message属性的文本,另一个实例化 aSubElement并传递一个字符串。

SubElementHTML 模板只是传递的字符串。

我希望呈现的 HTML 看起来像这样:

<div>
    <p>AppRoot's message</p>
    <p>The string passed to SubElement</p>
</div>

但实际上它只是 SubElement 的渲染模板:

The string passed to SubElement

为什么 SubElement 的模板在渲染时会替换 AppRoot 的模板?我尝试过更改标签(用 div、段落括起来),但无济于事。

您可以在下面找到源代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./index.js" type="module"></script>
    <app-root></app-root>
</body>
</html>
import { render, html } from './node_modules/lit-html/lit-html.js';


class SubElement extends HTMLElement {

    constructor(message) {
        super();
        this.message = message;
    }

    connectedCallback() {
        this.innerHTML = render(this.template(), document.body);;
    }

    template() {
        return html`
            ${this.message}
        `;
    }

}

customElements.define('sub-element', SubElement);


class AppRoot extends HTMLElement {

    constructor() {
        super();
        this.message = "I am root!";
    }

    connectedCallback() {
        this.innerHTML = render(this.template(), document.body);
    }

    template() {
        return html`
            <div>
                <p>${this.message}</p>
                <p>${new SubElement("I am not root!")}</p>
            </div>
        `;
    }

}

customElements.define('app-root', AppRoot);
4

1 回答 1

1

的第二个参数render是应该在其中呈现模板的容器。每个组件当前都将模板结果呈现到文档正文并覆盖先前呈现的结果。

connectedCallback() {
    this.innerHTML = render(this.template(), document.body);
}

您应该考虑使用shadow DOM或在组件本身内渲染。

connectedCallback() {
    render(this.template(), this);
}
于 2021-07-26T13:11:49.167 回答