<p>Layui表格templet中不能写原生JavaScript if语句,必须用arttemplate语法{{# if(d.status == 1) { }}启用{{# } else { }}停用{{# } }},所有逻辑须基于数据对象d展开。</p>
直接说结论:layui 表格 templet 中不能写原生 javascript 的 if 语句,必须用 arttemplate 语法 {{# if() { }} 块,且所有判断逻辑必须围绕数据对象 d 展开。
templet 里写 if(d.status === 1) 为什么会空白?
这是最常踩的坑 —— 把模板当 JS 函数写。Layui 的 templet 字符串(无论是内联字符串、#id 引用,还是函数返回值)最终都交给 laytpl 解析,而 laytpl 只识别自己的语法,对原生 if、return、function 一概忽略或静默失败。
- 错误写法:
templet: function(d) { if(d.status === 1) return '启用'; else return '停用'; }→ 控制台无报错,但单元格空 - 正确方向:要么改用函数形式并手动拼接(见下一条),要么统一走
{{# if}}模板语法 - Layui 2.8+ 对语法校验更严格,旧版可能“碰巧”能跑,新版大概率失效
三种写法怎么选:函数 / 内联模板 / 外部 <script type="text/html">
本质是同一套逻辑的三种载体,选哪种取决于可维护性和复用需求:
-
函数形式(适合简单逻辑或需动态计算):
templet: function(d) { return d.status === 0 ? '未开始' : d.status === 1 ? '进行中' : '已结束'; }→ 支持完整 JS 表达式,但无法直接写 HTML 标签(需手动拼字符串) -
内联模板字符串(推荐中小项目快速上手):
templet: '<div>{{# if(d.status == 0) { }}未开始{{# } else if(d.status == 1) { }}进行中{{# } else { }}已结束{{# } }}</div>'→ HTML 片段直接写,不转义,但注意引号嵌套和空格 -
外部
<script type="text/html">(适合复杂 HTML 或多列复用):templet: '#statusTpl',再定义<script type="text/html" id="statusTpl">{{# if(...) { }}...{{# } }}→ 易读易调试,但要确保id存在且未被重复定义
{{# if}} 块里能写什么?不能写什么?
arttemplate 的 {{# }} 是执行上下文,不是纯插值,这点和 {{ d.xxx }} 有本质区别:
- ✅ 能写:
if/else if/else块、for循环、访问d上任意字段(如d.user.name)、直接写 HTML 标签(<button>编辑</button>) - ❌ 不能写:
function声明、var/let/const变量声明、console.log、调用外部函数(除非提前挂到全局,不推荐) - ⚠️ 关键细节:
{{ d.xxx }}会自动 HTML 转义,{{# if() { }}xxx{{# } }}块里的内容默认不转义 —— 所以按钮、input、带样式的span必须放块里,不能拆成{{ d.btnHtml }}
多状态 + 动态属性(比如 radio name 带 ID)怎么写?
这是真实业务中最容易翻车的场景:既要判断状态,又要为不同行生成唯一 DOM 属性。核心原则是——所有动态值都从 d 取,HTML 结构全写在 {{# if}} 块里:
<script type="text/html" id="stateBar">
{{# if(d.state == '0') { }}
<input type="radio" name="state{{d.id}}" value="0" title="已提交" {{ d.state=='0' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="1" title="处理中" {{ d.state=='1' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="2" title="已处理" {{ d.state=='2' ? 'checked' : '' }}>
{{# } else if(d.state == '1') { }}
<input type="radio" name="state{{d.id}}" value="0" title="已提交" {{ d.state=='0' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="1" title="处理中" {{ d.state=='1' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="2" title="已处理" {{ d.state=='2' ? 'checked' : '' }}>
{{# } else { }}
<input type="radio" name="state{{d.id}}" value="0" title="已提交" {{ d.state=='0' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="1" title="处理中" {{ d.state=='1' ? 'checked' : '' }}>
<input type="radio" name="state{{d.id}}" value="2" title="已处理" {{ d.state=='2' ? 'checked' : '' }}>
{{# } }}
</script>注意:{{ d.id }} 和三元表达式 {{ d.state=='0' ? 'checked' : '' }} 都是合法的,但必须写在同一 {{# }} 块内;name="state{{d.id}}" 这种字符串插值只在 {{# }} 块中生效,外面写无效。
真正麻烦的从来不是语法本身,而是把「状态判断」和「DOM 属性动态绑定」混在一起时,稍不留神就漏掉一个 {{d.xxx}} 或多写一个引号。建议复杂逻辑一律抽到 <script type="text/html"> 里,先写死 HTML 跑通,再逐步替换动态部分。


















