vue生成二维码
需求:
1.根据后端返回的图片地址,生成带logo的二维码
2.支持单个下载及批量下载
根据需求,最先想到的是使用qrcode,但qrcode不支持生成带logo,所以决定使用vue-qr来实现这个功能
注意:本文主要介绍的的vue-qr在vue2项目中的使用方法
先上效果图
vue-qr
1.安装
npm install vue-qr --save
2.在页面中引入
import VueQr from 'vue-qr'
3.在components中注册
components: { VueQr },
4.生成二维码
<el-table-column label="二维码">
<template slot-scope="scope">
<div class="qrCode">
<vue-qr
ref="qr"
:logo-src="scope.row.imgLogo"
:text="scope.row.imgUrl"
:size="100"
:margin="0"
/>
</div>
</template>
</el-table-column>
单个二维码下载
saveCode(data) {
const fileName = data.name
const img = this.$refs.qr.imgUrl
const aLink = document.createElement('a')
const blob = this.base64ToBlob(img)
const evt = document.createEvent('HTMLEvents')
evt.initEvent('click', true, true)
aLink.download = fileName
aLink.href = URL.createObjectURL(blob)
aLink.click()
},
// base64转blob
base64ToBlob(code) {
const parts = code.split(';base64,')
const contentType = parts[0].split(':')[1]
const raw = window.atob(parts[1])
const rawLength = raw.length
const uInt8Array = new Uint8Array(rawLength)
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i)
}
return new Blob([uInt8Array], { type: contentType })
},
多个文件导出为一个zip格式
1.安装
npm install jszip
npm install file-saver
2.在页面中引入
import JSZip from "jszip";
import FileSaver from "file-saver";
3.批量下载
// 选中表格数据
selectTable(val) {
val.map((item, index) => {
var oQrcode = document.querySelectorAll('.qrCode img')
item.href = oQrcode[index].src
})
this.images = val
},
//批量下载
doDownfiles() {
const that = this
const zip = new JSZip()
const cache = {}
setTimeout(_ => {
const arr = that.images
arr.forEach((item, index) => {
const fileName = item.name
zip.file(fileName + '.png', item.href.substring(22), {
base64: true
})
cache[fileName] = item.href
})
zip.generateAsync({ type: 'blob' }).then(content => {
FileSaver.saveAs(content, '小程序二维码.zip')
})
}, 0)
},
完整代码
<template>
<div class="content">
<el-button
@click="doDownFiles()"
type="primary"
size="small"
style="margin: 10px"
>批量下载</el-button
>
<el-table
:data="tableData"
border
style="width: 100%"
@selection-change="selectTable"
>
<el-table-column type="selection"></el-table-column>
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
<el-table-column label="二维码">
<template slot-scope="scope">
<div class="qrCode">
<vue-qr
ref="qr"
:logo-src="scope.row.imgLogo"
:text="scope.row.imgUrl"
:size="100"
:margin="0"
/>
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="saveCode(scope.row)"
>下载</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import VueQr from "vue-qr";
export default {
data() {
return {
images: [],
tableData: [
{
date: "2016-05-02",
name: "王小虎1",
address: "上海市普陀区金沙江路 1518 弄",
imgUrl:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
imgLogo:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
},
{
date: "2016-05-04",
name: "王小虎2",
address: "上海市普陀区金沙江路 1517 弄",
imgUrl:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
imgLogo:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
},
{
date: "2016-05-01",
name: "王小虎3",
address: "上海市普陀区金沙江路 1519 弄",
imgUrl:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
imgLogo:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
},
{
date: "2016-05-03",
name: "王小虎4",
address: "上海市普陀区金沙江路 1516 弄",
imgUrl:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
imgLogo:
"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
},
],
};
},
components: { VueQr },
methods: {
selectTable(val) {
val.map((item, index) => {
var oQrcode = document.querySelectorAll(".qrCode img");
item.href = oQrcode[index].src;
});
this.images = val;
},
doDownfiles() {
const that = this;
const zip = new JSZip();
const cache = {};
setTimeout((_) => {
const arr = that.images;
console.log(that.images, "that.images");
arr.forEach((item, index) => {
const fileName = item.name;
zip.file(fileName + ".png", item.href.substring(22), {
base64: true,
});
cache[fileName] = item.href;
});
zip.generateAsync({ type: "blob" }).then((content) => {
FileSaver.saveAs(content, "二维码.zip");
});
}, 0);
},
// 单个下载
saveCode(data) {
const fileName = data.name;
const img = this.$refs.qr.imgUrl;
const aLink = document.createElement("a");
const blob = this.base64ToBlob(img);
const evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true);
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.click();
},
// base64转blob
base64ToBlob(code) {
const parts = code.split(";base64,");
const contentType = parts[0].split(":")[1];
const raw = window.atob(parts[1]);
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
},
},
};
</script>
<style>
.content {
padding: 20px;
background-color: #ffffff;
}
</style>