下载依赖npm install --save qrcode
引入qrcode
如果报错 Could not find a declaration file for module 'qrcode'.
则只需在src下新建shims-vue.d.ts文件写入declare module 'qrcode'即可
准备一个canvas
<template>
<canvas ref="canvas"></canvas>
</template>
定义类型
interface Props {
value: string, // 二维码的内容值。
size?: number, // 二维码大小。
margin?: number, // 定义空白区的宽度应该是多少。
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H', // 维码的容错能力等级,取值为 'L', 'M', 'Q', 'H' 之一。
dark?: string,
light?: string,
}
纠错等级也叫纠错率,就是指二维码可以被遮挡后还能正常扫描,而这个能被遮挡的最大面积就是纠错率。 通常情况下二维码分为 4 个纠错级别:L级 可纠正约 7% 错误、M级 可纠正约 15% 错误、Q级 可纠正约 25% 错误、H级 可纠正约30% 错误。 并不是所有位置都可以缺损,像最明显的三个角上的方框,直接影响初始定位。中间零散的部分是内容编码,可以容忍缺损。 当二维码的内容编码携带信息比较少的时候,也就是链接比较短的时候,设置不同的纠错等级,生成的图片不会发生变化。
设置props默认值
const props = withDefaults(defineProps<Props>(), {
value: '',
size: 200,
margin: 5,
level: 'M',
light: '#fff',
dark: '#000',
})
获取canvas元素,需要在onMonuted之后才能获取得到canvas元素
const canvas = ref<HTMLCanvasElement | null>(null)
onMounted(() => {
const canvasDom = canvas.value as HTMLCanvasElement
// 第一个参数为 canvas画板
// 第二个参数为 我们想要把字符串转二维码的 字符串
// 第三个参数为 配置对象
// 第四个参数为 一个完成后的回调函数
QRCode.toCanvas(canvasDom, props.value, {
errorCorrectionLevel:props.errorCorrectionLevel,
width: props.size,
margin: props.margin,
color: {
dark: props.dark,
light: props.light
}
}, (error: any) => {
if (error) console.error(error)
console.log('success!');
})
})
详细配置可参照官网:
qrcode - npm (npmjs.com)
QRCode组件
<template>
<canvas ref="canvas"></canvas>
</template>
<script setup lang='ts'>
import QRCode from 'qrcode'
import { onUpdated, ref, defineProps } from 'vue';
interface Props {
value: string, // 二维码的内容值。
size?: number, // 二维码大小。
margin?: number, // 定义空白区的宽度应该是多少。
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H', // 维码的容错能力等级,取值为 'L', 'M', 'Q', 'H' 之一。
dark?: string, // 二维码前景颜色。
light?: string, // 二维码背景颜色。
}
const props = withDefaults(defineProps<Props>(), {
value: '',
size: 200,
margin: 5,
level: 'M',
light: '#fff',
dark: '#000',
})
const canvas = ref<HTMLCanvasElement | null>(null)
onUpdated(() => {
const canvasDom = canvas.value as HTMLCanvasElement
console.log(props.value, 'props.value');
QRCode.toCanvas(canvasDom, props.value, {
errorCorrectionLevel:props.errorCorrectionLevel,
width: props.size,
margin: props.margin,
color: {
dark: props.dark,
light: props.light
}
}, (error: any) => {
if (error) console.error(error)
console.log('success!');
})
})
</script>
在父组件中引用QRCode组件
<template>
<div class="qr-code-container">
<Qrcode v-bind="QRStyle"></Qrcode>
</div>
<div class="qr-code-info">打开网易云音乐APP扫码登录</div>
</template>
<script setup lang='ts'>
import { onBeforeMount, reactive, watch } from 'vue'
import { loginQrCodeKey, loginQrCodeCreate } from '@/api/auth'
import Qrcode from '@/components/Qrcode.vue'
// 二维码样式
const QRStyle = reactive({
value: '', // 生成二维码的字符串
width: '200px',
height: '200px',
margin: 0,
dark: '#335eea',
light: '#00000000',
})
onBeforeMount(async () => {
const getKey = await loginQrCodeKey()
const key: string = getKey.data.data.unikey
const result = await loginQrCodeCreate({ key }) // 请求得到二维码的字符串
QRStyle.value = result.data.data.qrurl
})
watch(()=>QRStyle.value , (val) => { // 监听二维码字符串的变化
QRStyle.value = val
})
</script>
<style scoped lang="scss">
.qr-code-container {
background-color: var(--color-primary-bg);
padding: 24px 24px 21px 24px;
border-radius: 1.25rem;
margin-bottom: 12px;
}
.qr-code-info {
color: var(--color-text);
text-align: center;
margin-bottom: 28px;
}
</style>
最后生成的效果图