You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用lit-html渲染嵌套自定义HTMLElement时子模板覆盖父模板问题

问题原因分析
  • lit-html render API 用法错误:render(template, container) 函数的作用是直接将模板渲染到第二个参数指定的容器节点中,本身不会返回可用于innerHTML赋值的HTML字符串。你两次调用render都传入了document.body作为容器,后执行的SubElement渲染会直接覆盖掉之前AppRoot渲染到body的内容,这是内容被替换的核心原因。
  • 自定义元素用法不符合规范:浏览器实例化自定义元素时不会调用带自定义参数的构造函数,你直接new SubElement("I am not root!")塞进lit模板的写法不符合规范,正确用法是在模板中直接编写自定义元素标签<sub-element>,通过属性/插槽传递参数。
  • 模板中标签转义错误:AppRoot的template方法中写的&lt;div&gt;是转义后的字符,会被当成纯文本渲染,而非实际的DOM节点。
修复后可运行代码

HTML代码

<!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>

JS代码

import { render, html } from './node_modules/lit-html/lit-html.js';

class SubElement extends HTMLElement {
    static get observedAttributes() {
        return ['message'];
    }
    constructor() {
        super();
        this.message = '';
    }
    attributeChangedCallback(name, oldValue, newValue) {
        if(name === 'message') {
            this.message = newValue;
            render(this.template(), this);
        }
    }
    connectedCallback() {
        render(this.template(), this);
    }
    template() {
        return html`${this.message}`;
    }
}
customElements.define('sub-element', SubElement);

class AppRoot extends HTMLElement {
    constructor() {
        super();
        this.message = "I am root!";
    }
    connectedCallback() {
        render(this.template(), this);
    }
    template() {
        return html`
            <div>
                <p>${this.message}</p>
                <p><sub-element message="I am not root!"></sub-element></p>
            </div>
        `;
    }
}
customElements.define('app-root', AppRoot);
修复说明
  • 所有render调用的第二个参数改为自定义元素自身this,仅在当前元素内部渲染内容,不会覆盖全局body的内容
  • 移除错误的innerHTML = render()写法,render本身会完成DOM插入操作
  • 自定义元素遵循规范实现,通过message属性传递参数,监听属性变化自动更新
  • 模板中直接编写原生DOM标签和自定义元素标签,无需转义

内容的提问来源于stack exchange,提问作者GeckStar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 11:06:04