二维码

This commit is contained in:
曹磊 2025-07-10 17:57:51 +08:00
parent e65263cffb
commit dd18a1a720
3 changed files with 178 additions and 157 deletions

View File

@ -1,14 +1,13 @@
<template>
<div class="qrcode-container">
<main class="qrcode">
<div class="code" ref="code">
<!-- 直接绑定ref到QRCodeVue3组件 -->
<QRCodeVue3 ref="qrcodeInstance" render-as="canvas" :margin="margin" :width="width" :height="height" :value="value"
<QRCodeVue3 render-as="canvas" :margin="margin" :width="width" :height="height" :value="value"
:qrOptions="qrOptions" :image="image" :imageOptions="imageOptions" :dotsOptions="dotsOptions"
:backgroundOptions="backgroundOptions" :cornersSquareOptions="cornersSquareOptions"
:cornersDotOptions="cornersDotOptions" :key="key" />
<button @click="downloadQRCode" :disabled="isDownloading" class="download-btn">
{{ isDownloading ? '生成中...' : '下载二维码' }}
</button>
:cornersDotOptions="cornersDotOptions" :download="download" :buttonName="buttonName" :key="key" />
</div>
</main>
</template>
<script lang="ts" setup>
@ -16,11 +15,6 @@ import { ref, reactive, toRefs, nextTick } from 'vue'
import QRCodeVue3 from 'qrcode-vue3'
import type { PropType } from 'vue'
//
interface QRCodeExpose {
$el: HTMLCanvasElement
}
const props = defineProps({
key: {
type: String as PropType<string>,
@ -130,12 +124,17 @@ const props = defineProps({
]
}
})
}
},
download: {
type: Boolean as PropType<boolean>,
default: false,
},
buttonName: {
type: String as PropType<string>,
default: "下载二维码",
},
})
const qrcodeInstance = ref<QRCodeExpose | null>(null)
const isDownloading = ref(false)
const data = reactive({
key: props.key,
width: props.width,
@ -160,6 +159,8 @@ const data = reactive({
dotsOptions: props.dotsOptions,
cornersSquareOptions: props.cornersSquareOptions,
cornersDotOptions: props.cornersDotOptions,
download: props.download,
buttonName: props.buttonName,
})
const {
@ -174,60 +175,21 @@ const {
imageOptions,
dotsOptions,
cornersSquareOptions,
cornersDotOptions
cornersDotOptions,
download,
buttonName
} = toRefs(data)
const downloadQRCode = async () => {
isDownloading.value = true
await nextTick() // DOM
// img
const imgEl = qrcodeInstance.value?.$el?.querySelector?.('img')
if (imgEl && imgEl.src) {
const imgSrc = imgEl.src
const link = document.createElement('a')
link.href = imgSrc
link.download = 'qrcode.png'
link.click()
} else {
console.error('未找到二维码 img 或 src 为空')
}
isDownloading.value = false
}
</script>
<style scoped>
.qrcode-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
<style lang="less">
.qrcode {
.code {
padding: 8px;
width: 360px;
height: 360px;
border-radius: 6px;
border: 1px solid gray;
}
.download-btn {
padding: 8px 16px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
min-width: 120px;
}
.download-btn:hover {
background-color: #3aa876;
transform: translateY(-1px);
}
.download-btn:disabled {
background-color: #cccccc;
cursor: not-allowed;
transform: none;
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<QRCodeVue3
ref="qrcodeInstance"
margin="5"
width="400"
height="400"
:key="qrCodeKey"
:value="data.value"
:logo="data.logoImage"
download="true"
/>
<button @click="downloadQRCode" :disabled="isDownloading" class="download-btn">
{{ isDownloading ? '生成中...' : '下载二维码' }}
</button>
</template>
<script lang="ts" name="qrcode" setup>
import {computed, nextTick, reactive, ref} from "vue";
import { QRCodeVue3 } from '/@/components/QrcodeVue3';
import image from "@/assets/images/logo.png";
//
interface QRCodeExpose {
$el: HTMLCanvasElement
}
const data = reactive({
value: 'www.baidu.com',
logoImage: image,
})
const qrCodeKey = computed(()=>data.value.length + data.logoImage.length);
const qrcodeInstance = ref<QRCodeExpose | null>(null)
const isDownloading = ref(false)
const downloadQRCode = async () => {
isDownloading.value = true
await nextTick() // DOM
// img
const imgEl = qrcodeInstance.value?.$el?.querySelector?.('img')
if (imgEl && imgEl.src) {
const imgSrc = imgEl.src
const link = document.createElement('a')
link.href = imgSrc
link.download = 'qrcode.png'
link.click()
} else {
console.error('未找到二维码 img 或 src 为空')
}
isDownloading.value = false
}
</script>
<style lang="less">
.download-btn {
margin-top:20px;
padding: 8px 16px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
min-width: 120px;
}
.download-btn:hover {
background-color: #3aa876;
transform: translateY(-1px);
}
.download-btn:disabled {
background-color: #cccccc;
cursor: not-allowed;
transform: none;
}
</style>

View File

@ -1,113 +1,86 @@
<template>
<main class="qrcode">
<div class="form">
<input
type="text"
v-model="data.value"
placeholder="请在这里输入要生成的内容!"
@change="changeValue"
/>
<JImageUpload
text="上传LOGO"
ref="uploadRef"
v-model:value="data.logoImage"
@change="upFile"
/>
</div>
<div class="code" ref="code">
<QRCodeVue3
ref="qrcodeInstance"
margin="5"
width="400"
height="400"
:key="qrCodeKey"
:value="data.value"
:logo="data.logoImage"
download="true"
/>
</div>
</main>
<button @click="downloadQRCode" :disabled="isDownloading" class="download-btn">
{{ isDownloading ? '生成中...' : '下载二维码' }}
</button>
</template>
<script lang="ts" name="qrcode" setup>
import {computed, nextTick, reactive, ref} from "vue";
import { QRCodeVue3 } from '/@/components/QrcodeVue3';
import { JImageUpload } from '/@/components/Form/index';
import image from "@/assets/images/logo.png";
const uploadUrl = ref('');
//
interface QRCodeExpose {
$el: HTMLCanvasElement
}
const data = reactive({
value: 'www.baidu.com',
logoImage: image,
})
// const qrCodeKey = ref(0);
const qrCodeKey = computed(()=>data.value.length + data.logoImage.length);
// console.log(qrCodeKey.value);
function upFile(){
// console.log(data.logoImage);
// qrCodeKey.value = qrCodeKey.value + 1;
// console.log(qrCodeKey.value);
const qrcodeInstance = ref<QRCodeExpose | null>(null)
const isDownloading = ref(false)
const downloadQRCode = async () => {
isDownloading.value = true
await nextTick() // DOM
// img
const imgEl = qrcodeInstance.value?.$el?.querySelector?.('img')
if (imgEl && imgEl.src) {
const imgSrc = imgEl.src
const link = document.createElement('a')
link.href = imgSrc
link.download = 'qrcode.png'
link.click()
} else {
console.error('未找到二维码 img 或 src 为空')
}
function changeValue(){
// qrCodeKey.value = qrCodeKey.value + 1;
isDownloading.value = false
}
</script>
<style lang="less">
.qrcode {
.form {
margin: 30px auto;
width: 86%;
input {
box-sizing: border-box;
padding: 0 10px;
width: 80%;
height: 50px;
font-size: 18px;
border: 1px solid #767676;
border-radius: 6px 0 0 6px;
}
button {
box-sizing: border-box;
position: relative;
width: 20%;
height: 50px;
font-size: 18px;
vertical-align: top;
.download-btn {
margin-top:20px;
padding: 8px 16px;
background-color: #42b983;
color: white;
background: #42b983;
border: 1px solid #767676;
border-radius: 0 6px 6px 0;
border-left: none;
overflow: hidden;
border: none;
border-radius: 4px;
cursor: pointer;
input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0;
}
}
transition: all 0.3s ease;
font-size: 14px;
min-width: 120px;
}
.code {
margin: auto;
padding: 8px;
width: 360px;
height: 360px;
border-radius: 6px;
border: 1px solid gray;
.download-btn:hover {
background-color: #3aa876;
transform: translateY(-1px);
}
.download-btn:disabled {
background-color: #cccccc;
cursor: not-allowed;
transform: none;
}
</style>