浏览器解析 时跳过其内容,不渲染、不执行脚本、不加载资源,dom 中不可见;需用 document.importnode() 安全克隆并填充数据,通过 data-bind 属性绑定,避免 id 重复和内存泄漏。

为什么不能直接当组件用
浏览器解析到 <template></template> 时会跳过其内容,不渲染、不执行内联 <script></script>、不加载图片或字体,DOM 中完全不可见。你写一个 <template id="card"><div>{{title}}</div></template>,页面不会显示任何东西——这不是 bug,是规范行为。
常见误操作包括:
• 把它当 Vue 的 <template></template> 直接写插值语法,结果空白
• 用 innerHTML = tmpl.innerHTML 注入,导致 <input checked> 状态丢失
• 用 cloneNode(true) 复制后插入,但其中的 <script></script> 不执行、<style></style> 不生效
如何安全克隆并填充内容
核心是用 document.importNode() 替代 cloneNode(),它能保留表单状态、正确处理 <select></select> 选项,并兼容 Shadow DOM。
- 获取模板:
const tmpl = document.getElementById('card-template') - 克隆内容:
const fragment = document.importNode(tmpl.content, true) - 查找绑定点:
fragment.querySelectorAll('[data-bind]'),例如data-bind="title" - 填充数据:对文本节点用
node.textContent = data.title;对 HTML 内容用node.innerHTML = data.content(注意 XSS) - 挂载:
container.appendChild(fragment),别用innerHTML覆盖已有结构
怎么让支持属性传参和复用
纯 <template></template> 没有属性、生命周期或响应式机制,“传参”本质是调用 JS 工厂函数时传入对象,再映射到 DOM 节点。
- 模板中用语义化
data-bind属性,比如data-bind="author-name",比class="author"更易维护 - 工厂函数返回
DocumentFragment,而非字符串,避免重复解析 - 如需更新,缓存首次生成的节点,后续只改
textContent或dataset值,不重新克隆 - 禁止在模板里硬编码
id(如id="card-1"),否则多次使用会导致 ID 重复,破坏 CSS 选择器和getElementById
和 Web Components 的边界在哪
<template></template> 是轻量级原生方案,但它不提供封装性、无样式隔离、无事件自动绑定、无属性监听——这些都得靠 JS 手动补全。它适合静态内容或低频交互场景(如卡片列表、弹窗骨架),不适合复杂交互组件。
真正容易被忽略的是资源生命周期:哪怕你用 <template></template> + JS 实现了“组件”,一旦该 DOM 被移除,若没手动清理 IntersectionObserver、定时器或事件监听器,内存泄漏就藏在那儿,比 jQuery 时代更难定位。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











