应使用 table.on('cell(filter)', callback) 事件,在回调中用 layui.qrcode 初始化二维码,传入已挂载的 e.cell、显式 width/height 和 String(data.url||''),避免在 templet 中直接操作 DOM。

layui table 的 templet 中怎么插入可点击的二维码 DOM?
直接在 templet 里写 <div id="qrcode-123"></div> 是无效的——Layui 渲染完表格后,DOM 才存在,但此时 qrcode.js 或 QRCode 实例还没执行,会报 Cannot read property 'appendChild' of null。
必须等单元格真实挂载到页面后,再初始化二维码。Layui 提供了 done 回调,但更准确定位是用 cellEvent 或在 templet 返回字符串后,靠 layui.table.on('rendered', ...) + 委托处理,不过最稳的是用 cell 事件配合 layui.qrcode(官方扩展)。
- 优先用 Layui 官方维护的
layui.qrcode,避免引入第三方库导致jQuery冲突或canvas渲染异常 -
templet函数返回的只能是字符串,不能直接 new QRCode;得把数据塞进data-*属性,留待后续初始化 - 别在
templet里写new layui.qrcode(...)—— 此时节点尚未 append 到 body,render会失败
为什么用 cell 事件比 tool 或 row 更合适?
因为目标是「点某列的某个单元格」,不是整行操作,也不是工具栏按钮。用 table.on('cell(filter)', callback) 能精准捕获列字段(field)、行数据(data)、单元格 DOM(td),且天然支持动态生成的表格(含分页、重载)。
-
tool事件只响应toolbar列里的按钮,不适用于普通数据列 -
row事件触发范围太大,无法区分点的是哪一列 -
cell可通过if (e.field === 'url') {...}精确拦截目标列,避免误触发 - 注意:
e.cell是原生 DOM,要插二维码得先清空它再 append,否则重复点击会堆叠 canvas
layui.qrcode 初始化时容易漏掉的三个参数
很多人复制示例后二维码不显示,大概率卡在宽高、容器、内容这三项。Layui 的 qrcode 不像其他库自动撑满父容器,它严格依赖传入的 width/height 和明确的 DOM 节点。
-
elem必须传入一个**已挂载的 DOM 元素**(不能是字符串选择器),推荐用e.cell或临时创建的div并 append 进去 -
width和height必须显式设置(如120),默认值是0,结果就是白屏 -
text必须是字符串,如果传data.url是undefined,会生成空白码;建议加String(data.url || '') - 额外提醒:若内容含中文或特殊符号,确保
text已 UTF-8 编码(通常 URL 已 encode,但纯中文需encodeURIComponent)
点击后弹出浮层还是原地渲染?性能和体验怎么选?
原地替换单元格内容(清空 e.cell 后塞 canvas)最简单,但破坏表格布局,滚动/重绘易错位;弹出 layer.open 浮层更稳妥,也符合“弹出”的原始需求。
- 用
layer.open({ type: 1, content: '<div id="qrcode-popup"></div>' })创建独立容器,再对#qrcode-popup初始化二维码,完全隔离表格生命周期 - 浮层记得加
success回调,在里面初始化二维码,否则 DOM 还没插入 document 就执行会失败 - 如果并发点击频繁(比如快速连点),给浮层加个
id标识并检查是否已打开,避免重复实例占用内存 - 小屏设备慎用大尺寸二维码(如
width: 200),建议统一设为120–150,用 CSStransform: scale()适配更灵活
真正麻烦的不是生成二维码,而是时机控制——DOM 存在、尺寸可用、上下文未销毁,这三个条件缺一不可。多数问题都出在以为“节点有了就能画”,其实还要等浏览器完成 layout。

















