核心概念
templet
是 Layui 表格组件中用于自定义单元格渲染的核心功能,它提供了三种使用方式:
1. 函数形式(最灵活)
templet: function(d) {
return `<span class="status-${d.status}">${d.statusName}</span>`;
}
2. 模板字符串形式
templet: '<span class="status-{{d.status}}">{{d.statusName}}</span>'
3. 引用预定义模板
templet: '#statusTpl'
<script type="text/html" id="statusTpl">
<span class="status-{{d.status}}">{{d.statusName}}</span>
</script>
核心参数详解
函数参数:
d
:当前行数据对象obj
(Layui 2.6.0+):obj.field
:当前字段名obj.title
:列标题obj.index
:行索引obj.data
:行数据(同 d)
templet: function(d, obj) {
return `第${obj.index+1}行: ${d[obj.field]}`;
}
最佳实践方案
1. 项目中的实现方案
// 在JS中动态添加templet
var tableConfig = {
dataurl: "/FSProduct/getAllFSProductList1",
cols: [
// 基础列配置...
]
};
// 渲染表格前处理列配置
tableConfig.cols.forEach(col => {
if (col.field === 'id') {
col.templet = function(d) {
return `<div class="layui-table-cell-id">${d.id || ''}</div>`;
}
}
});
// 渲染表格
table.render({
elem: '#product-table',
url: tableConfig.dataurl,
cols: [tableConfig.cols],
// ...其他配置
});
2. 状态显示模板
{
field: 'status',
title: '状态',
templet: function(d) {
const statusMap = {
1: {text: '启用', class: 'layui-bg-green'},
0: {text: '禁用', class: 'layui-bg-gray'},
2: {text: '审核中', class: 'layui-bg-orange'}
};
const status = statusMap[d.status] || {text: '未知', class: ''};
return `<span class="layui-badge ${status.class}">${status.text}</span>`;
}
}
3. 操作按钮组
{
field: 'actions',
title: '操作',
templet: function(d) {
return `
<button class="layui-btn layui-btn-xs"
onclick="editItem(${d.id})">编辑</button>
<button class="layui-btn layui-btn-xs layui-btn-danger"
onclick="deleteItem(${d.id})">删除</button>
`;
}
}
4. 安全渲染(防XSS)
{
field: 'content',
title: '内容',
templet: function(d) {
// 使用Layui的escape方法防止XSS攻击
return `<div>${layui.escape(d.content)}</div>`;
}
}
5. 响应式设计
{
field: 'userInfo',
title: '用户信息',
templet: function(d) {
return `
<div class="hidden-xs">${d.fullName} (${d.email})</div>
<div class="visible-xs">${d.fullName}</div>
`;
}
}
性能优化技巧
1. 避免复杂计算
// 不推荐
templet: function(d) {
const result = complexCalculation(d);
return `<div>${result}</div>`;
}
// 推荐:预处理数据
data.forEach(item => {
item.calculatedValue = complexCalculation(item);
});
// 简单渲染
templet: '<div>{{d.calculatedValue}}</div>'
2. 使用静态模板
// 定义静态模板
const statusTpl = '<span class="status-{{d.status}}">{{d.statusName}}</span>';
// 渲染时使用
{
field: 'status',
title: '状态',
templet: statusTpl
}
3. 事件委托处理
// 表格渲染后绑定事件
table.on('tool(tableFilter)', function(obj) {
if(obj.event === 'edit') {
editItem(obj.data.id);
} else if(obj.event === 'delete') {
deleteItem(obj.data.id);
}
});
// templet中使用data-event属性
templet: function(d) {
return `
<button class="layui-btn layui-btn-xs"
data-event="edit" data-id="${d.id}">编辑</button>
<button class="layui-btn layui-btn-xs layui-btn-danger"
data-event="delete" data-id="${d.id}">删除</button>
`;
}
高级应用场景
1. 嵌套表格
{
field: 'details',
title: '详情',
templet: function(d) {
return `
<div class="nested-table">
<table>
<tr><th>项目</th><th>值</th></tr>
<tr><td>创建时间</td><td>${d.createTime}</td></tr>
<tr><td>更新时间</td><td>${d.updateTime}</td></tr>
</table>
</div>
`;
}
}
2. 图表集成
{
field: 'progress',
title: '进度',
templet: function(d) {
return `
<div class="progress-container">
<div class="progress-bar" style="width: ${d.progress}%">
<span>${d.progress}%</span>
</div>
</div>
`;
}
}
3. 图片预览
{
field: 'image',
title: '图片',
templet: function(d) {
return `
<img src="${d.thumbnail}"
onclick="showImage('${d.fullImage}')"
class="preview-image">
`;
}
}
常见问题解决方案
1. 模板不更新
// 错误:使用字符串模板(不会更新)
templet: '<div>{{d.name}}</div>'
// 正确:使用函数形式
templet: function(d) {
return `<div>${d.name}</div>`;
}
2. 事件绑定失效
// 使用Layui事件委托
table.on('tool(tableFilter)', function(obj) {
if($(obj.tr).find('.edit-btn').is(e.target)) {
editItem(obj.data.id);
}
});
// templet中:
templet: function(d) {
return `<button class="edit-btn" data-id="${d.id}">编辑</button>`;
}
3. 性能优化
// 大数据量时使用虚拟滚动
table.render({
elem: '#table',
height: 'full-200',
page: true,
limit: 1000, // 合理设置每页数量
// ...
});
总结与最佳实践
- 优先使用函数形式:提供最大灵活性
- 复杂逻辑外部化:将复杂计算移出templet
- 安全第一:使用
layui.escape()
防止XSS - 性能优化:
- 避免在templet中创建大量DOM
- 使用分页和虚拟滚动
- 预处理数据
- 事件处理:
- 使用Layui事件委托
- 通过
data-*
属性传递参数
- 响应式设计:
- 使用CSS媒体查询
- 为不同设备提供不同内容
通过合理使用templet
,您可以创建高度定制化、用户友好的数据表格,同时保持代码的可维护性和性能。