NQrcode 二维码
基于 Canvas 绘制的二维码生成组件:内容 / 尺寸 / 颜色 / 点阵形态 / 纠错级别全可配,支持中心图标、四周留白、像素级高分屏绘制与 png dataURL 导出;内置扫码业务状态层(生成中 / 已过期含刷新 / 已扫描)。
平台兼容性
| App(ANDROID) | App(IOS) | App(HARMONY) | WEB | 微信小程序 |
|---|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ | ✓ |
- 绘制通道分端:Web 端画布元素直取上下文,小程序端组件作用域选择器取节点,App 端异步上下文载体;导出统一 png dataURL。
- 中心图标支持网络与本地路径;微信端网络图标需在平台配置
downloadFile合法域名。
基本使用
html
<template>
<n-qrcode value="https://example.com" :size="200" />
</template>
内容动态更新(value 一变即重绘):
html
<template>
<n-qrcode :value="text" :size="220" @change="onChange" @error="onError" />
</template>
<script setup lang="uts">
const text = ref("https://example.com");
function onChange(value: string) {
// value 为当前绘制完成的内容
}
function onError(message: string) {
// 内容超出容量、图标加载失败等
}
</script>
中心带图标(纠错级别保持 H 保证可扫):
html
<n-qrcode value="https://example.com" icon="/static/logo.png" :icon-size="48" />
扫码业务状态层(过期 → 点击刷新,业务刷新 value 后把 status 置回空):
html
<template>
<n-qrcode :value="code" status="expired" expired-text="订单已过期" @refresh="onRefresh" />
</template>
<script setup lang="uts">
function onRefresh() {
// 请求新二维码内容,成功后 status = ''
}
</script>
导出图片:
html
<script setup lang="uts">
const qrRef = ref<NQrcodeComponentPublicInstance | null>(null);
async function save() {
const dataUrl = await qrRef.value!.toPng();
// png dataURL,可直接用作 image src 或自行转存
}
</script>
API
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | string | "" | 二维码内容(文本 / 链接 / 卡片数据),空值不绘制 |
| size | number | string | 200 | 边长 px(数字)或 px/rpx 字符串,组件恒正方形 |
| foreground | string | "#000000" | 数据点颜色 |
| background | string | "#ffffff" | 背景颜色 |
| pdColor | string | "" | 定位点(三个角上的回字形图案)颜色,留空跟随前景色 |
| pdRadius | number | 10 | 定位点圆角 px,0 为直角 |
| level | "L" / "M" / "Q" / "H" | "H" | 纠错级别(约 7% / 15% / 25% / 30% 可恢复);中心带图标时建议 H |
| icon | string | "" | 中心图标图片地址(网络 / 本地路径);点阵在中心让位(面积封顶 20%) |
| iconSize | number | 40 | 中心图标边长 px(建议不超过尺寸的 20%) |
| padding | number | 5 | 二维码四周留白 px |
| mode | "rect" / "circular" / "line" / "rectSmall" | "rect" | 点阵形态,rect 为标准实心方块 |
| status | "" / "loading" / "expired" / "scanned" | "" | 状态层:非空时在二维码上覆盖半透明状态面板 |
| loadingText | string | "" | 「生成中」文案,留空用内置词条 |
| expiredText | string | "" | 「已过期」文案,留空用内置词条 |
| scannedText | string | "" | 「已扫描」文案,留空用内置词条 |
| refreshText | string | "" | 过期状态刷新按钮文案,留空用内置词条 |
| customClass | string | "" | 根节点类名(类须定义在组件样式表内,如 n-qrcode--xxx) |
| customStyle | string | "" | 根节点行内样式,拼接在内部默认值之后可覆盖(含尺寸) |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
| ready | — | 首次绘制完成时触发(仅一次) |
| change | value: string |
二维码重绘完成时触发,参数为当前内容 |
| refresh | — | 点击过期状态层的刷新按钮时触发(业务刷新 value 后自行把 status 置回空) |
| longpress | — | 长按二维码时触发(可用于保存图片等) |
| error | message: string |
生成失败时触发:内容超出容量、图标加载失败或画布通道失败 |
插槽
| 插槽 | 说明 |
|---|---|
| loading | 生成中状态面板整区接管(替代内置文案) |
| expired | 过期状态面板整区接管(替代内置文案与刷新按钮;接管后刷新交互由插槽内容自行实现,不经组件 refresh 事件) |
| scanned | 已扫描状态面板整区接管(替代内置文案) |
实例方法
(通过 ref 直调)
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
| toPng | — | Promise<string> | 导出当前二维码为 png dataURL(三端一致);空内容或未绘制成功时返回空串 |
实现说明(参考做法 vs 本库做法)
| 机制 | 参考做法 | 本库做法 | 分歧理由 |
|---|---|---|---|
| 内容命名 | 一源 value(其一源 text) | value | 语义直白,两源多数命名 |
| 尺寸 | 一源 width/height 双 prop(绘制只按宽);另一源 rpx 400 | 单 size(number/px/rpx),正方形恒定 |
二维码必然正方形,双 prop 是假维度;单一事实源 |
| 定位点色 | 一源空值跟随前景色;另一源固定 #000000 | pdColor 空值跟随前景色 |
换前景色时固定定位点色会脱节 |
| 纠错级别 | 两源固定 H;另一源 level 可配 | level 可配、默认 H |
并集收录可配能力,默认取两源固定值 |
| 点阵形态 | 一源四形态默认圆点 | 四形态全收、默认 rect |
标准实心方块扫码兼容性最强,装饰形态显式选择 |
| 状态层 | 一源 status + 三插槽 + 三文案 | 全并集:status 三态、loading/expired/scanned 插槽、三文案 prop + 内置词条 | 扫码登录 / 支付过期场景完整能力 |
| 长按 | 一源 onLongpress;另一源 longclick | longpress 事件(画布通用长按事件转发) |
统一 uni 惯用事件名 |
| 导出 | 一源分端临时路径 / 对象 URL;另一源无导出 | toPng() png dataURL 三端一致 |
与本库签名 / 裁剪组件同源导出基建,临时路径方案依赖各端差异 API 无法统一 |
| 超容行为 | 参考实现静默截断内容产生可扫但错误的码(其源码自注 FIXME) | generateFrame 显式返回超容标志 → error 事件 + 不绘制 |
残码比报错危害大,根治参考实现已知缺陷 |
| 图标绘制 | 一源 Web new Image(uni-app x App 端无此构造器);另一源 nvue gcanvas |
官方跨平台 createImage()(Web 元素 / 其余端载体),加载失败发 error |
平台支持面以官方 canvas API 为准 |
| ready/change | 一源 ready 带画布 id、无 change;另一源 change 无参 | ready 仅首次;change 每次绘制成功带 value | ready 表示可用、change 表示更新,回调可直接取最新内容 |
| 触摸事件透传 | 另一源透传 touchStart/touchEnd | 不收录 | 无业务语义(画布触摸不含交互逻辑),业务可直接在组件外层监听 |
编码核心为 QR Code 标准公开算法的字节模式实现(UTF-8 内容、版本 1–40 自动选择、8 掩码择优、Reed–Solomon 纠错),仅支持字节模式(数字 / 字母模式的压缩优化不做过——浏览器与微信扫码器对字节模式二维码全兼容)。