第一、下载依赖包
npm install html2canvas --save
npm install jszip --save
npm install qrcodejs2-fix --save
npm install file-saver --save
第二步、组件封装
<template>
<div class="down-image">
<div id="qrid-box">
<img :src="bgImg" alt="" class="qdid-img" />
<div
class="code-box"
:class="{ 'left-center': leftDistance == 0 }"
:style="{
bottom: bottomDistance + 'px',
width: size + 'px',
height: size + 'px',
left: leftDistance == 0 ? '50%' : leftDistance + 'px',
}"
></div>
</div>
<div class="down-mask" v-show="isGenera">
{{ maskMessage }}
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import html2canvas from "html2canvas";
import JSZip from "jszip";
import QRcode from "qrcodejs2-fix";
import FileSaver from "file-saver";
const props = defineProps({
dataList: {
type: <any>Array,
required: true,
default: [],
},
url: {
type: String,
required: true,
default: "",
},
params: {
type: <any>Array,
required: true,
default: [],
},
bgImg: {
type: String,
required: true,
default: "",
},
size: {
type: Number,
required: false,
default: 120,
},
leftDistance: {
type: Number,
required: false,
default: 0,
},
bottomDistance: {
type: Number,
required: false,
default: 30,
},
});
const maskMessage = ref("正在批量生成中...");
const isGenera = ref(false);
let imgList: any[] = [];
const paramsHandel = (item: any) => {
let params = "?";
if (typeof props.params == "object") {
let arr = props.params;
arr.forEach((arrItem: any) => {
let str = `${arrItem}=${item[arrItem]}&`;
params = params + str;
});
} else {
console.warn("参数需要为数组类型");
}
if (params.indexOf("&") != -1) {
params = params.slice(0, params.length - 1);
}
return params;
};
const generaCode = (item: any) => {
let code: any = document.querySelector(".code-box");
code.innerHTML = "";
let params = paramsHandel(item);
let qrcode = new QRcode(code, {
text: props.url + params,
width: props.size - 30,
height: props.size - 30,
render: "table",
colorDark: "#333333",
colorLight: "#ffffff",
correctLevel: QRcode.CorrectLevel.H,
});
};
const generaZip = (list: any[]) => {
if (list.length <= 0) {
console.warn("dataList参数为空");
return;
}
var zip = new JSZip();
let num = 1;
for (const QRcodeIterator of list) {
zip.file(
`test_${num}.png`,
QRcodeIterator.imgurl.replace(/^data:image\/(png|jpg);base64,/, ""),
{ base64: true }
);
num++;
}
zip.generateAsync({ type: "blob" }).then(function (content: any) {
FileSaver(content, "二维码.zip");
});
isGenera.value = false;
};
const timmer = () => {
setTimeout(() => {
if (isGenera.value == true) {
maskMessage.value = "当前生成文件较多,请耐心等候...";
}
}, 5000);
setTimeout(() => {
if (isGenera.value == true) {
maskMessage.value = "文件还在努力生成...";
}
}, 10000);
};
const generateImg = async () => {
if (props.url == "") {
console.warn("url参数为空");
return;
}
isGenera.value = true;
timmer();
let qridElement: any = document.querySelector("#qrid-box");
for (const item of props.dataList) {
generaCode(item);
await html2canvas(qridElement).then(function (canvas) {
const qrContentImage = canvas.toDataURL("image/png", 1.0);
imgList.push({
imgurl: qrContentImage,
});
});
}
if (imgList.length > 0) {
generaZip(imgList);
}
};
const init = () => {
generateImg();
};
defineExpose({
init,
});
</script>
<style lang="scss" scoped>
.down-image {
position: absolute;
bottom: 0;
left: -9999999px;
width: 375px;
#qrid-box {
width: 100%;
.qdid-img {
width: 100%;
}
.code-box {
position: absolute;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 12px;
}
}
}
.left-center {
left: 50%;
transform: translateX(-50%);
}
.down-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 999999;
display: flex;
align-items: center;
justify-content: center;
color: #ffff;
font-size: 24px;
}
</style>
第三步、调用
<DownImage
:dataList="state.dataList"
:url="'https://www.baidu.com'"
:params="{one:'1'}"
:bgImg="bgImg"
:size="100"
ref="downImage"
></DownImage>
const downImage = ref(null);
downImage.value.init();
四、参数说明
参数名 | 参数类型 |
---|
dataList | [{}] 数组对象 必填 |
url | string 必填 |
params | [‘xxx’] 数组 必填 |
bgImg | string 必填 |
size | number 默认120 不必填 |
leftDistance | number 默认0 , 0代表水平居中 不必填 |
bottomDistance | number 默认30 不必填 |
五、事件
函数名 | 函数解释 |
---|
init | 生成并下载海报图;调用方法见第三步示例 |