Skip to content

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&lt;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 纠错),仅支持字节模式(数字 / 字母模式的压缩优化不做过——浏览器与微信扫码器对字节模式二维码全兼容)。

记录 · 思考 · 创作