templet函数中直接调用formatDate会报错,因Layui用new Function动态构造函数,不继承外部作用域;推荐挂载到layui.cache或用闭包传参,字符串模板不支持调用外部函数。

templet函数里直接写formatDate(d.time)会报错
不是函数没定义,是Layui用new Function('d', 'return ' + templateStr)动态构造执行函数,天然不带外部作用域——连window都不自动可访问,更别说你定义在模块顶层的formatDate了。哪怕它就在table.render()上方声明,templet函数里也根本“看不见”。
挂到layui.cache是最稳的传参方式
layui.cache是Layui官方预留的轻量级全局缓存区,所有模块都能读写,且不会被压缩工具误删或污染window。比window.xxx更安全,兼容严格模式和部分沙箱环境。
- 初始化表格前就存好:
layui.cache.myUtils = { formatDate: function(ts) { return layui.util.toDateString(ts, 'yyyy-MM-dd'); }, statusText: function(status) { return {0: '未开始', 1: '进行中', 2: '已结束'}[status] || '-'; } }; - 在templet里直接调用:
templet: function(d) { return layui.cache.myUtils.statusText(d.status) + ' / ' + layui.cache.myUtils.formatDate(d.sbj_start); } - 注意字段名必须和后端返回一致(比如
sbj_start,不是createTime),否则toDateString会fallback为当前时间
闭包捕获适合简单、单点复用场景
如果你的工具函数只在当前表格用,且定义在table.render()外层作用域(比如IIFE或模块顶层),用闭包最干净,不污染任何全局空间。
- 写法示例:
var myFormat = layui.util.toDateString; var myStatusMap = {0: '禁用', 1: '启用'}; <p>// 闭包把myFormat和myStatusMap“带进”templet templet: (function(fmt, map) { return function(d) { return '<span class="layui-badge">' + (map[d.status] || '-') + '</span> ' + fmt(d.sbj_start, 'MM-dd HH:mm'); }; })(myFormat, myStatusMap) - 优势:不依赖
layui.cache或window,加载顺序无风险 - 缺点:逻辑分散,多列复用时需重复写闭包
别碰字符串模板里的函数调用
像templet: '{{# if(layui.util.toDateString(d.sbj_start)) { }}...{{# } }}这种写法一定失败。laytpl引擎不支持跨作用域执行函数,{{# }}块里只能访问d上的字段,不能调用任何外部方法。
- 字符串模板只认
{{d.xxx}}和{{# if(d.xxx) { }}{{# } }}这类语法 - 想用工具函数?必须切到函数形式
templet: function(d) { ... } - 如果用了
layui.use(['table', 'util'], function(){}),记得把util传进去,否则layui.util可能还是undefined
复杂点在于:templet函数执行时机早于很多模块就绪,而闭包和layui.cache又各有适用边界——字段名匹配、模块加载顺序、是否多列共用,这几个条件一叠,方案就得跟着变。


















