<template>标签是惰性DOM容器,不渲染不绑定,需JS手动克隆填值;Layui中HTML渲染失效因templet默认转义,须用{{= d.xxx }}启用原始模式。

HTML <template> 标签不是组件,只是惰性 DOM 片段容器
它不参与渲染、不触发样式计算、不建立布局上下文,也不会响应数据变化。你写 <template><div class="item">{{name}}</div></template>,浏览器根本不会解析 {{name}},更不会绑定或更新——那只是纯文本。所谓“复用”,必须靠 JS 手动克隆:content.cloneNode(true),再逐个填值,比如 row.querySelector('.name').textContent = item.name。直接往 <template> 里塞 innerHTML 就废了:它会立刻被当作普通 HTML 解析,失去“不激活”特性,后续克隆也无效。
Layui 表格中 HTML 渲染失效,本质是模板引擎未启用 raw 模式
常见现象是 <strong>加粗</strong> 被原样显示为字符串。Layui 的 templet 默认对内容做 HTML 转义,防止 XSS;要渲染 HTML,必须显式启用原始模式:
• 函数模板写法:templet: '<div><span class="tag">{{= d.status }}</span></div>'(注意双大括号语法)
• 脚本模板写法:用 <script type="text/html" id="statusTpl"><span class="tag">{{= d.status }}</span></script>,再配 templet: '#statusTpl'
别漏掉 {{= ... }} 中的等号,{{ ... }} 是纯文本插值,{{= ... }} 才输出未转义 HTML。
Vue/React 组件中直接插入 HTML,需绕过框架默认转义机制
Vue 的 v-html 和 React 的 dangerouslySetInnerHTML 都是显式开关,不是“自动识别 HTML”。Element Plus 的 Notification 组件同理:
• 必须传 dangerouslyUseHTMLString: true,否则 message: '<b>警告</b>' 就是字面量
• 即使开了开关,CSS 仍可能穿透或被重置:通知弹窗内部作用域有限,<span class="highlight"> 若没在组件样式中定义,就只靠全局样式生效,极易冲突
• 不推荐在 v-html 里放 <script> 或事件内联 handler(如 onclick),框架不会执行,还可能被 CSP 拦截
服务端模板(EJS/Nunjucks)输出 HTML 时,必须区分 <%= %> 和 <%- %>
这是最容易踩的坑:
• <%= ssrHtml %> 会对字符串做 HTML 转义,<div> 变成 <div>,页面直接显示标签源码<br>• 正确写法是 <code><%- ssrHtml %>(减号表示“不转义”),才能把服务端生成的合法 HTML 片段原样注入 layout
• 如果 SSR 输出的 HTML 包含 <html><body> 外层结构,客户端 hydration 一定失败——服务端只能吐 fragment,由模板引擎拼进预设的 <div id="root"></div> 容器里
• renderToString() 在 Node 环境中不执行 useEffect,所以动态拉取的数据必须提前注入 props,不能指望客户端“补请求”
立即学习“前端免费学习笔记(深入)”;
真正容易被忽略的是:<template> 和服务端模板都只解决“结构生成”,不解决“状态同步”;一旦你用 JS 克隆 <template> 填值,或用 EJS 渲染完发 HTML,后续任何交互都要自己手动绑定事件、维护状态,没有框架的响应式链路兜底。



















