1、安装依赖:
// 二维码组件
npm install vue-qr --save
//实现复制二维码链接
npm install clipboard --save
2、使用组件:
<!--
二维码生成组件弹框
使用:
<template>
.....
//二维码
<QRCode ref="qrcode" />
...
</template>
<script>
import QRCode from '@/components/qrcode'
export default {
data() {
return {}
},
components: { QRCode },
methods: {
// 按钮点击事件=>生成二维码
generateQRCodeBtn() {
let param={...this.siteInfoList}
this.$refs.qrcode.init(param,'','站点二维码') //(二维码内容,二维码下载名称)
},
}
}
</script>
-->
<template>
<el-dialog :visible.sync="erCode" center :title="title" width="15%" :fullscreen="fullscreen">
<i class="el-icon-full-screen fullscreen" @click="isFullScreen()"></i>
<div class="ebox">
<vue-qr ref="Qrcode" :text="dataObj.text" :logoSrc="dataObj.logo" qid="testQrId">
</vue-qr>
</div>
<div class="eboxBtn">
<a class="tag-copy" :data-clipboard-text="dataObj.text" @click="copyShareLink()">复制二维码</a>
<a :href="exportLink" @click="downloadImg()" :download="downloadFilename">下载二维码</a>
</div>
<section class="footer">
<el-button type="danger" @click="cancelBtn()">取消</el-button>
</section>
</el-dialog>
</template>
<script>
import VueQr from 'vue-qr'// 二维码组件
import Clipboard from 'clipboard'// 复制粘贴组件
export default {
data() {
return {
erCode: false,//弹框显示与隐藏
title: '二维码',//弹框名称
dataObj: {
text: '',//二维码信息
// logo: require('@/assets/img/avatar5.png')
logo: ''
},
exportLink: '',
downloadFilename: '',//下载图片名称
fullscreen: false,
}
},
components: { VueQr },
methods: {
// 生成二维码
init(text, type, title) {
if (!text) {
this.$message.warning('二维码的内容不能为空!!!')
return
}
//如果要跳转到想要的页面this.dataObj.text=页面地址+参数
if (type == 'presetInfo_appointCode') {
//预置信息=>生成预约码
text.jgid = text.deptId, text.bdid = text.stationId, text.fhdw = text.consigner
text.shdw = text.consignee, text.pm = text.variety, text.yxq = text.usefulTime
this.dataObj.text = "https://xxx/index.html#/" + this.ObjConcatURL(text)
} else if (type == 'stationInfo_carNumberConfirmCode') {
//站点信息=>生成车牌确认码
text.jgid = text.deptId, text.cd = text.laneName
this.dataObj.text = "http://xxx/xiugaichepai/index.html#/" + this.ObjConcatURL(text)
} else {
this.dataObj.text = typeof text == 'object' ? JSON.stringify(text) : text
}
this.title = title && title != '' ? title : this.$route.meta.title ? this.$route.meta.title + '二维码' : '二维码'
console.log(this.title + "链接地址:", this.dataObj.text)
this.fullscreen = false
this.erCode = true //弹框显示
},
// 将对象拼接到url地址后面
ObjConcatURL(obj) {
if (!(typeof obj == 'object') || Object.keys(obj).length == 0) {
return "";
} else {
// 过滤对象中为NaN,undefined的属性
for (let key in obj) {
if (obj.hasOwnProperty(key) && (obj[key] == null || obj[key] == undefined || obj[key] == NaN || obj[key] == '')) {
delete obj[key]
}
}
// 拼接字符串到url
return obj ? '?' + Object.keys(obj).map(i => `${i}=${obj[i]}`).join('&') : "";
}
},
// 复制链接
async copyShareLink() {
const This = this
let clipboard = new Clipboard('.tag-copy')
await clipboard.on('success', e => {
This.$message.success('链接复制成功!')
clipboard.destroy() // 释放内存
})
clipboard.on('error', e => {
This.$message.error('该浏览器不支持自动复制!') // 不支持复制
clipboard.destroy() // 释放内存
})
},
// 下载二维码图片
downloadImg() {
let Qrcode = this.$refs.Qrcode
this.exportLink = Qrcode.$el.currentSrc
this.downloadFilename = this.title
},
// 取消按钮
cancelBtn() {
this.erCode = false
},
// 弹框是否全屏
isFullScreen() {
this.fullscreen = !this.fullscreen
},
}
}
</script>
<style scoped lang="scss">
.ebox {
display: flex;
align-items: center;
justify-content: center;
}
i.fullscreen {
position: absolute;
right: 20px;
top: 0px;
padding: 10px;
cursor: pointer;
z-index: 9999;
}
i.fullscreen:hover {
color: #1890FF;
}
.eboxBtn {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
width: 100%;
a {
flex: 1;
display: flex;
justify-content: center;
margin: 5px 0 0 5px;
color: #FFF;
background-color: #67C23A;
border-color: #67C23A;
padding: 5.5px 15px;
font-size: 14px;
border-radius: 3px;
&:nth-child(1) {
background-color: #1890FF;
border-color: #1890FF;
}
}
}
.footer {
text-align: center;
padding-top: 25px;
}
</style>
<style scoped>
>>>.el-dialog__title {
font-weight: bold;
color: #5a5e66;
}
>>>.el-dialog__headerbtn {
position: absolute;
top: 5px;
right: 5px;
}
>>>.el-dialog--center .el-dialog__body {
padding: 0 25px 25px;
border-top: 1px solid #5a5e66;
}
>>>.el-button--danger {
width: 80%;
}
</style>
如何需要扫码跳转到别的页面=>this.dataObj.text需要加
页面网址
及页面加载所
必要的参数
(参数可加密,但获取参数时需解密)
3.最终效果:
4、改造后
由于要使用的地方太多了,组件就只做数据接收和处理
【1】QRCode
<template>
<div class="QRCode">
<vue-qr ref="Qrcode" :text="(typeof text == 'object') ? JSON.stringify(filterObj(text)) : text"
qid="testQrId"></vue-qr>
<div class="QRCode-footer" v-if="isButtonDownload == true">
<a class="tag-copy" :data-clipboard-text="(typeof text == 'object') ? JSON.stringify(filterObj(text)) : text"
@click="copyQRCodeShareLink()">复制二维码</a>
<a :href="exportLink" @click="downloadQRCode()" :download="downloadFilename">下载二维码</a>
</div>
</div>
</template>
<script>
import VueQr from 'vue-qr'// 二维码组件
import Clipboard from 'clipboard'// 复制粘贴组件
export default {
components: { VueQr },
props: {
text: {//二维码内容
type: [Number, String, Object],
default: ''
},
title: {//下载图片名称
type: String,
},
isButtonDownload: {
type: [Boolean],
default: true
},
},
data() {
return {
logo: require('@/assets/logo.png'),
exportLink: '',//二维码下载链接
downloadFilename: '',//下载图片名称
}
},
watch: {
'title': function (val) {
this.downloadFilename = val ? val : this.$route.meta.title ? this.$route.meta.title + '二维码' : '二维码'
}
},
methods: {
filterObj(obj) {
if (!(typeof obj == 'object')) { return {}; }
for (let key in obj) {
if (obj.hasOwnProperty(key) && (obj[key] == null || obj[key] == undefined || obj[key] == NaN || obj[key] == '')) { delete obj[key]; }
}
return obj;
},
// 复制链接
copyQRCodeShareLink() {
const that = this
let clipboard = new Clipboard('.tag-copy')
clipboard.on('success', e => {
that.$message.success('链接复制成功!')
clipboard.destroy() // 释放内存
})
clipboard.on('error', e => {
that.$message.warning('该浏览器不支持自动复制!') // 不支持复制
clipboard.destroy() // 释放内存
})
},
// 下载二维码图片
downloadQRCode() {
let Qrcode = this.$refs.Qrcode
this.exportLink = Qrcode.$el.currentSrc
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
.QRCode {
min-width: 200px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.QRCode-footer {
width: 200px;
display: flex;
justify-content: space-evenly;
a {
cursor: pointer;
}
}
</style>
【2】QRCodeModel
<template>
<a-modal v-model="visible" :title="title" width="16%" :closable="false">
<a-spin :spinning="confirmLoading">
<QRCode ref="QRCode" :text="text" :title="title" />
</a-spin>
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
</template>
</a-modal>
</template>
<script>
import QRCode from './QRCode.vue';
export default {
name: 'QRCodeModel',
components: { QRCode },
data() {
return {
description: '二维码弹框',
visible: false,
title: '二维码',
confirmLoading: false,
text: '',//二维码内容
};
},
methods: {
showModal(text, title) {
const that = this
if (!text) {
this.$message.warning('二维码的内容不能为空!!!')
return
}
that.confirmLoading = true
that.text = (typeof text == 'object') ? that.filterObj(text) : text
that.title = title ? title : that.$route.meta.title ? that.$route.meta.title + '二维码' : '二维码'
that.confirmLoading = false
that.visible = true
},
filterObj(obj) {
if (!(typeof obj == 'object')) { return {}; }
for (let key in obj) {
if (obj.hasOwnProperty(key) && (obj[key] == null || obj[key] == undefined || obj[key] == NaN || obj[key] == '')) { delete obj[key]; }
}
return obj;
},
// 取消按钮
handleCancel() {
this.visible = false
},
},
beforeDestroy() {
this.record = {}
this.fileList = []
}
};
</script>
<style scoped>
@import '~@assets/less/common.less';
/deep/.ant-modal-content {
min-width: 240px;
}
/deep/.ant-modal-header {
text-align: center;
}
/deep/.ant-modal-title {
font-weight: 600;
}
</style>
【3】全局注册
【4】使用:
(1)弹框
(2)内容
版权声明:本文为weixin_53791978原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。