Layui表格权限控制需分层处理:toolbar按钮须在table.render()前按角色过滤生成;操作列按钮依赖行级权限字段;列显隐由视图级结构决定,三者不可混用。
toolbar 必须在 table.render() 前完成权限过滤
layui 的 toolbar 参数不支持运行时条件渲染,只接受 html 字符串、模板 id 或 true。所谓“按角色显示按钮”,本质是在调用 table.render() 之前,就根据 window.user_role(或 localstorage、api 返回值)筛出当前用户能点的按钮,拼成字符串传进去。
常见错误是全量渲染后用 $('.layui-btn[lay-event="export"]').hide() —— 按钮 DOM 还在,右键审查就能 show 出来,甚至直接触发绑定函数,后端鉴权变成最后一道防线。
- 按钮配置必须结构化:定义为带
role字段的数组,例如[{id: 'export', text: '导出', role: ['admin', 'editor']}, {id: 'sync', text: '同步', role: ['admin']}] - 拼接时用
.filter().map().join(''),避免 XSS 和空值报错;lay-event值必须全局唯一 -
title提示不能靠 CSSattr()补,得在done回调里通过data-title预埋并统一补全 - 权限变更时不能 patch DOM,必须销毁表格后重新
table.render()
操作列按钮要依赖行级权限字段,而非全局角色
如果某行本应禁止操作(比如非本人创建),仅靠 window.USER_ROLE 或 localStorage.getItem('role') 在 templet 里判断,会漏掉行级控制。后端必须在每条记录中透出必要权限标识,例如 can_edit、can_delete、is_creator。
前端不要在 templet 里重复写 d.create_by === window.USER_ID 这类逻辑——既易错又难维护。若必须前端计算,请抽成统一工具函数,如 canDo(d, 'delete')。
- fixed 列 + 动态按钮 = 必须显式设
width,否则宽度计算异常导致错位或换行 - 按钮数量不固定时(1 个 vs 3 个),Layui 不会自动重算列宽,
width值建议留余量(如150) - templet 中避免内联 JS,用
data-*属性传递原始值,便于后续扩展(如右键菜单)
动态切换列显示要用 cols 重载,别硬写索引
想隐藏“操作”列?别写 cols[0][3].hide = true。加删列、多级表头、响应式折叠都会让索引偏移。正确做法是遍历 tableIns.config.cols,按 field 或自定义 data-field 定位目标列。
初始化时给关键列加标识:{field: 'op', title: '操作', data-field: 'operation'},之后切换更可靠。
- 修改前必须深拷贝:
JSON.parse(JSON.stringify(tableIns.config.cols)),否则引用共享导致状态污染 - fixed 列的
hide属性仍生效,但固定区域宽度不会自动收缩,需手动调用table.resize() -
reload()不继承where、page.curr、initSort,必须显式传入,否则翻页跳回第 1 页、排序箭头消失 - 如果用了
autoSort: true,initSort必须完整传入,格式如{field: 'name', type: 'asc'}
不同视图的列结构差异大时,后端必须按视图返回对应字段
用户视图返回 name、age、city,订单视图返回 order_no、amount、status —— 这些字段名必须与前端 cols 中的 field 一一对应。前端不能靠 JS 拼数据,否则分页、搜索、排序参数全乱。
列定义应拆成多个变量(如 userCols、orderCols),由下拉框或路由参数决定用哪一组,再传给 table.reload({ cols: [xxx] })。
- 切换列时强制回到第 1 页是合理行为,加
page: { curr: 1 }显式声明,避免当前页无数据 - 如果列中有
templet,不同视图间不能“复用”同一列定义 —— A 视图有templet,B 视图没有,就得各自完整声明 - 列名翻译(如中英文切换)也走同一套机制:后端返回
field+title,前端只做映射,不硬编码中文
列配置和权限校验的边界容易模糊:toolbar 是页面级静态控制,操作列按钮是行级动态控制,而列显隐是视图级结构控制——三者触发时机、数据来源、更新方式完全不同,混用会导致 reload 失效或权限绕过。


















