templet 必须返回字符串,不可返回 jQuery 对象或 DOM 节点;需用 layui.laytpl.escape() 转义用户内容防 XSS;事件应委托绑定,控件状态变更后须手动同步至 table.cache。
templet 必须返回字符串,不能返回 jQuery 对象或 DOM 节点
常见错误是写成 templet: function(d) { return layui.$('<button>' + d.status + '</button>'); }——这会导致单元格空白或报错。layui 表格只接受字符串作为渲染内容,内部用 innerhtml 插入。返回 jquery 对象或原生 document.createelement 结果,表格无法识别。
正确做法是拼出完整 HTML 字符串:
templet: function(d) { return '<button class="layui-btn layui-btn-xs" data-id="' + d.id + '">' + (d.status === 1 ? '启用' : '禁用') + '</button>'; }- 确保所有引号嵌套合法:外层单引号,HTML 属性用双引号
- 若字段值含双引号(如
d.name === 'Alice "Dev"'),直接拼接会破坏 HTML 结构,此时必须用layui.laytpl.escape(d.name)过滤
绑定事件不能靠 onclick 写死,得用事件委托
在 templet 里写 onclick="handleClick()" 看似简单,但实际不可靠:表格重载、分页、排序后 DOM 重建,内联事件会丢失;且无法访问当前行数据 d。
推荐在 table.render 的 done 回调里统一绑定:
- 用
layui.$(elem).on('click', 'td[data-field="status"] button', handler),利用事件冒泡捕获 - 通过
$(this).closest('tr').data('index')拿到行索引,再查table.cache[<code>id][index] 获取原始数据 - 避免给每行按钮单独绑定,防止内存泄漏和重复绑定
自定义 HTML 元素要兼容 Layui 表格盒模型
直接塞一个 <input type="range"> 或 <select></select> 进去,常出现高度塌陷、文字错位、点击区域偏移——因为 Layui 单元格默认有 padding 和 line-height,而原生控件没做适配。
解决方法是包裹一层带样式的容器:
- 加
class="layui-table-cell"保持默认对齐和垂直居中 - 对
input[type="range"]需额外设width: 100%; margin: 4px 0;,否则拖动条被截断 - 禁用
user-select: none(Layui 默认加了),否则 range 拖拽失灵
示例:templet: function(d) { return '<div class="layui-table-cell"><input type="range" value="' + d.progress + '" max="100"></div>'; }
富文本或用户输入内容必须手动转义,{{d.xxx}} 不安全
Layui 的模板语法 {{d.content}} 是纯字符串替换,不做任何 HTML 转义。如果 d.content 是用户提交的 <script>alert(1)</script>,就会直接执行。
安全做法只有两种:
- 用函数模板 +
layui.laytpl.escape():templet: function(d) { return layui.laytpl.escape(d.content); } - 服务端返回时已做过滤(如只允许
<b><i></i></b><p></p>),前端再用DOMPurify二次清洗(需额外引入)
别图省事用 templet: '{{d.content}}'——上线后 XSS 漏洞基本就坐实了。
最易被忽略的是:动态生成的 HTML 元素(比如 range 滑块、开关按钮)在表格重载(table.reload)后,事件委托仍有效,但控件状态不会自动同步到缓存数据里。你得在 input/change 事件里手动更新 table.cache[<code>id][index].field = newValue,否则导出或提交时还是旧值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











