使用场景:
根据用户的输入信息,批量生成二维码图片并下载,下载完成后删除对应的DOM元素
使用插件
vue-qr、html2canvas
使用技术
Vue.extend
当然可以将组件提前写入html中,但是实际需求中,提前写入标签可能会影响页面性能,以下只是个人在开发使用的一种方法
动态添加组件的方法:
import QrCodeImage from '@/ik-components/QrCodeImage.vue' // 待添加的组件
const codeArr = ['12', '13', '14', '15'] // 用户输入的,待生成二维码的数据
let numIndex = 0 // 计数器,确保所有的二维码都正常保存下载使用
const DomConstructor = Vue.extend(QrCodeImage) // 创建组件的构造函数
codeArr.forEach((item, index) => {
// 实例化组件
const domObj = new DomConstructor({
propsData: { // 组件内所需的参数
codeInfo: item,
uniqueId: index
}
})
// 建立虚拟Dom
domObj.$mount()
// 将Dom挂在到页面上,html2canvas所需
document.getElementById('app').appendChild(domObj.$el)
domObj
.toSave()
.then(() => {
domObj.$el.remove() // 保存下载成功后移除Dom元素
numIndex++ // 下载完成后计数器加一
if (numIndex === codeArr.length) console.log('全部成功')
})
.catch((err) => {
console.error('失败:', err)
})
})
生成二维码的组件:
待动态插入页面的组件
<template>
<div :id="'qrCodeImage' + uniqueId" class="qr_code_content">
<vue-qr :text="codeInfo" :size="240" />
<div class="qrcode_info_content">
{{ codeInfo }}
</div>
</div>
</template>
<script>
// https://www.npmjs.com/package/vue-qr
import VueQr from 'vue-qr'
import html2canvas from 'html2canvas'
export default {
name: 'QrCodeImage',
components: {
VueQr
},
props: {
// 待生成二维码的数据信息
codeInfo: {
type: String,
default: ''
},
// DOM元素的唯一ID
uniqueId: {
type: Number,
default: 0
}
},
methods: {
// 保存二维码
toSave() {
let resolveFunc, rejectFunc
const saveSuccessPromise = new Promise((resolve, reject) => {
resolveFunc = resolve
rejectFunc = reject
})
setTimeout(() => { // 确保二维码图片生成后才可进行保存下载操作
html2canvas(document.getElementById('qrCodeImage' + this.uniqueId))
.then((canvas) => {
const saveUrl = canvas.toDataURL('image/png')
const aLink = document.createElement('a')
const blob = this.base64ToBlob(saveUrl)
const evt = document.createEvent('HTMLEvents')
evt.initEvent('click', true, true)
aLink.download = `批量生成二维码-${this.codeInfo}.jpg`
aLink.href = URL.createObjectURL(blob)
aLink.click()
if (aLink.href) console.log(`二维码'${this.codeInfo}'保存成功`)
resolveFunc()
})
.catch(rejectFunc)
}, 0)
// 返回一个Promise对象,确保二维码图片正常/异常下载都会被记录
return saveSuccessPromise
},
// 图片转base64
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 lang="scss" scoped>
.qr_code_content {
width: 250px;
margin: 0 auto;
padding: 10px;
border-radius: 10px;
background: #ffffff;
border: #909399 1px solid;
display: flex;
align-items: center;
flex-direction: column;
}
.qrcode_info_content {
width: 100%;
padding: 0 5px;
color: #000000;
font-size: 20px;
font-weight: bold;
line-height: 22px;
text-align: center;
}
</style>