Appearance
二维码解决方案
二维码由服务端生成,前端无需考虑。
vue-qrcode
todo
qrcode
国外开源,使用率较高,稳定,跨平台
但是原生不支持中间logo,需要自己实现
https://www.npmjs.com/package/qrcode
html 使用需要使用 canvas
html
<canvas v-if="props.qr" class="qr-code" ref="model-qr-code"></canvas>ts
import { throttle } from '@/util'
import qrcode, { type QRCodeRenderersOptions } from 'qrcode'
import { useTemplateRef, nextTick } from 'vue'
import logo from '@/assets/logo.ico'
export const useQRCode = (refName: string, conf: QRCodeRenderersOptions = {}) => {
const qrdom = useTemplateRef(refName)
const addLogo = (canvas?: HTMLCanvasElement) => {
if (!canvas || !canvas.getContext) return
const ctx = canvas.getContext('2d')
if (!ctx) return
const img = new Image()
img.crossOrigin = 'Anonymous' //解决Canvas.toDataURL 图片跨域问题
img.src = logo
img.onload = () => {
const codeWidth = (canvas.clientWidth * 0.75) / 2
const codeHeight = (canvas.clientHeight * 0.75) / 2
ctx.drawImage(
img,
codeWidth,
codeHeight,
canvas.clientWidth * 0.25,
canvas.clientHeight * 0.25
)
}
}
const setQRCode = (url: string) => {
if (!qrdom || !qrdom.value) {
return nextTick(() => {
setQRCode(url)
})
}
qrcode.toCanvas(
qrdom.value,
url,
{
errorCorrectionLevel: 'H',
margin: 0,
...conf
},
(error: any) => {
if (error) {
console.error(error)
} else {
addLogo(qrdom.value as HTMLCanvasElement)
}
}
)
}
return { setQRCode: throttle(setQRCode, 100) }
}参考:https://www.guijiaow.com/2024/08/8816.html
qrcodejs2
vue3中有bug,使用qrcodejs2-fix
html 使用需要使用 div
ts
// qrcodejs2 无法使用会出现 Cannot read properties of undefined (reading '_android')
// 先使用 qrcodejs2-fix 处理
// @ts-ignore
import { throttle } from '@/util'
// @ts-ignore
import QRCode from 'qrcodejs2-fix'
import { useTemplateRef, nextTick } from 'vue'
export const useQRCode = (refName: string, conf: QRCodeRenderersOptions = {}) => {
let lastQRCode: any
const qrdom = useTemplateRef(refName)
const setQRCode = (url: string) => {
// console.log('qr div is', qrdiv.value)
if (!qrdom || !qrdom.value) {
return nextTick(() => {
setQRCode(url)
})
}
if (lastQRCode) {
lastQRCode.clear()
}
lastQRCode = new QRCode(qrdiv.value, {
text: url,
width: 200,
height: 200
})
return { setQRCode: throttle(setQRCode, 100) }
}