toolbar必须在table.render()前完成角色过滤,依据window.USER_ROLE等同步权限数据动态拼接HTML字符串,禁用异步后处理或DOM隐藏;按钮配置应统一为带role字段的数组,拼接用map().join()防XSS;lay-event须全局唯一;title提示应在done回调中通过data-title预埋并补全;操作列hover显隐需事件委托+防抖+fixed区域适配;权限变更须销毁重render。
toolbar 必须在 table.render() 前完成角色过滤
layui 的 toolbar 参数只接受 html 字符串或 dom 节点,不支持运行时条件渲染。所谓“按权限显示”,本质是:在调用 table.render() 之前,就根据 window.user_role(或 localstorage、api 返回值)筛出当前用户能点的按钮,拼成字符串传进去。
常见错误是全量渲染再 $('.layui-btn[lay-event="export"]').hide() —— 按钮 DOM 还在,右键审查就能 show 出来,甚至直接触发绑定函数,后端鉴权变成最后一道防线。
- 角色信息必须在 JS 执行时已就绪,不能依赖异步请求结果后再 render 表格(否则会闪一下所有按钮)
- 按钮配置建议统一定义为数组对象,每个带
role字段,例如:[{id: 'add', text: '新增', role: ['admin', 'editor']}] - 拼接时用
map().join(''),避免innerHTML +=引入 XSS 风险(尤其当按钮文字来自后端时) -
lay-event值必须全局唯一,否则table.on('toolbar(demo)')无法正确分发事件
按钮提示文字(title)得在 done 回调里加
直接在 toolbar 字符串里写 <button title="导出"> 看似可行,但 Layui 内部会对字符串做简单转义,双引号、& 符号容易被破坏,导致 title 截断或失效。更稳的方式是等表格渲染完,在 done 回调里用 layui.$ 找到按钮补 title 属性。
- 推荐用
data-title预埋提示文案,比如:<button data-event="export" data-title="导出当前页数据">导出</button> - 在
done里统一处理:layui.$('[data-title]').each((i, el) => layui.$(el).attr('title', layui.$(el).data('title'))) - 不要用 CSS
:hover::after模拟 tooltip —— Layui 表格有行复用机制,hover 状态会错乱 - 移动端 Safari 和部分安卓 WebView 原生
title不显示,这是平台限制,不是你代码的问题
操作列按钮 hover 显隐必须用事件委托
想实现“鼠标移到某行,才显示该行的操作按钮”,不能给 td 写 onmouseover,也不能靠 CSS :hover。因为 Layui 表格滚动、分页、排序都会重绘 DOM,静态绑定的事件会丢失,:hover 则会因行复用导致状态错位。
- 操作列模板里必须包裹一层固定 class 的容器,例如:
<div class="opt-btns"><button lay-event="edit">编辑</button></div> - 在
done回调中监听表格容器的mouseenter/mouseleave,用e.target.closest('tr')定位当前行,再找里面的.opt-btns切换layui-hide - 加 200ms 防抖,避免快速划过时按钮频繁闪现
- 如果操作列用了
fixed: 'right',要额外监听.layui-table-fixed-r区域,否则右侧固定列 hover 失效
权限变化后不能只改 DOM,得重 render
用户切换角色(比如从 editor 升为 admin)后,仅靠 JS 修改 toolbar DOM 或加按钮 class 是不够的。Layui 表格内部状态和事件绑定都基于初始化时的配置,手动增删按钮容易导致 table.on('toolbar()) 监听失效,或者点击无响应。
真正安全的做法是:销毁原实例(table.destroy('demo')),重新执行一遍带新角色过滤逻辑的 table.render()。虽然看起来重,但比修各种状态不一致的 bug 更省时间。
注意:重 render 时要显式传入 where、page、initSort 等参数,否则会丢失搜索条件、当前页码和排序状态。


















