templet 用函数还是模板字符串?看场景选
直接给结论:简单格式化,用 {{d.field}} 这种模板字符串就够了;一旦需要加点逻辑,比如判断状态、拼接复杂HTML或者调用工具函数,那就必须切换到函数形式 templet: function(d) { ... }。

这两种方式区别在哪?模板字符串写法轻巧,Layui内部会自动帮你解析,但它有个硬伤:除了简单的三元运算,几乎不支持其他Ja vaScript表达式。函数形式就自由多了,你可以在里面调用 layui.util.toDateString,可以访问全局变量,还能做各种空值兜底处理。当然,自由也有代价——函数每次渲染都会执行,数据量特别大的时候,会带来微小的性能开销。
- 需要格式化时间、渲染状态标签、或者制作带图标的操作按钮列?果断用函数。
- 只是把
d.name显示出来,或者简单加个粗体、标签包裹?模板字符串完全够用。 - 想在不同列里复用同一套格式化逻辑?函数更容易抽离成公共方法,用模板字符串的话,要么复制ID,要么就得重复写。
日期格式化别踩 d.created 字段名不匹配的坑
这大概是最高频的踩坑点了:明明写了 {{layui.util.toDateString(d.createTime, 'yyyy-MM-dd')}},结果表格里显示的却是当前时间。先别急着怀疑是Bug,问题很可能出在字段名没对上。
Layui的 toDateString 方法,第一个参数必须严格对应你表格列定义里的 field 值。如果后端返回的JSON是 {"sbj_start": 1712345678000},那模板里就必须写 d.sbj_start。写成 d.createTime,方法找不到对应字段,就会默认 fallback 到当前时间戳。
- 排查第一步:打开浏览器开发者工具的Network面板,仔细核对Response里的原始数据字段名。
- 一个小细节:模板字符串里不能换行,
templet: "{{layui.util.toDateString(d.sbj_start, 'yyyy-MM-dd HH:mm:ss')}}"必须是一整行写完。 - 更稳妥的做法:如果字段可能为null或undefined,直接用函数形式做安全处理:
templet: function(d) { return d.sbj_start ? layui.util.toDateString(d.sbj_start, 'yyyy-MM-dd') : '-'; }
templet 函数里能拿到的不只是 d
从Layui 2.6.0版本开始,templet 函数的第二个参数 obj 提供了更丰富的列上下文信息。善用它,能让你的代码灵活不少,减少很多硬编码。
举个例子,你想给“序号”列根据行索引动态添加背景色,或者在操作列里,根据当前行的状态值决定显示“启用”还是“禁用”按钮。有了 obj 参数,你就不用再死板地依赖 d 对象里的某个特定字段了。
obj.field:当前列定义的field值,比如"status"。obj.index:当前行的索引(从0开始),用来生成序号列非常方便:`第${obj.index + 1}行`。obj.title:当前列的标题文本,可以用来生成提示信息(tooltip)或者辅助调试。- 注意一点:
obj.data和传入的第一个参数d是同一个对象,不需要重复解构。
树形表格(treeTable)里 templet 要防 isParent 漏判
普通表格的 templet 逻辑相对简单,直接读 d.xxx 就行。但到了树形表格(treeTable)里,数据结构多了 isParent、children 这些层级属性。如果模板里不做区分,很容易导致父子节点样式混排、展开图标错位,甚至点击展开功能失效。
典型症状就是:子节点前面也显示了“▶”折叠图标,或者父节点的名称没有加粗显示。根源在于模板没有根据层级进行条件渲染。
- 核心解决方案:必须使用
{{# if(d.isParent){ }}...{{# } else { }}...{{# } }}这样的模板语法进行条件判断。 - 一个实用建议:尽量不要在模板里直接访问
d.children.length来判断,优先使用数据中已有的d.isParent属性。这是treeTable内部计算好的、更可靠的层级标识。 - 对于异步加载子节点的情况,务必确保后端返回的每个节点数据都带有准确的
isParent: true/false标记,否则前端模板无法正确识别节点类型。
话说回来,在实际项目开发中,templet 函数里最容易被忽略的,其实是对空值和异常时间戳的防御性处理。这类问题通常不会导致页面报错,但会静默地展示出混乱的时间或空白单元格,排查时往往需要从Network里的原始数据开始,逆向推导。
