一、实现思路
- 下载二维码生成器(qrcodejs2)的依赖
- 从后端获取到唯一的key值,来生成二维码。有些公司是获取到key值后就直接生成,而有些是要求拼接成链接后再生成,都 没问题的 (下面代码将展示第二种)
- 前端不断轮询,查询二维码登录状态,如(我司是通过返回0-4之间的数字来判断登录状态的)
- 返回的数字为登录成功状态,则登录
二、效果
三、具体实现代码
3.1 下载依赖
npm install --save qrcodejs2
3.2 将qrcodejs2引入二维码登录页面
import QRCode from 'qrcodejs2';
3.3 代码
ps:代码不可直接引入,但是二维码模块还是比较详细的,给新手参考。以及解决了使用 rcode.clear() 不生效的坑。
<template>
<div class="qr-code-box">
<!-- 存放二维码的盒子 -->
<div id="qrcode"></div>
<div class="tt">
<!-- 扫码成功,会有个图案覆盖在二维码上 -->
<img
v-if="this.showcodestate === '扫码成功'"
src="../../../assets/images/qr-success.png"
>
<!-- 登录成功,会有个图案覆盖在二维码上 -->
<img
v-else-if="this.showcodestate ==='登录成功'"
src="../../../assets/images/login-succcess.png"
>
</div>
</div>
<div class="code-text">请使用手机版xxx - 我的右上角 - 扫码登录</div>
<!-- 登录失败弹出框 -->
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
>
<span>登录失败!!</span>
<span
slot="footer"
class="dialog-footer"
>
<el-button
type="primary"
@click="dialogVisible = false"
>确 定</el-button>
</span>
</el-dialog>
</el-form>
</template>>
<script>
import QRCode from 'qrcodejs2';
import { qrcodelogin, getcodestate } from "@/api/user"; //引入api=>获取key值和轮询,登录的使用了vuex
export default {
name: "codelogin",
data () {
return {
// 后端返回来的key值
key: '',
// 放置拼接成的链接
codeurl: '',
// 扫码后的状态
showcodestate: '',
// 登录失败弹出框
dialogVisible: false
};
},
mounted () {
this.getqrcodekey() //获取key值
this.$nextTick(() => {
this.getstate() //轮询
})
},
destroyed () {
this.timeagain()
},
methods: {
// 获取后端传来的key值,拼接成一个链接
async getqrcodekey () {
const codedata = await qrcodelogin();
if (codedata.code === 20000) {
this.key = codedata.data.key
this.codeurl = 'http://www.xxxxxxxxxxxxxxxxxxxxxxxx/qr?key=' + this.key
// 生成二维码
let qrcode = new QRCode("qrcode", {
width: 172,
height: 172,
text: this.codeurl, //需要生成的内容(看APP需要)
});
console.log(qrcode, 'qrcode');
//因为隔两分钟就会生成一个新的二维码,因此需要把直接的删除了,以下两个是看别人的生效了,但是放在我的页面不生效,也记录下吧,给能用的上的人,若你用这个也没用 那就参考我接下来代码的写法吧
// qrcode.clear()
// qrcode.makeCode(this.codeurl)
qrcode._el.title = ""; //清除标题,不然鼠标停留在二维码上面会暴露二维码的内容
this.getstate()
}
},
// 循环调用后台接口,查看扫码状态
async getstate () {
if (this.key) {
const statedata = await getcodestate(this.key);
if (statedata.code === 20000) {
// 判断状态
if (statedata.data.state === 0) {
this.showcodestate = '未扫码'
this.timeagain() //继续每隔一秒调用接口查看状态一次
} else if (statedata.data.state === 1) {
this.showcodestate = '扫码成功'
this.timeagain()
} else if (statedata.data.state === 2) {
this.showcodestate = '登录成功'
//登录
this.$store
.dispatch("user/codelogin", this.key)
.then(() => {
this.$router.push({ path: '/layout' });
})
} else if (statedata.data.state === 3) {
this.showcodestate = '登录失败'
this.dialogVisible = 'true' //登录失败 弹出提示框
new QRCode("qrcode").clear() //清除原来的二维码
this.getqrcodekey() // 重新获取key值
} else if (statedata.data.state === 4) {
this.showcodestate = '二维码超时'
new QRCode("qrcode").clear()
this.getqrcodekey()
}
}
}
},
// 轮询登录接口状态
timeagain () {
setTimeout(() => {
this.getstate()
}, 1000)
},
}
}