效果
准备工作
为了简化操作及组件模块化,使用社区成熟的插件
npm install vue-wxlogin --save-dev
示例代码
建议找个新页面,一键复制以下代码,进行测试
<!--
【整体思路流程】
1. 先通过后端接口获取appid等敏感数据,保存到data中。
2. 将获取到的数据传递给组件,如果正确无误扫码登录框就自动出来了。
3. 用户扫码登录后,会自动跳转到重定向的回调域地址(解析code),也就是前端当前的页面。
4. 解析成功或失败,前端就可以拿着code去找接口换数据了,进行您的逻辑即可。
———————————————————————————————————————————————————————————
【注意事项】
1. [非常重要] 前端和后端必须都在一个回调域下,比如前端是:www.abc.com/index,
后端的是:www.abc.com/admin,这样就处于同一个【www.abc.com】回调域下。如果前端是abc,后端是def,则无法互通。
2. 一定要等敏感数据(appid等)请求过来后,再传递给组件!我是用的if暂时不渲染!
3. redirect_uri 是回调域,重定向的地址,必须是微信开放平台里设置好的回调域(找后端看),咱们测试默认的localhost,什么192.168.xx 统统不行,
所以每次调试必须部署到线上进行测试,非常麻烦。
如果想要解决,请访问:https://wangjiabin.blog.csdn.net/article/details/127787561
———————————————————————————————————————————————————————————
这个扫码登录操作,必须要和后端进行协商,这些参数你不知道是什么、怎么做的时候,要去问后端!
-->
<template>
<div>
<!-- 微信扫码登录框 -->
<!-- 配置说明请参考文章底部Props,或直接访问组件文档:https://github.com/toMatthew/vue-wxlogin -->
<div v-if="sensitive != null">
<wxlogin
:appid="sensitive.appid"
:scope="sensitive.scope"
:redirect_uri="redirect_uri"
state=""
/>
</div>
<!-- END -->
<!-- 数据还未请求过来 -->
<div v-else>二维码加载中...</div>
<!-- END -->
</div>
</template>
<script>
// 微信登录组件
import wxlogin from 'vue-wxlogin';
export default {
components: { wxlogin },
data() {
return {
// 敏感数据(appid等)
sensitive: null,
// 重定向的路径
redirect_uri: null,
}
},
mounted() {
// 获取要重定向的路径(本页面url)
this.getRedirect()
// 获取敏感数据(appid等)
this.getSensitive()
},
methods: {
/**
* 获取要重定向的路径(本页面url)
* @description 赋值到本地,传递给组件
* @return void
*/
getRedirect() {
// 获取本页面的域名,也就是下面的代码(需要UrlEncode编码)
this.redirect_uri = encodeURIComponent(window.location.href)
},
/**
* 获取敏感数据(appid等)
* @description 赋值到本地,传递给组件
* @return void
*/
getSensitive() {
// 请求接口
this.$axios.post(`XXX`).then(res => {
// console.log(res)
this.sensitive = res.data.data
// 检测是否扫码登录成功(因为用户扫码登录后,会刷新页面,必须进行检测)
this.testing()
})
},
/**
* 检测是否扫码登录成功
* @description 判断检测url上有没有code拼接
* @return void
*/
testing() {
// 获取URL上code
const code = this.getUrlParam('code')
// 判断是否存在code
if(code == null || code == '' || code == undefined) {
// code为空
// 意味着没有扫码登录,您的逻辑...
} else {
// code存在,调用接口获取登录信息
console.log('【当前code】', code)
this.getInfo(code)
}
},
/**
* 获取登录信息(一定要后端去获取最终登录数据!)
* @description 通过拿到的code,去接口换登录信息
* @param {String} code - code
* @return
*/
getInfo(code) {
// 请求接口
this.$axios.post(`XXX`, { code: code }).then(res => {
// 判断code码
// 获取失败
if(res.data.code == 0) {
// 要做的操作...
// 大部分是清空url上的code参数并跳转回本页面
this.delUrlParam(window.location.href)
}
// 获取成功
else {
// 业务逻辑(res就是用户登录信息了,比如写入缓存)
console.log(res)
// 回跳到原页面(去掉URL上的code参数)
this.delUrlParam(window.location.href)
}
})
},
/**
* 解析URL参数
* @description 截取路由参数
* @param {String} name - 要解析的路由参数
* @return String
*/
getUrlParam(name) {
let reg = new RegExp('(^|&)'+ name + '=([^&]*)(&|$)')
let r = window.location.search.substr(1).match(reg)
if(r != null){// ok
return unescape(r[2])
}
// false
return null
},
/**
* 删除url路径指定参数
* @description 去除地址栏url上的code参数,回到原页面
* @param {String} url - URL
* @param {String} key - KEY
* @return String
*/
delUrlParam(url, key = 'code') {
let baseUrl = url.split('?')[0] + '?';
let query = url.split('?')[1];
if (query.indexOf(key) > -1) {
let obj = {};
let arr = query.split('&');
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i].split('=');
obj[arr[i][0]] = arr[i][1];
}
delete obj[key];
let url =
baseUrl +
JSON.stringify(obj)
.replace(/[\"\{\}]/g, '')
.replace(/\:/g, '=')
.replace(/\,/g, '&');
// return url;
window.history.pushState({},0,url);//跳转页面
} else {
// return url;
window.history.pushState({},0,url);//跳转页面
}
},
}
}
</script>
<style scoped>
</style>
自定义样式
默认生成的二维码样式,大小可能不符合我们的需求
有两种解决方案:
1、使用https链接地址。这个很简单,只需要把自定义的css文件上传到服务器,然后使用服务器上的css文件即可(缺点:如果网络比较慢,首先加载默认样式,然后才回使用自定义样式,有一个闪烁的过程)
2、使用base64。这个比较推荐。
第 1 种方案很简单,主要说一下第 2 种使用 base64 的方案。
比如您想要将二维码尺寸改小一点,去掉标题等样式,对应的 css 如下:
.impowerBox .title {
display: none;
}
.impowerBox .status.status_browser {
display: none;
}
.impowerBox .qrcode {
border: none;
width: 200px;
height: 200px;
}
.impowerBox .status{
display: none
}
使用这个工具转换base64编码,如下图所示:
复制右侧的lmltcG93ZX...,放到代码中
<!-- XXXX: 就是你复制的编码,注意不要因为太长另起一行,否则不生效 -->
<!-- data:text/css; 不可删除,否则不生效 -->
<wxlogin
href="data:text/css;base64,XXXXXX"
/>
更多资源
微信扫码登录,官方文档
vue-wxlogin Github:github.com/toMatthew/v…
常见问题
如果提示redirect_uri参数错误,则证明你的程序跑出来的本地地址域名,不是微信开放平台后台填写的回调域,具体可去问后端。
redirect_uri 是回调域,重定向的地址,必须是微信开放平台里设置好的回调域(找后端看),咱们测试默认的localhost,什么192.168.xx 统统不行,所以每次调试必须部署到线上进行测试,非常麻烦。
能出来二维码,就意味着你们成功一半了,后面的事需要前后端一起商量。
用户扫码成功并登录以后,会自动重定向地址,并在地址栏中添加“code”、“state”query参数,您也可以使用watch检测$route.query参数的变化,从而知道扫码成功,然后可以设置setTimeout等待几秒关闭扫码弹窗,跳转到原来的路由地址。当然使用示例中的方式是最好的。
微信开放平台:open.weixin.qq.com/,去这里看回调配置,前…
如果安装的组件出现引入失败的问题,请重启项目。