templet函数必须动态返回HTML字符串,通过if/else判断d.category拼接按钮,避免静态模板、CSS隐藏或文本反推;lay-event回调中直接用obj.data.category获取原始值;字段比较前需归一化类型。
templet 函数必须写成动态返回 HTML 字符串的形式
静态字符串模板(比如 templet: '<button>编辑</button>')无法做条件判断,所有行都会渲染一模一样的按钮。唯一可行路径是让 templet 是一个函数,接收当前行数据 d,内部用 if/else 或 switch 分支决定返回什么 html。
常见错误包括:
- 在字符串模板里写
{{ d.type }}试图插值后加逻辑——laytpl不支持表达式执行,只做简单替换 - 把所有按钮都写出来再靠 CSS
display: none控制显隐——DOM 节点冗余,事件监听器全挂载,状态难同步
正确做法是:函数体内直接判断 d.category,拼出最终要渲染的按钮 HTML 字符串,不操作 DOM,不调用 laytpl,不引入额外依赖。
示例:
{field: 'category', title: '操作', templet: function(d) {
if (d.category === 'user') {
return '<button class="layui-btn layui-btn-xs" lay-event="edit">编辑用户</button>';
} else if (d.category === 'order') {
return '<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="cancel">取消订单</button>';
} else {
return '<button class="layui-btn layui-btn-xs layui-btn-warm" lay-event="view">查看详情</button>';
}
}}lay-event 回调里必须用 data 参数取真实状态,不能解析按钮文本
按钮文字变了,但点击后业务逻辑仍需知道这行原始的 category 值。如果靠 $(e.elem).text() 反推,一旦按钮文案被翻译、被样式遮挡、或前端临时改了文字,整个逻辑就崩了。
正确方式是:监听 tool(tableId) 事件,在回调函数的 obj.data 中直接读取字段:
-
obj.data.category就是该行原始数据中的值,和渲染时传给templet的d.category完全一致 - 不需要查
table.cache,也不需要obj.tr找父节点再查属性 - 只要没在
parseData里篡改过字段,这个值就是可信的
注意:lay-event 绑定的是按钮,不是列;事件监听必须用 table.on('tool(yourTableId)', callback),普通 click 监听拿不到 obj.data。
字段类型不一致时,比较前务必归一化
Layui 不做隐式转换,d.category === 'user' 和 d.category === 'USER' 是两回事,后端返回大小写混杂、空格、数字编码(如 1 表示 user)时,很容易漏判。
建议统一处理策略:
- 在
parseData回调中提前标准化:data.category = String(data.category).trim().toLowerCase() - 或在
templet函数里用宽松比较:String(d.category).toLowerCase() === 'user' - 避免只写
d.category == 'user',万一后端返回'user '(带空格)就失效
同理,布尔型字段如 is_active,别直接写 d.is_active === true,优先用 !!d.is_active 或 Boolean(d.is_active) 转换。
toolbar 模板(script type="text/html")里 if 判断写法要严格遵循 laytpl 语法
如果你选择用外部 <script type="text/html"> 定义 toolbar 模板(比如 toolbar: '#operateBar'),里面的条件语句必须用 laytpl 的双大括号语法,且括号内只能是简单表达式,不能写复杂 JS 逻辑。
正确写法:
<script type="text/html" id="operateBar">
{{# if(d.category === 'user') { }}
<button class="layui-btn layui-btn-xs">管理权限</button>
{{# } else if(d.category === 'product') { }}
<button class="layui-btn layui-btn-xs layui-btn-normal">上架</button>
{{# } else { }}
<button class="layui-btn layui-btn-xs layui-btn-warm">通用操作</button>
{{# } }}
</script>容易踩的坑:
- 漏写
{{# }}开头的#,变成{{ if(...) { }}→ 模板不解析,原样输出 - 在
{{# if(...) { }}里写函数调用或三元运算符 → laytpl 不支持,会报错或静默失败 - 模板 ID 写错,或未在
cols中正确引用toolbar: '#operateBar'→ 按钮根本不出现
这种写法适合按钮结构较固定、判断逻辑简单的场景;一旦分支多或 HTML 复杂,还是推荐用函数形式 templet,可控性更强、调试更直接。
最易被忽略的一点:无论用函数还是 script 模板,所有判断依据都必须来自 d(即当前行原始数据),而不是全局变量、DOM 状态或 localStorage —— 否则翻页、搜索、reload 后极易错乱。


















