直接在layTable表头加checkbox无效,因渲染后DOM会被重绘清空,且Layui不支持动态更新列配置;应使用toolbar自定义区域配合table.setColsStatus控制列显隐,并通过localStorage持久化状态。
为什么直接在 layTable 表头加 checkbox 不起作用
layui 的 table.render() 渲染后,表头是动态生成的 dom,手动往 .layui-table-header 里塞 checkbox 会被后续重绘清空;而且 layui 默认不暴露列配置的实时变更接口,col 数组改了也不会自动同步到已渲染表格。
真正可行的路径是:拦截列定义、接管显示逻辑、用自定义工具栏触发列显隐 —— 而不是硬塞到表头内部。
用 toolbar 配置 + table.setColsStatus 控制列显隐
Layui v2.8+ 提供了 table.setColsStatus(id, field, status) 方法,配合 toolbar 自定义区域,就能实现“列显示开关”功能。关键点在于:field 必须与列定义中的一致,且表格初始化时要设 defaultToolbar: true 才能启用右上角工具栏扩展能力。
-
table.render()中启用defaultToolbar: true,并定义toolbar: '#column-toggle-toolbar' - 在 HTML 中写一个
<script type="text/html" id="column-toggle-toolbar">...</script>模板,里面放按钮或下拉菜单 - 点击时遍历
table.config[id].cols[0]获取所有列,对每个field调用table.setColsStatus(id, field, true/false) - 注意:
setColsStatus不会触发重绘,需手动调用table.reload(id)或用table.resize(id)(轻量刷新)
示例片段:
table.render({
elem: '#demo',
id: 'demoTable',
defaultToolbar: true,
toolbar: '#column-toggle-toolbar',
cols: [[
{type: 'checkbox'},
{field: 'username', title: '用户名', width: 120},
{field: 'email', title: '邮箱', width: 160},
{field: 'status', title: '状态', width: 80}
]]
});
如何让列开关支持“全选/反选”并记忆用户选择
单纯切换显隐不够,用户需要感知当前状态、能批量操作、且刷新后不丢失。Layui 没有内置列状态持久化,得自己存到 localStorage 或 sessionStorage。
- 每次调用
setColsStatus后,用table.getColData('demoTable')(需自行封装,Layui 无此 API)不可靠;更稳的方式是维护一个本地映射对象,如colStatus = {username: true, email: false, status: true} - 点击“全选”时,遍历
colStatus设为true,再逐个调用setColsStatus - 页面加载时,在
table.render()前读取localStorage.getItem('demoTable-colStatus'),然后对每个field预设hide: !status[field](注意:hide是列定义属性,只在首次渲染生效) - 真正运行时的显隐控制必须靠
setColsStatus+table.resize(),hide只管初始态
兼容旧版 Layui(v2.5.x)怎么办
v2.5.x 没有 setColsStatus,只能靠暴力重载:table.reload() 并动态修改 cols 数组。缺点是会丢失当前页码、排序、滚动位置。
- 把原始
cols存为全局变量(如window.demoCols),每次 toggle 前先 clone 它 - 根据用户选择,给对应列加上
hide: true或删掉hide属性 - 调用
table.reload('demoTable', { cols: [newCols] }) - 为减少闪烁,可加
done: function() { $table.next('.layui-table-box').scrollTop(top); }尝试恢复滚动位置 - 务必避免在
done回调里再 reload,否则无限循环
这个方案实操成本高,状态管理容易出错,建议优先升级到 v2.8+。
实际最难的不是代码,是列配置里的field 和真实数据字段名是否严格一致 —— 字段名带点号(user.name)、驼峰(userName)、或用了 templet 却没设 field,都会导致 setColsStatus 失效。动手前先 console.log(table.config['demoTable'].cols[0]) 看一眼字段结构。











