因为项目使用的是vue2,下面那个组件,大佬没有写canvas的生成二维码+logo的形式。
所以跟着大佬的vue3的代码,写了一遍vue2的。
vue3 直接安装使用
npm install qrcode@1 @chenfengyuan/vue-qrcode@2
vue2参考下面
npm install qrcode@1
组件:QrcodeComponent.vue
<template>
<div>
<canvas id="canvas" v-if="tag === 'canvas'"></canvas>
<img id="img" v-if="tag === 'image'"/>
<svg id="svg" v-if="tag === 'svg'"></svg>
</div>
</template>
<script>
import { toCanvas, toDataURL, toString } from 'qrcode'
export default {
props: {
value: {
type: String,
default: undefined
},
options: {
type: Object,
default: undefined
},
tag: {
type: String,
default: 'canvas'
}
},
mounted () {
this.generate()
},
methods: {
generate () {
const options = this.options || {}
const value = String(this.value)
const canvas = document.getElementById('canvas')
const img = document.getElementById('img')
const svg = document.getElementById('svg')
switch (this.tag) {
case 'canvas':
toCanvas(canvas, value, options, (error) => {
if (error) {
throw error
}
this.$emit('ready', canvas)
})
break
case 'image':
toDataURL(value, options, (error, url) => {
if (error) {
throw error
}
img.src = url
})
break
case 'svg':
toString(value, options, (error, string) => {
if (error) {
throw error
}
const div = document.createElement('div')
div.innerHTML = string
const svgEle = div.querySelector('svg')
if (svgEle) {
const { attributes, childNodes } = svgEle
Object.keys(attributes).forEach(key => {
const attribute = attributes[Number(key)]
svg.setAttribute(attribute.name, attribute.value)
})
Object.keys(childNodes).forEach(key => {
const childNode = childNodes[Number(key)]
svg.appendChild(childNode.cloneNode(true))
})
div.remove()
}
})
}
}
}
}
</script>
使用组件
<template>
<QrcodeComponent
:value="value"
:options="{
errorCorrectionLevel: 'Q',
width: 200,
}"
tag="canvas"
@ready="onReady"
></QrcodeComponent>
</template>
<script>
import QrcodeComponent from './QrcodeComponent.vue'
export default {
components: {
QrcodeComponent
},
data () {
return {
value: '222222'
}
},
methods: {
onReady (canvas) {
const context = canvas.getContext('2d')
const image = new Image()
image.src = 'https://avatars.githubusercontent.com/u/3456749'
image.crossorigin = 'anonymous'
image.onload = () => {
const coverage = 0.15
const width = Math.round(canvas.width * coverage)
const x = (canvas.width - width) / 2
this.drawImage(context, image, x, x, width, width)
}
},
drawImage (context, image, x, y, width, height, radius = 4) {
context.shadowOffsetX = 0
context.shadowOffsetY = 2
context.shadowBlur = 4
context.shadowColor = '#00000040'
context.lineWidth = 8
context.beginPath()
context.moveTo(x + radius, y)
context.arcTo(x + width, y, x + width, y + height, radius)
context.arcTo(x + width, y + height, x, y + height, radius)
context.arcTo(x, y + height, x, y, radius)
context.arcTo(x, y, x + width, y, radius)
context.closePath()
context.strokeStyle = '#fff'
context.stroke()
context.clip()
context.fillStyle = '#fff'
context.fillRect(x, x, width, height)
context.drawImage(image, x, x, width, height)
}
}
}
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。