必须在table的done回调中用layui.progress()逐个初始化进度条,因templet渲染的dom需手动激活组件;示例:templet返回带data-rate的容器,done里遍历并render。
layui table 列里用 templet 渲染进度条不生效?
直接在 templet 里写 <div class="layui-progress"></div> 是没用的——layui 的进度条组件需要手动初始化,表格渲染时 dom 还没被 layui.progress() 处理过。
常见错误现象:templet 返回了 HTML,但页面只显示空容器,或者样式错乱、百分比不更新。
- 必须在
done回调里遍历表格行,对每个进度条调用layui.progress() - 不能依赖
init阶段,因为templet输出的 DOM 在render后才真实挂载 - 如果列数据是数字(比如
rate: 65),记得转成字符串再拼进data-percent,否则属性值为空
怎么给 table 某一列写 templet 并绑定动态进度值?
核心是把进度值透传进 HTML 字符串,并预留可识别的容器标识,方便后续初始化。别硬塞 layui.use 或重复加载模块。
示例:假设列字段叫 progress,值是 0–100 的整数
{
field: 'progress',
title: '完成度',
width: 120,
templet: function(d) {
return '<div class="progress-cell" data-rate="' + d.progress + '"></div>';
}
}
-
class="progress-cell"是为了后续document.querySelectorAll定位,别用太泛的类名(如layui-progress)干扰全局样式 - 不要在
templet里写layui.progress({...})—— 此时 layui 模块可能未就绪,且会报progress is not a function - 如果后端返回的是小数(如
0.75),要乘 100 再取整:Math.round(d.progress * 100)
done 回调里怎么批量初始化进度条?
表格渲染完成后的唯一可靠时机。重点不是“调用一次”,而是“对每行匹配到的元素逐个调用”。
关键点:必须等 table.render() 的 done 执行,且确保 layui.progress 已加载(通常和 table 同批 use 即可)
done: function(res, curr, count) {
// 等 DOM 更新完毕再操作
setTimeout(() => {
document.querySelectorAll('.progress-cell').forEach(el => {
const rate = el.dataset.rate;
if (rate && !isNaN(rate)) {
layui.progress().render({
elem: el,
percent: rate + '%',
width: '100%',
showPercent: true
});
}
});
}, 0);
}
- 包一层
setTimeout(..., 0)是为了确保 DOM 已完成重排,尤其在分页或异步加载时更稳妥 - 检查
dataset.rate是否存在且合法,避免NaN%导致进度条崩溃 - 别漏掉
width: '100%'—— 默认宽度是 150px,窄列里会溢出或截断
为什么翻页/重载后进度条消失?
因为 done 只触发一次,而 Layui 表格翻页是局部 DOM 替换,新行不会自动初始化。
解决方法只有一个:每次 done 都重新执行初始化逻辑,不能只在首次 render 里做。
- 不要把初始化逻辑写在
render外部闭包里并只执行一次 - 如果用了
table.reload(),确保它也带done回调,且内容和首次一致 - 注意事件代理失效问题:如果后续要监听进度条里的按钮点击,得用
document.addEventListener代理到 body,而不是直接绑在.progress-cell上
最麻烦的地方其实是 DOM 生命周期和模块初始化时机的错位——看着只是加个进度条,实际要卡准三次时机:templet 输出、DOM 挂载、progress 初始化。少一个,就白忙活。











