template标签不渲染、不执行、不绑定、不解析,内容仅存于content属性的documentfragment中;必须用clonenode(true)克隆后操作,填值用textcontent/value,禁用innerhtml以防xss和事件丢失。

不会渲染,也不会执行、绑定或解析任何内容。 template 标签天生“离线”,浏览器解析 HTML 时直接跳过其内部所有节点,不建 DOM、不触发脚本、不加载样式、不计算布局——它只是个静态结构仓库。
为什么 template.innerHTML 总是空字符串
因为真实内容被封装在 content 属性指向的 DocumentFragment 中,不是普通文本节点。你看到的 HTML 字符串只是源码,浏览器根本不把它当 DOM 处理。
-
template.innerHTML永远返回"",别试 -
template.textContent能读到所有文本(含换行缩进),但无法操作结构、不能查子元素 - 唯一合法入口是
template.content.cloneNode(true),否则后续所有操作都无效
克隆时漏掉 true 参数会丢什么
不加 true 是浅克隆,只复制顶层节点,子树全引用原 DocumentFragment 中的内容。后果很实际:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 表单控件(
input、select)的当前值、焦点、光标位置全部丢失 - 已绑定的事件监听器(比如模板里写好的
onclick)不会复制过去 - 后续对克隆体调用
querySelector可能找不到子元素,或返回 null
填值时为什么不能用 innerHTML
用 innerHTML 往克隆节点里塞字符串,等于主动打开两个口子:
-
XSS 风险:用户输入的
<script>alert(1)</script>会被执行 -
破坏已有行为:哪怕模板里有个带
onclick的按钮,innerHTML一赋值,这个监听器就没了 - 纯文本内容一律用
textContent;表单控件一律用value属性赋值
真正容易被忽略的是:克隆后的节点和原始 template 完全解耦,但它的 data- 属性能保留,而 slot、bind、{{}} 这类东西根本不会激活——它不是 Web Components,也不是 Vue 模板,就是一段被 JS 拿来手动摆弄的 HTML 片段。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










