Layui templet需用函数或{{d.xxx}}字符串模板,禁用三元运算;调用外部函数须挂window或闭包传入;事件绑定须用委托;性能优化应避免templet内耗时操作。
templet 里怎么写 JS 逻辑才不报错
直接在 templet 字段里写 js,最容易踩的坑是:把模板当 html 写,忘了它本质是函数体。layui 的 templet 接收的是字符串(如 '<div>{{d.name}}</div>')或函数(如 function(d){return '<div>'+d.name+'</div>'}),但很多人误用 es6 模板字符串又漏了 return,结果渲染空白。
正确做法是:优先用函数形式,明确返回字符串;若用字符串模板,必须用 {{d.xxx}} 语法,且不能嵌套 JS 表达式(比如 {{d.status == 1 ? '启用' : '禁用'}} 是非法的,Layui 不支持三元运算)。
- 需要条件判断、格式化、拼接时,必须用函数形式:
templet: function(d) { return d.age > 18 ? '<span class="layui-badge">成年</span>' : '<span class="layui-badge layui-bg-gray">未成年</span>'; } - 纯字段展示用字符串模板更轻量:
templet: '<div>{{d.title}}</div>' - 函数里访问不到全局变量或外部作用域的
let/const变量,所有依赖要提前定义或闭包传入
如何在 templet 里调用外部函数或工具方法
Layui 表格初始化时,templet 函数执行上下文是表格行数据 d,不自动绑定 this 或外部作用域。想复用已有工具函数(比如时间格式化),不能直接写 formatDate(d.create_time)——会报 formatDate is not defined。
根本原因是:Layui 把 templet 字符串动态 new Function 执行,只传入 d 参数,其他一概不带。
- 方案一:把函数挂到
window下(简单但污染全局):window.formatDate = function(t){...};,然后templet: function(d){return formatDate(d.time);} - 方案二:用闭包预置依赖(推荐):
templet: (function(fmt){ return function(d){ return fmt(d.time); }; })(myDateFormatFunc) - 方案三:在表格配置外统一处理数据(如用
parseData预加工字段),避免模板里做逻辑
templet 渲染后事件绑定失效怎么办
常见现象:在 templet 里写了按钮 <button class="del-btn">删除</button>,然后用 $('.del-btn').on('click', ...) 绑定事件,结果点不动——因为表格是异步渲染的,DOM 还没出来就去绑了。
Layui 表格的 templet 内容是在 render() 后才插入 DOM 的,而且可能分页、重载时反复销毁重建。
- 永远不要在初始化后立刻用 jQuery 直接选
.del-btn绑事件 - 改用事件委托:
$(document).on('click', '.del-btn', function(){...}),或者更精准地委托到表格容器:$('#table-id').on('click', '.del-btn', ...) - 如果用 Layui 自带的
lay-event,就别手写按钮和事件,直接配event: 'del'+tool: function(obj){...}回调,更稳
templet 性能差、滚动卡顿怎么优化
当表格行数超过 500 行,每个单元格都用函数型 templet 做复杂计算(比如多次 JSON.parse、正则匹配、循环拼接),滚动会明显掉帧。不是 Layui 慢,是 JS 执行阻塞了渲染。
关键原则:模板函数里只做必要渲染,不做数据转换、请求、DOM 查询。
- 把耗时操作提到
parseData或接口层完成,让d传进来就是“开箱即用”的值 - 避免在
templet里调用$.ajax、localStorage.getItem等同步阻塞操作 - 字符串模板比函数模板快(V8 优化更好),能用
'{{d.name}}'就别写function(d){return d.name;} - 用 Chrome DevTools 的 Performance 面板录一次滚动,看是不是
templet函数占了大量主线程时间
templet 看似简单,实际是“数据—视图”链路上最易失控的一环:它既不是纯模板,也不是标准组件,而是一个被动态执行的 JS 片段。最容易被忽略的是它的执行时机和作用域隔离——不是写对了语法就能跑通,得时刻想着“这行代码运行时,我手里到底有什么”。









