本身无响应能力,需配合custom elements的observedattributes和attributechangedcallback手动触发重渲染,克隆后注入数据并重绑事件,且须按数据类型安全处理内容。

HTML <template></template> 本身不带响应能力,它只是个“冷模板”——你得手动把它热起来。所谓“自动响应”,其实是靠配合 Custom Elements 生命周期 + 属性监听 + 状态驱动渲染来实现的,不是模板自己动,是你写清楚了它才动。
为什么直接用 <template></template> 不会自动更新
<template></template> 是惰性节点,内容不会被解析、不执行脚本、不加载资源,也不会响应属性变化。它就像一张未展开的设计图,克隆后才变成真实 DOM,而克隆时机、数据注入逻辑、重渲染触发点,全得你自己定。
- 常见错误:把模板写在页面里,然后只靠
document.querySelector('template').content一次克隆就完事——改了属性,DOM 不变 - 正确做法:每次属性或状态变更后,重新克隆模板 + 填充数据 + 替换 shadowRoot 内容(或局部 patch)
- 别在
constructor()或connectedCallback()里只做一次克隆并缓存 DocumentFragment——它不会随数据变而自动更新
如何让模板响应 HTML 属性变更
必须显式声明监听项,并在 attributeChangedCallback() 中触发重渲染。浏览器不会因为你用了 <template></template> 就自动帮你绑定属性和 DOM。
- 在类上定义
static get observedAttributes() { return ['title', 'content', 'disabled']; } -
attributeChangedCallback(attrName, oldValue, newValue)中,仅当newValue !== oldValue才调用this._render() - 若属性值是对象(如
params='{"id":123}'),需用JSON.parse(this.getAttribute('params'))解析,不能直接当对象用 - 避免对布尔属性(如
disabled)用===比较字符串"true",应统一转为布尔:this.disabled = this.hasAttribute('disabled')
模板克隆后怎么安全注入动态数据
直接 innerHTML = 有 XSS 风险,且无法复用事件绑定;硬写 textContent 又没法渲染 HTML 片段。得按数据类型分策略处理。
- 纯文本内容(如标题、描述):用
element.textContent = value,最安全 - 允许 HTML 的字段(如富文本摘要):用
element.innerHTML = DOMPurify.sanitize(value)(需引入 DOMPurify),别裸奔 - 需要绑定事件的子元素(如按钮、输入框):在克隆后立即用
this.shadowRoot.querySelector('.btn').addEventListener('click', ...),别指望模板里写onclick能生效 - 避免用
data-bind自定义属性做模板占位符——没框架时,得自己遍历节点解析,容易漏、难维护;更推荐在_render()中用字符串插值或document.createElement构建
性能陷阱:别每次属性变都全量克隆模板
频繁调用 template.content.cloneNode(true) 开销不小,尤其模板复杂或更新密集(如输入框实时反馈)。该优化的地方得优化。
- 对静态结构部分(如容器外壳),可只克隆一次,缓存在实例上:
this._tplClone = template.content.cloneNode(true) - 对动态区域(如列表项),用
document.createElement+appendChild局部更新,比整块替换快 - 输入类交互(如搜索框),用
requestAnimationFrame节流_render()调用,避免 layout thrashing - 注意:
cloneNode(true)不会复制已绑定的事件监听器,所有事件都得重绑——这是最容易漏掉的一环
真正难的不是让模板“动起来”,而是决定什么时候动、动多少、动完是否干净。比如 connectedCallback 和 attributeChangedCallback 都可能被高频触发,但 UI 更新未必需要一一对应。边界模糊的地方,往往就是 bug 存活的温床。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











