SwQrcodeScanner
SwQrcodeScanner 提供图片上传 → 二维码识别能力。点击区域触发系统文件选择器,选取图片后在浏览器端完成解码,识别成功后在原位置展示图片预览。
UI 完全可定制:trigger slot 替换默认「+」图标,preview slot 替换默认预览图,二者均支持作用域插槽。
基础用法
点击虚线框选择含二维码的图片,识别成功后图片预览替换「+」图标,仍可点击重新上传。
基础用法
加载中...
自定义触发 UI
通过 trigger slot 替换默认「+」图标。Slot scope 暴露 loading(解码中)/ hasResult(已有结果)等状态,可驱动自定义 UI。
自定义 trigger slot
加载中...
自定义预览区
通过 preview slot 替换识别成功后的默认图片预览。Slot scope 暴露 result(解码文本)和 url(图片内存 URL)。
自定义 preview slot
加载中...
错误处理
error 事件携带 code 字段,可根据不同错误码做差异化提示;complete 事件在 success / error 之后必发,适合控制 loading 状态。
错误处理
加载中...
maxSize 限制 + reset()
加载中...
Props
| 名称 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
width | number | string | '8rem' | 容器宽度(数字按 px,字符串原样传入) | |
height | number | string | '8rem' | 容器高度(数字按 px,字符串原样传入) | |
iconSize | number | string | 32 | 默认「+」图标尺寸(数字按 px) | |
iconColor | string | 'var(--primary)' | 默认「+」图标颜色 | |
accept | string | 'image/png,image/jpeg,image/webp,image/gif,image/bmp' | input accept 白名单(逗号分隔),change 时二次校验 file.type | |
maxSize | number | 10 * 1024 * 1024 | 单文件最大字节数,超出 emit error(FILE_TOO_LARGE) | |
ariaLabel | string | '选择图片识别二维码' | 透明 input 的无障碍标签 | |
decodeTimeout | number | 8000 | 解码超时(ms)。upstream vue-qrcode-reader@5.x QrcodeCapture 对非二维码图片 decode promise 静默 reject(无 @error 事件),此 timeout 兜底 emit error(NO_QRCODE) + complete,避免业务 loading 永挂 |
CSS 变量(可在父级直接覆盖,无需传 prop):
| 变量 | 默认值 | 说明 |
|---|---|---|
--sw-qrcode-scanner-width | 8rem | 扫描区宽度 |
--sw-qrcode-scanner-height | 8rem | 扫描区高度 |
--sw-qrcode-scanner-icon-size | 2rem | 中央图标尺寸 |
--sw-qrcode-scanner-icon-color | var(--primary) | 中央图标颜色 |
Slots
| 插槽名 | 说明 |
|---|---|
trigger | 上传引导 UI,scope: { hasResult, result, url, loading };默认「+」SVG |
preview | 识别成功后展示区,scope: { result, url };默认 <img> |
Events
| 事件名 | 载荷类型 | 说明 |
|---|---|---|
start | void | 文件通过校验、URL 已建、解码前 |
success | payload: { result: string; url: string; allResults: string[] } | 至少识别到一个二维码 |
error | payload: { message: string; code: 'NO_QRCODE' | 'INVALID_FORMAT' | 'FILE_TOO_LARGE' | 'DECODE_ERROR' } | 4 种错误码:未识别 / 格式不支持 / 超大 / 解码异常 |
complete | void | success 或 error 之后必发 |
success.result 为首个识别码,success.allResults 为图片中全部识别码的数组(单码场景长度为 1)。
Exposed Methods
| 方法 | 说明 |
|---|---|
reset() | 清除已有结果并撤销图片内存 URL,恢复初始「+」状态 |
注意事项
- 文件 MIME 二次校验:浏览器的
accept属性可被绕过,组件在change事件处理中会再次检查file.type,不匹配直接error(INVALID_FORMAT)。 - 内存管理:图片内存 URL 通过
URL.createObjectURL创建,组件在重新上传 /reset()/ 卸载时均会自动URL.revokeObjectURL,无需手动释放。 - 层级原理:透明
QrcodeCapture始终覆盖在最上层,确保在有预览图的状态下点击仍能重新选择文件。 - decodeTimeout 兜底:upstream
vue-qrcode-reader@5.xQrcodeCapture内部对非二维码图片的 decode promise 静默 reject(无@error事件),导致@detect永不触发 → 业务侧 loading 状态机一直转。 组件默认 8s 超时后自动 emiterror({ code: 'NO_QRCODE' })+complete,业务无需自己加 setTimeout。 慢网络 / 大图场景可调高decodeTimeout。