amis QRCode 二维码组件完全指南:JSON 配置、样式定制与下载导出实战
【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis
本文围绕 amis 前端低代码框架中的qr-code(二维码)渲染器展开,系统讲解如何在 JSON Schema 中快速生成二维码,并深度覆盖背景/前景色、纠错等级、内嵌 Logo 图片、码眼与码点样式定制,以及基于事件动作的二维码下载导出等实战能力。读完本文,你将掌握 amis 二维码组件的全部配置属性与底层实现原理,可直接在表单、详情页或业务看板中落地使用。
组件概述与基本用法
在 amis 中,二维码组件通过type: "qr-code"声明,其核心职责是把一段文本或 URL 编码为可扫描的二维码图形。从源码 QRCode.tsx 可以看到,渲染器注册为type: 'qrcode',并提供别名'qr-code',两种写法均有效;文档与示例统一推荐使用qr-code。
最简单的用法只需要提供value与codeSize两个字段:
{ "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com" }value:扫描二维码后显示的文本内容;若要跳转页面,必须填写以http://或https://开头的完整 URL,并且该字段支持 amis 模板语法,可引用上下文变量(详见下文"嵌入图片"一节的关联上下文变量)。codeSize:二维码的宽高,默认128(单位 px),可理解为整个二维码图形的边长。
需要特别说明的是内容长度限制:根据 QR 码国际标准,二进制模式最多可存储2953字节(1 个中文汉字占 2 字节)。这一限制并不仅仅是文档提示,而是被硬编码进了组件实现——在 QRCode.tsx 的渲染逻辑中,当finalValue.length > 2953时,组件不会渲染二维码,而是直接显示本地化错误提示QRCode.tooLong(文案形如"内容超过 2953 字节")。因此,生成二维码前建议先预估内容体积,尤其是包含长中文文本的场景。
另外,当value为空时,组件会渲染一个占位符,默认占位内容为-(由placeholder属性控制,默认值见 QRCode.tsx 的defaultProps)。
配置背景色与前景色
二维码由"背景"和"前景(码点/码眼)"两部分构成,二者可分别独立配置颜色。
背景色 backgroundColor
背景色默认为#fff(纯白色),通过backgroundColor属性修改:
[ { "type": "qr-code", "codeSize": 128, "backgroundColor": "#108cee", "foregroundColor": "#000", "value": "https://www.baidu.com" } ]前景色 foregroundColor
前景色默认为#000(纯黑色),通过foregroundColor属性修改:
[ { "type": "qr-code", "codeSize": 128, "backgroundColor": "#fff", "foregroundColor": "#108cee", "value": "https://www.baidu.com" } ]从实现层面看,这两个属性最终会作为styleConfig.bgColor与styleConfig.color传入底层二维码渲染库qrcode-react-next(见 QRCode.tsx)。测试用例 QRCode.test.tsx 验证了在 svg 渲染模式下,背景色会写入 SVG 根节点的background-color样式,前景色会写入码点元素的fill属性,二者互不影响。
配色实践提示:二维码识别依赖码点与背景之间的明暗对比,建议保持深色前景 + 浅色背景的组合;过度接近的配色(如浅灰前景 + 白背景)可能导致扫码失败。
纠错等级 level
二维码具备容错能力:即使部分图形被遮挡、污损或印制模糊,只要损坏程度在纠错能力范围内,依然可以被正常识别。level属性用于设置纠错等级,共四种,从左到右纠错能力依次提升:
| 等级 | 容错能力 | 适用场景 |
|---|---|---|
L | 约 7% | 默认值,适合无遮挡、打印清晰的场景 |
M | 约 15% | 一般场景 |
Q | 约 25% | 推荐用于内嵌图片(Logo)的场景 |
H | 约 30% | 遮挡风险高的场景 |
默认等级为'L'(见 QRCode.tsx 的defaultProps与 属性表)。一个直观的对比如下——同一内容分别使用 L/M/Q/H 四种等级渲染:
{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "level": "L", "value": "https://www.baidu.com" }, { "type": "qr-code", "codeSize": 128, "level": "M", "value": "https://www.baidu.com" }, { "type": "qr-code", "codeSize": 128, "level": "Q", "value": "https://www.baidu.com" }, { "type": "qr-code", "codeSize": 128, "level": "H", "value": "https://www.baidu.com" } ] }值得注意的是,源码中向渲染库传入的配置除了level外,还包含了minVersion: 2与boostLevel: true(见 QRCode.tsx)。boostLevel表示在内容允许的情况下自动提升纠错等级,minVersion: 2则规定了二维码符号的最小版本,这保证了生成结果在图形尺寸与纠错冗余上有更稳定的表现。
嵌入图片(Logo 水印)
二维码中间可以嵌入一张图片(例如品牌 Logo),通过imageSettings对象配置,该能力自1.10.0版本起支持。
基础用法 src
imageSettings.src设置图片链接地址;图片尺寸默认取二维码大小的10%,位置默认水平、垂直居中:
{ "type": "qr-code", "codeSize": 128, "level": "Q", "value": "https://www.baidu.com", "imageSettings": { "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg", } }强烈建议:嵌入图片会遮挡部分码点,请根据图片大小适当调高
level纠错等级(一般建议至少Q),避免图片遮挡导致二维码无法被正确识别。
关联上下文变量
imageSettings.src支持 amis 模板/变量语法,可以引用页面数据域中的值。下面的示例在页面data中声明了imgSrc变量,图片地址通过${imgSrc}动态注入,同时显式指定了图片宽高:
{ "type": "page", "data": { "imgSrc": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg" }, "body": { "type": "qr-code", "codeSize": 128, "level": "Q", "value": "https://www.baidu.com", "imageSettings": { "width": 50, "height": 30, "src": "${imgSrc}" } } }这个变量解析逻辑有明确的源码支撑:在 QRCode.tsx 的getImageSettings()方法中,组件会通过isPureVariable检测src是否为变量表达式,若是则调用resolveVariableAndFilter(src, data, '| raw')从当前数据域中解析出真实地址。同时,width、height、x、y这四个数值型配置还会经过isNumeric校验并转换为Number,以兼容从数据域中取到的字符串数值。
图片宽高
width和height可以显式设置图片的宽度和高度(不设置时默认各为codeSize的 10%):
{ "type": "qr-code", "codeSize": 128, "level": "Q", "value": "https://www.baidu.com", "imageSettings": { "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg", "width": 50, "height": 30 } }图片偏移量 x / y
默认情况下图片水平、垂直居中。如需调整位置,以二维码左上角为原点,用x设置水平偏移量、y设置垂直偏移量。下面的示例通过codeSize(128)与图片的width(50)、height(30)推算出偏移量{"x": 78, "y": 98},使图片位于右下角:
{ "type": "qr-code", "codeSize": 128, "level": "Q", "value": "https://www.baidu.com", "imageSettings": { "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg", "width": 50, "height": 30, "x": 78, "y": 98 } }偏移量的推算逻辑可以这样理解:以 128×128 的二维码为例,图片宽 50、高 30,若想贴到右下角,x 应为128 - 50 - 某边距、y 应为128 - 30 - 某边距,示例中的 78 与 98 即按此思路留出边距后计算得到。svg 模式下,测试用例 QRCode.test.tsx 会断言图片节点(<image>)的x、y、width、height属性均大于 0,验证偏移与尺寸配置确实生效。
imageSettings 汇总
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src | string | - | 图片链接地址,支持${var}变量 |
width | number | codeSize的 10% | 图片宽度 |
height | number | codeSize的 10% | 图片高度 |
x | number | 水平居中 | 图片水平偏移量(左上角为原点) |
y | number | 垂直居中 | 图片垂直偏移量(左上角为原点) |
源码中的
QRCodeImageSettings接口还包含一个excavate: boolean字段(见 QRCode.tsx),表示是否挖空图片覆盖区域的码点以提升识别率,从类型定义看该能力由底层渲染库提供。
码眼与码点样式定制
从 1.x 起,amis 二维码组件支持对"码眼"(二维码四角的定位图案)和"码点"(承载数据的小方块)进行个性化定制,可用于品牌化二维码的外观设计。所有样式属性最终都会透传给底层渲染库的styleConfig(见 QRCode.tsx)。
- 码眼类型
eyeType:可配置default、rounded、circle - 码眼边框大小
eyeBorderSize:可配置default、sm、xs - 码眼边框颜色
eyeBorderColor与内部颜色eyeInnerColor:可分别配置,默认使用foregroundColor - 码点类型
pointType:可配置default、circle - 码点大小
pointSize:可配置default、sm、xs - 码点大小随机
pointSizeRandom:布尔值,开启后各码点大小会随机变化,营造更自然的视觉风格
完整效果对照示例:
{ "type": "page", "body": [{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeType": "rounded" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeType": "circle" } ] },{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeBorderSize": "sm" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeBorderSize": "xs" } ] },{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeBorderColor": "red" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeInnerColor": "blue" } ] },{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "pointType": "circle" } ] },{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "pointSize": "sm" }, { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "pointSize": "xs" } ] },{ "type": "hbox", "columns": [ { "type": "qr-code", "codeSize": 128, "value": "https://www.baidu.com", "eyeType": "rounded", "eyeBorderSize": "sm", "pointType": "circle", "pointSizeRandom": true } ] }] }设计提醒:码眼是扫码设备定位二维码的关键图案,对其做样式改造(尤其是颜色与形状)时,请确保仍保留足够的结构对比度,并进行真机扫码验证。
下载二维码(saveAs 动作)
自3.6.0版本起,二维码组件支持通过 amis 事件动作体系导出下载。其原理是:给二维码组件设置一个id,然后在其他组件(如按钮)的onEvent中触发saveAs动作并指定该componentId,即可把二维码保存为本地图片文件。
[ { "type": "action", "label": "下载二维码", "onEvent": { "click": { "actions": [ { "actionType": "saveAs", "componentId": "qr-code-download", "args": { "name": "download.png" } } ] } } }, { "type": "qr-code", "id": "qr-code-download", "codeSize": 128, "value": "https://www.baidu.com" } ]关键配置拆解:
componentId:目标二维码组件的id,必须与qr-code上的id一一对应;args.name:下载文件的文件名(可选)。传入.png后缀时导出 PNG 图片;不传时默认文件名为qr-code.png。
需要注意:该下载方式不支持嵌入图片的二维码,如果二维码配置了imageSettings,建议直接对页面截图保存。
从源码看,saveAs动作在 QRCode.tsx 的doAction中实现,且与mode渲染模式密切相关:
- canvas 模式(默认):获取容器内的
<canvas>元素,调用toBlob(..., 'image/png')生成 PNG 文件后通过saveAs下载;若args.name以.svg结尾还会被自动替换为.png(见 QRCode.tsx)。 - svg 模式:读取容器内
<svg>的innerHTML,重新包裹上带命名空间与viewBox的外层<svg>后,以image/svg+xml类型生成 Blob 下载,默认文件名为qr-code.svg(见 QRCode.tsx)。
因此实际下载得到的是 PNG(canvas 模式)还是 SVG(svg 模式)文件,取决于当前组件的mode配置。
关于事件动作的通用触发机制(actionType+componentId+args),可进一步参考 amis 的 事件动作文档。
属性表
以下为 QRCode 组件的完整属性清单(与文档属性表保持一致,并结合源码补充了部分实现细节):
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| type | string | "qr-code" | 指定为 QRCode 渲染器(源码别名qrcode亦可用) |
| mode | string | "canvas" | 渲染模式,有canvas和svg两种 |
| className | string | 外层 Dom 的类名 | |
| qrcodeClassName | string | 二维码的类名 | |
| codeSize | number | 128 | 二维码的宽高大小 |
| backgroundColor | string | "#fff" | 二维码背景色 |
| foregroundColor | string | "#000" | 二维码前景色 |
| level | string | "L" | 二维码纠错级别,有('L' 'M' 'Q' 'H')四种 |
| value | 模板 | "https://www.baidu.com" | 扫描二维码后显示的文本,如果要显示某个页面请输入完整 url("http://..."或"https://..."开头),支持使用模板 |
| imageSettings | object | QRCode 图片配置 | |
| imageSettings.src | string | 图片链接地址 | |
| imageSettings.width | number | 默认为codeSize的 10% | 图片宽度 |
| imageSettings.height | number | 默认为codeSize的 10% | 图片高度 |
| imageSettings.x | number | 默认水平居中 | 图片水平方向偏移量 |
| imageSettings.y | number | 默认垂直居中 | 图片垂直方向偏移量 |
| eyeType | string | "default" | 码眼类型,有default、circle、rounded三种 |
| eyeBorderColor | string | "#000000" | 码眼边框颜色 |
| eyeBorderSize | string | "default" | 码眼边框大小,有default、sm、xs三种 |
| eyeInnerColor | string | "#000000" | 码眼内部颜色 |
| pointType | string | "default" | 码点类型,有default、circle两种 |
| pointSize | string | "default" | 码点大小,有default、sm、xs三种 |
| pointSizeRandom | boolean | false | 码点大小随机 |
除上表外,从 AMISQRCodeSchema 的类型定义还可以看到两个文档表格未列出的实用属性:
name:string,关联字段名,可用于在表单中与数据字段绑定;placeholder:string,默认-,value为空时展示的占位内容。
动作表
当前组件对外暴露以下特性动作,其他组件可以通过指定actionType: 动作名称、componentId: 该组件id来触发这些动作,动作配置可以通过args: {动作配置项名称: xxx}来配置具体的参数,详细请查看事件动作。
| 动作名称 | 动作配置 | 说明 |
|---|---|---|
| saveAs | name?: string文件名 | 下载文档 |
附:渲染模式与测试验证
mode决定二维码最终的输出载体,默认canvas,可切换为svg。两种模式在 QRCode.test.tsx 中均有覆盖:
- svg 模式:断言渲染出
<svg>节点,且backgroundColor以background-color样式呈现、foregroundColor以fill属性呈现(QRCode.test.tsx); - 嵌入图片:断言
<image>节点存在、xlink:href已设置且x/y/width/height均大于 0(QRCode.test.tsx); - canvas 模式:默认渲染
<canvas>节点,并对toDataURL输出的图片数据进行了断言(QRCode.test.tsx)。
SnapShot 文件 QRCode.test.tsx.snap 中也保留了三种 svg 场景(默认、自定义颜色、嵌入图片)的完整 DOM 结构快照,可作为理解组件实际输出结构的参考。
选择建议:需要位图导出(PNG)时使用默认的canvas模式;需要无损矢量输出、便于放大或二次加工时选择svg模式,但需注意svg模式下saveAs下载的是.svg文件。
【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考