<template>里的内容默认不渲染,因为它是惰性容器,子节点解析时不加入DOM、不执行脚本、不加载资源,与display:none等视觉隐藏有本质区别。

为什么 <template> 里的内容默认不渲染
<template> 是浏览器原生支持的“惰性容器”,它的子节点在解析时不会被添加到 DOM 树,也不会触发脚本执行、图片加载或样式计算。这和 <script type="text/template"> 或隐藏的 <div style="display:none"> 有本质区别:前者是语义化模板,后者只是视觉隐藏但已参与 DOM 构建和资源加载。
常见误操作是直接写 <template><div id="item">xxx</div></template> 然后试图用 document.getElementById("item") 获取——它永远找不到,因为里面的内容根本没进 DOM。
如何安全提取并插入 <template> 内容
必须通过 .content 属性访问其文档片段(DocumentFragment),再用 cloneNode(true) 复制后插入目标位置。直接 appendChild(template) 会移动原始模板,导致后续调用失效。
- 错误写法:
parent.appendChild(template)—— 模板被移走,第二次调用就空了 - 正确写法:
parent.appendChild(template.content.cloneNode(true)) - 若需动态填充,先克隆,再遍历
.content的子节点操作(比如改textContent或设dataset) - 注意:
.content不是HTMLCollection,不能用[0]索引,要用.firstElementChild或.querySelector
在 Vue/React 中还该用 <template> 吗
一般不该。Vue 的 <template> 是编译时语法糖,和 HTML 原生 <template> 无关;React 完全不识别它。强行混用会导致:
立即学习“前端免费学习笔记(深入)”;
- Vue 单文件组件里写原生
<template>标签 → 被 Vue 编译器忽略或报错 - React JSX 中写
<template>→ React 渲染为真实 DOM 节点,但内容仍不显示,且无法用 ref 访问.content - 真正需要跨框架复用模板时,应导出为字符串或函数,而非依赖 HTML 解析
兼容性与容易被忽略的细节
<template> 在 IE 中完全不支持,Edge 13+、Chrome 26+、Firefox 22+ 支持良好。但有几个硬伤常被忽略:
-
<template>不能作为<table>的直接子元素(如<table><template>...</template></table>)→ 浏览器会自动将其提升到<table>外,破坏结构 - 模板内写
<style>或<script>标签 → 不会执行,也不会注入样式作用域,纯静态文本 - 服务端渲染(SSR)时,
<template>会被当作普通标签输出,客户端 JS 必须主动接管,否则就是一堆不可见的空壳
最稳妥的做法:只用它存纯结构化的 HTML 片段,所有逻辑、数据绑定、样式隔离都交给 JS 控制,别指望它自动“活”起来。


















