更新记录
1.0.0(2026-03-18)
--
平台兼容性
uni-app(5.0)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Chrome插件版本 | Safari | Safari插件版本 | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | 5.0 | 1.0.0 | 12 | 1.0.0 | - |
| 微信小程序 | 微信小程序插件版本 | 支付宝小程序 | 支付宝小程序插件版本 | 抖音小程序 | 抖音小程序插件版本 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | - | - | - | - | - | - | - | - | - |
uni-app x(5.03)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
ry-qrcode
一款功能强大的 UniApp 二维码生成组件,支持自定义颜色、渐变色、圆角、Logo 等特性,兼容多端。
功能特性
- 纯 Canvas 绘制,无第三方依赖
- 支持生成标准二维码,可被微信、支付宝等主流 App 识别
- 支持自定义颜色(单色/渐变色)
- 支持随机颜色和随机样式
- 支持自定义圆角码点
- 支持添加 Logo(自动提升容错级别)
- 支持导出图片和 Base64
- 支持多种容错级别(L/M/Q/H)
- 全端兼容:H5、微信小程序、支付宝小程序、App 等
安装
方式一:HBuilderX 插件市场导入
在 HBuilderX 中,点击菜单 工具 -> 插件安装 -> 前往插件市场安装,搜索 ry-qrcode 导入。
方式二:手动安装
将 ry-qrcode 文件夹复制到项目的 uni_modules 目录下。
基础用法
<template>
<view>
<ry-qrcode
ref="qrcodeRef"
text="https://uniapp.dcloud.net.cn"
:width="200"
:height="200"
/>
</view>
</template>
<script>
export default {
methods: {
// 保存二维码图片
async save() {
const filePath = await this.$refs.qrcodeRef.save()
console.log('图片路径:', filePath)
}
}
}
</script>
Props 属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| text | String | '' | 必填,二维码内容(文本或链接) |
| width | Number | 260 | 二维码宽度(单位:px) |
| height | Number | 260 | 二维码高度(单位:px) |
| bgColor | String | '#ffffff' | 背景颜色 |
| level | String | 'M' | 容错级别:L(7%)、M(15%)、Q(25%)、H(30%) |
| radius | Number | 6 | 码点圆角半径(单位:px) |
| logo | String | '' | Logo 图片路径(支持本地路径和网络路径) |
| logoSize | Number | 60 | Logo 尺寸(单位:px),实际会限制为二维码宽度的 20% |
| logoRadius | Number | 8 | Logo 圆角半径(单位:px) |
| autoRandomColor | Boolean | true | 是否自动随机颜色 |
| color | String | '' | 自定义颜色(单色模式) |
| colorStart | String | '' | 渐变起始色 |
| colorEnd | String | '' | 渐变结束色 |
颜色优先级
- 如果设置了
color、colorStart或colorEnd,则使用自定义颜色 - 如果
autoRandomColor为true且未设置自定义颜色,则自动随机颜色 - 单色模式:只设置
color - 渐变模式:设置
colorStart和colorEnd
Events 事件
| 事件名 | 参数 | 说明 |
|---|---|---|
| ready | - | 二维码初始化完成时触发 |
| colorChange | colorInfo | 颜色变化时触发 |
colorChange 事件参数
{
start: '#1677FF', // 渐变起始色
end: '#722ED1', // 渐变结束色
primary: '#1677FF' // 主色调
}
Methods 方法
通过 ref 调用组件方法:
this.$refs.qrcodeRef.methodName()
| 方法名 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| save() | - | Promise\<string> | 保存二维码为临时文件,返回文件路径 |
| getBase64() | - | Promise\<string> | 获取二维码 Base64 数据 |
| refresh() | - | Promise | 手动刷新二维码 |
| refreshColor() | - | Promise | 刷新颜色(随机模式下随机新颜色) |
| randomStyle() | - | Promise | 随机更换样式(颜色+圆角) |
| setColor(color, colorEnd?) | color: 主色, colorEnd: 结束色 | Promise | 设置自定义颜色 |
| getColors() | - | Object | 获取当前颜色信息 |
| getRadius() | - | Number | 获取当前圆角值 |
使用示例
1. 基础二维码
<ry-qrcode text="Hello World" />
2. 自定义尺寸和颜色
<ry-qrcode
text="https://example.com"
:width="300"
:height="300"
color="#1677FF"
:autoRandomColor="false"
/>
3. 渐变色二维码
<ry-qrcode
text="https://example.com"
colorStart="#1677FF"
colorEnd="#722ED1"
:autoRandomColor="false"
/>
4. 带 Logo 的二维码
<ry-qrcode
text="https://example.com"
logo="/static/logo.png"
:logoSize="50"
:logoRadius="8"
/>
注意:添加 Logo 时,组件会自动使用 H 级别容错(30%),以确保二维码可被正常识别。
5. 自定义圆角
<!-- 方形码点 -->
<ry-qrcode
text="https://example.com"
:radius="0"
/>
<!-- 圆形码点 -->
<ry-qrcode
text="https://example.com"
:radius="10"
/>
6. 监听就绪事件
<template>
<ry-qrcode
ref="qrcodeRef"
text="https://example.com"
@ready="onQrcodeReady"
/>
</template>
<script>
export default {
methods: {
onQrcodeReady() {
console.log('二维码已就绪,可以安全调用方法了')
// 此时可以安全地调用 save()、getBase64() 等方法
}
}
}
</script>
7. 保存图片到相册
async saveToAlbum() {
try {
const filePath = await this.$refs.qrcodeRef.save()
// #ifdef H5
uni.showModal({
title: '提示',
content: 'H5端请长按图片保存',
showCancel: false
})
// #endif
// #ifndef H5
uni.saveImageToPhotosAlbum({
filePath: filePath,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' })
},
fail: (err) => {
console.error('保存失败', err)
uni.showToast({ title: '保存失败', icon: 'none' })
}
})
// #endif
} catch (e) {
console.error('获取图片失败', e)
}
}
8. 获取 Base64 数据
async getBase64Data() {
try {
const base64 = await this.$refs.qrcodeRef.getBase64()
console.log('Base64 数据:', base64)
// 可用于上传到服务器或其他用途
} catch (e) {
console.error('获取失败', e)
}
}
9. 随机样式
// 随机更换颜色
this.$refs.qrcodeRef.refreshColor()
// 随机更换样式(颜色+圆角)
this.$refs.qrcodeRef.randomStyle()
10. 动态设置颜色
// 设置单色
this.$refs.qrcodeRef.setColor('#FF5500')
// 设置渐变色
this.$refs.qrcodeRef.setColor('#1677FF', '#722ED1')
11. 获取当前颜色(可用于同步页面背景)
<template>
<view :style="{ background: pageBg }">
<ry-qrcode
ref="qrcodeRef"
text="https://example.com"
@colorChange="onColorChange"
/>
</view>
</template>
<script>
export default {
data() {
return {
pageBg: '#ffffff'
}
},
methods: {
onColorChange(colorInfo) {
// 使用二维码颜色作为页面背景
this.pageBg = `linear-gradient(135deg, ${colorInfo.start}, ${colorInfo.end})`
}
}
}
</script>
完整示例
<template>
<view class="container" :style="{ background: pageBgStyle }">
<view class="header">
<text class="title" :style="{ color: titleColor }">二维码生成器</text>
</view>
<!-- 二维码展示区域 -->
<view class="qrcode-wrapper">
<ry-qrcode
ref="qrcodeRef"
:text="qrText"
:width="qrSize"
:height="qrSize"
:level="errorLevel"
:radius="cornerRadius"
:logo="logoUrl"
:logoSize="logoSize"
:autoRandomColor="autoColor"
:color="customColor"
:colorStart="gradientStart"
:colorEnd="gradientEnd"
@colorChange="onColorChange"
@ready="onQrcodeReady"
/>
</view>
<!-- 输入区域 -->
<view class="input-section">
<input v-model="qrText" placeholder="请输入文本或链接" />
<input v-model="logoUrl" placeholder="Logo图片地址(可选)" />
</view>
<!-- 操作按钮 -->
<view class="action-section">
<button @click="randomStyle">随机样式</button>
<button @click="refreshColor">换颜色</button>
<button @click="saveQrcode">保存图片</button>
<button @click="getBase64Data">获取Base64</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
qrText: 'https://uniapp.dcloud.net.cn',
qrSize: 220,
cornerRadius: 6,
logoUrl: '/static/logo.png',
logoSize: 50,
errorLevel: 'H',
autoColor: true,
customColor: '',
gradientStart: '',
gradientEnd: '',
pageColorStart: '#1677FF',
pageColorEnd: '#0056D2',
isReady: false
}
},
computed: {
pageBgStyle() {
return `linear-gradient(180deg, ${this.hexToRgba(this.pageColorStart, 0.15)} 0%, ${this.hexToRgba(this.pageColorEnd, 0.05)} 100%)`
},
titleColor() {
return this.pageColorStart
}
},
methods: {
onQrcodeReady() {
this.isReady = true
},
onColorChange(colorInfo) {
this.pageColorStart = colorInfo.start
this.pageColorEnd = colorInfo.end
},
refreshColor() {
this.$refs.qrcodeRef.refreshColor()
},
randomStyle() {
this.$refs.qrcodeRef.randomStyle()
},
async saveQrcode() {
if (!this.isReady) return
try {
const filePath = await this.$refs.qrcodeRef.save()
// #ifndef H5
uni.saveImageToPhotosAlbum({
filePath,
success: () => uni.showToast({ title: '保存成功', icon: 'success' }),
fail: () => uni.showToast({ title: '保存失败', icon: 'none' })
})
// #endif
// #ifdef H5
uni.showModal({ title: '提示', content: 'H5端请长按图片保存', showCancel: false })
// #endif
} catch (e) {
uni.showToast({ title: '操作失败', icon: 'none' })
}
},
async getBase64Data() {
if (!this.isReady) return
try {
const base64 = await this.$refs.qrcodeRef.getBase64()
console.log('Base64:', base64.substring(0, 100) + '...')
uni.showToast({ title: '获取成功', icon: 'success' })
} catch (e) {
uni.showToast({ title: '获取失败', icon: 'none' })
}
},
hexToRgba(hex, alpha) {
if (!hex) return `rgba(0,0,0,${alpha})`
hex = hex.replace('#', '')
if (hex.length === 3) {
hex = hex.split('').map(c => c + c).join('')
}
const r = parseInt(hex.substring(0, 2), 16)
const g = parseInt(hex.substring(2, 4), 16)
const b = parseInt(hex.substring(4, 6), 16)
return `rgba(${r},${g},${b},${alpha})`
}
}
}
</script>
平台兼容性
| 平台 | 支持情况 | 备注 |
|---|---|---|
| H5 | ✅ | 完全支持 |
| 微信小程序 | ✅ | 完全支持 |
| 支付宝小程序 | ✅ | 完全支持 |
| 百度小程序 | ✅ | 完全支持 |
| 抖音小程序 | ✅ | 完全支持 |
| QQ 小程序 | ✅ | 完全支持 |
| App (iOS) | ✅ | 完全支持 |
| App (Android) | ✅ | 完全支持 |
注意事项
1. Logo 相关
- Logo 尺寸会自动限制为二维码宽度的 20%,以确保识别率
- 添加 Logo 时自动使用 H 级别容错
- Logo 区域不会绘制二维码数据点,确保不影响识别
- H5 端使用网络图片作为 Logo 时,需确保图片支持跨域
2. 保存图片
- H5 端无法直接保存到相册,需引导用户长按保存
- 小程序端需要用户授权相册权限
- App 端需要在 manifest.json 中配置相册权限
3. 性能优化
- 组件内部有防并发绘制机制,频繁修改属性不会导致多次重绘
- 建议在
@ready事件触发后再调用save()或getBase64()方法 - 大尺寸二维码(>500px)可能会有轻微延迟
4. 容错级别说明
| 级别 | 容错率 | 说明 |
|---|---|---|
| L | 7% | 低容错,适合无遮挡场景 |
| M | 15% | 中等容错,默认级别 |
| Q | 25% | 较高容错 |
| H | 30% | 最高容错,适合添加 Logo |
5. 扫码识别
生成的二维码符合 QR Code 标准,可被以下 App 识别:
- 微信
- 支付宝
- 抖音
- 系统相机
- 其他标准二维码扫描器
常见问题
Q: 二维码无法被扫描识别?
A: 请检查以下几点:
- 二维码内容是否正确
- 如果有 Logo,确保 Logo 不超过二维码的 20%
- 颜色对比度是否足够(避免浅色前景+浅色背景)
- 尝试使用更高的容错级别
Q: H5 端保存图片失败?
A: H5 端浏览器限制,无法直接保存图片到本地。建议提示用户长按二维码图片保存,或使用 getBase64() 获取数据后上传到服务器生成下载链接。
Q: Logo 图片不显示?
A: 请检查以下几点:
- 图片路径是否正确
- 网络图片是否支持跨域(H5 端)
- 小程序端网络图片需配置合法域名
Q: 如何动态修改二维码内容?
A: 直接修改 text 属性即可,组件会自动重新绘制:
this.qrText = 'https://new-url.com'
Q: 颜色不生效?
A: 如果设置了自定义颜色但不生效,请确保:
autoRandomColor设置为false- 颜色格式正确(如
#1677FF)
更新日志
v1.0.2
- 修复多端兼容性问题
- 优化 canvas 渲染回调机制
- 添加 width/height/radius 等属性的 watch 监听
- 添加保存和 Base64 获取的重试机制
- 优化 Logo 加载使用运行时平台检测
v1.0.1
- 修复 Logo 遮挡导致无法识别的问题
- 添加自定义颜色支持(单色/渐变)
- 添加随机样式功能
- 添加 ready 事件
- 添加重试机制提高稳定性
v1.0.0
- 初始版本发布
- 支持基础二维码生成
- 支持圆角、渐变、Logo
- 支持导出图片和 Base64
License
MIT License
反馈与支持
如有问题或建议,欢迎提交 Issue 或 PR。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 4
赞赏 0
下载 11421196
赞赏 1879
赞赏
京公网安备:11010802035340号