如何在JavaScript(shadowDom)中生成二维码并导出图片data URL?
实现方案
你选用的无DOM依赖QR生成库完全适配shadowDom场景,不需要通过id查询全局元素,直接按以下逻辑即可实现两个核心需求。
现有代码问题修正
- 原有代码
btoa(this.data.toByteArray()))存在语法错误,多了一个闭合括号 - 直接对二维码原始字节数组做base64转码得到的是二进制编码数据,不是可被img标签直接识别的图片格式数据
完整实现代码
// 二维码基础配置,可按需调整 const QR_ERROR_CORRECT_LEVEL = 'L'; // 纠错等级可选:L(7%)/M(15%)/Q(25%)/H(30%) const QR_CELL_PX = 4; // 单个二维码像素点的大小 const QR_MARGIN_CELL = 2; // 二维码边距(单位为单元格数) /** * 从输入字符串生成二维码png的data URL * @param {string} inputStr 待生成二维码的原始字符串,如URL * @returns {string} 可直接赋值给img.src的data URL */ const generateQrDataUrl = (inputStr) => { // 1. 生成二维码矩阵数据 const qr = new QRCode(QR_ERROR_CORRECT_LEVEL); qr.addData(inputStr); qr.make(); // 2. 离线canvas绘制二维码,无需挂载到DOM const canvas = document.createElement('canvas'); const cellCount = qr.getModuleCount(); const totalSize = (cellCount + QR_MARGIN_CELL * 2) * QR_CELL_PX; canvas.width = totalSize; canvas.height = totalSize; const ctx = canvas.getContext('2d'); // 绘制白色背景 ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, totalSize, totalSize); // 绘制二维码黑色点位 ctx.fillStyle = '#000000'; for (let row = 0; row < cellCount; row++) { for (let col = 0; col < cellCount; col++) { if (qr.isDark(row, col)) { ctx.fillRect( (QR_MARGIN_CELL + col) * QR_CELL_PX, (QR_MARGIN_CELL + row) * QR_CELL_PX, QR_CELL_PX, QR_CELL_PX ); } } } // 3. 导出为png格式的data URL return canvas.toDataURL('image/png'); } // 业务调用示例 this.id = crypto.getRandomValues(new Uint32Array(1))[0].toString(); this.qrCodeUrl = generateQrDataUrl(this.id); // 直接赋值给shadowDom内的img标签即可使用 // this.shadowRoot.querySelector('.qr-img').src = this.qrCodeUrl;
注意事项
- 全程使用离线canvas绘制,不需要插入到任何DOM树,完全不受shadowDom的id隔离限制
- 可调整
QR_CELL_PX和QR_MARGIN_CELL参数自定义二维码的整体大小和边距 - 可修改
fillStyle属性值自定义二维码的前景色和背景色
内容的提问来源于stack exchange,提问作者chovy
相关产品推荐
相关产品推荐

