113 lines
2.4 KiB
Vue
113 lines
2.4 KiB
Vue
<template>
|
||
<canvas v-if="value" :type="type" :style="{width: size + 'px', height: size + 'px'}" :canvas-id="canvasId"
|
||
ref="qrcodeCanvas"></canvas>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
ref,
|
||
onMounted,
|
||
watch
|
||
} from 'vue';
|
||
import {
|
||
uqrcode
|
||
} from 'uqrcodejs'
|
||
|
||
const props = defineProps({
|
||
// 二维码内容(必填,如链接/文本)
|
||
value: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 尺寸(默认300px)
|
||
size: {
|
||
type: [Number, String],
|
||
default: 300
|
||
},
|
||
// 二维码颜色
|
||
color: {
|
||
type: String,
|
||
default: '#000000'
|
||
},
|
||
// 背景色
|
||
backgroundColor: {
|
||
type: String,
|
||
default: '#ffffff'
|
||
},
|
||
// logo图片地址
|
||
logo: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// logo大小(占二维码比例)
|
||
logoSize: {
|
||
type: Number,
|
||
default: 0.2
|
||
},
|
||
// canvas 类型(小程序需指定)
|
||
type: {
|
||
type: String,
|
||
default: '2d'
|
||
},
|
||
// canvas ID(避免重复)
|
||
canvasId: {
|
||
type: String,
|
||
default: 'uqrcode'
|
||
}
|
||
});
|
||
|
||
const emit = defineEmits(['success', 'fail']);
|
||
const qrcodeCanvas = ref(null);
|
||
|
||
// 生成二维码核心方法
|
||
const createQRCode = async () => {
|
||
if (!props.value) return;
|
||
|
||
try {
|
||
// 引入uQRCode核心库
|
||
const uQRCode = require('uqrcodejs');
|
||
|
||
// 获取canvas上下文
|
||
const query = uni.createSelectorQuery().in(getCurrentInstance());
|
||
const res = await query.select(`#${props.canvasId}`).fields({
|
||
node: true,
|
||
size: true
|
||
}).exec();
|
||
const canvas = res[0].node;
|
||
const ctx = canvas.getContext('2d');
|
||
|
||
// 设置canvas尺寸
|
||
const dpr = uni.getSystemInfoSync().pixelRatio;
|
||
canvas.width = props.size * dpr;
|
||
canvas.height = props.size * dpr;
|
||
ctx.scale(dpr, dpr);
|
||
|
||
// 生成二维码
|
||
await uQRCode.default.draw({
|
||
canvas: canvas,
|
||
componentInstance: getCurrentInstance(),
|
||
text: props.value,
|
||
width: props.size,
|
||
color: props.color,
|
||
background: props.backgroundColor,
|
||
logo: props.logo,
|
||
logoSize: props.logoSize
|
||
});
|
||
|
||
// 生成临时图片(可选,用于分享/保存)
|
||
uni.canvasToTempFilePath({
|
||
canvasId: props.canvasId,
|
||
success: (res) => emit('success', res.tempFilePath),
|
||
fail: (err) => emit('fail', err)
|
||
}, getCurrentInstance());
|
||
} catch (err) {
|
||
emit('fail', err);
|
||
}
|
||
};
|
||
|
||
// 监听value变化,重新生成
|
||
watch(() => props.value, () => createQRCode(), {
|
||
immediate: true
|
||
});
|
||
onMounted(() => createQRCode());
|
||
</script> |