标签不会被渲染,因为它是浏览器原生的惰性容器,内容在解析时被剥离出渲染树,不生成dom节点、不执行脚本、不加载资源。

template 标签为什么不会被渲染
<template></template> 是浏览器原生支持的“惰性容器”,它的内容在 DOM 解析阶段就被剥离出渲染树,既不显示、不执行脚本、也不触发资源加载(比如 <img src> 不会发起请求)。这和 <script type="text/template"></script> 或 display: none 有本质区别:后者仍存在于渲染树中,只是视觉隐藏或被绕过执行。
直接 innerHTML 赋值到 template 内部是否安全
安全,但要注意时机和来源。只要内容来自可信字符串或已转义的变量,template.innerHTML = "<div>{{name}}</div>" 没问题;但若拼接用户输入,必须提前做 HTML 实体转义(例如用 textContent 创建文本节点,或调用 DOMPurify.sanitize()),否则可能触发 XSS。另外,<template></template> 不支持直接写内联事件(如 onclick),即便写了也不会绑定——这是它防 XSS 的一层保障。
如何正确 clone 并插入 template 内容
不能直接 appendChild(template),因为 <template></template> 元素本身不可渲染;必须操作它的 content 属性。常见错误是忘了 cloneNode(true),导致多次使用时节点被移动而非复制:
const tmpl = document.querySelector('template');
const instance = tmpl.content.cloneNode(true); // 必须 true,否则只克隆空 DocumentFragment
document.body.appendChild(instance);
-
tmpl.content返回的是DocumentFragment,不是普通元素,不能直接设置id或className - 如果模板里含
<slot></slot>,需配合自定义元素使用,单独用<template></template>时<slot></slot>会被忽略 - 动态生成的
<style></style>或<script></script>在content中不会自动执行,需手动调用appendChild后再eval或insertRule
与 hidden / display:none 的关键区别在哪
核心就两点:hidden 和 display: none 只控制可见性,元素仍在 DOM 树中、占用布局空间(除非用 visibility: hidden)、绑定事件照常触发;而 <template></template> 的内容压根不在活动 DOM 中,连 querySelector 都搜不到它内部的节点——除非先 cloneNode 并挂载。这意味着:它不参与 CSS 选择器匹配、不触发重排重绘、也不消耗渲染性能。
如果你只是临时藏一个区块等后续 JS 控制显隐,用 hidden 更轻量;但要做高频模板复用(比如列表项渲染、模态框预制),<template></template> 才是语义正确且性能干净的选择。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











