详细代码请见文档最下方,仅供参考,更多需要请查看官方文档
一、
微信官方文档 | 获取手机号
这是服务端的
这是我们前端获取手机号需要给接口传递的两个参数
注意:
参数一:获取access_token需要用到小程序密钥,这个需要从服务端获取,也就是需要请求后端接口获取access_token,千万不要将小程序密钥写在前端代码中,必须要从服务端获取。
参数二:code的获取我们可以点击后面的 "手机号获取凭证" 查看用法,很简单。下面 二、 就是手机号获取凭证地址。
二、
微信官方文档 | 手机号获取凭证
注意:这里有基础库版本限制,所以我们最好做一下低版本兼容处理;
个人使用时碰到的坑:
微信开放社区 | 使用getPhoneNumber获取手机号code,微信PC拿不到code,手机端可以获取到?
详细实现代码:
<template>
<view class="flex">
<view class="title">
<view class="logo">
<image src="/static/image/logo.png" mode="widthFix" />
</view>
</view>
<!-- 手机号登录 --授权并获取手机号保存至本地 -->
<button
type="default"
class="loginButton"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
<view class="row">
<view class="icon">
<u-icon name="weixin-fill" size="28"></u-icon>
</view>
<view style="font-size: 30rpx">微信登录</view>
</view>
</button>
<!-- 协议选择 -->
<view class="serve-rule">
<u-checkbox-group size="24" @click="changeCheckStatus">
<u-checkbox
class="checkbox"
v-model="checkStatus"
activeColor="#ff414e"
></u-checkbox>
</u-checkbox-group>
<view class="protocol-prompt">
<text @click="changeCheckStatus">本人理解并同意</text>
<text class="serve-label" @click.stop="onServiceAgreement"
>《隐私政策》</text
>
<text class="serve-label" @click.stop="onUserAgreement"
>《用户协议》</text
>
</view>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
export default {
name: "login",
data() {
return {
phoneCode: "", // 获取手机号使用的code
phoneNumber: "", // 手机号
access_token: "", // 用户token
code: "", // authCode用户code码 ---- 登陆使用的code
userInfo: "", //用户信息
id: "",
checkStatus: false, //协议是否勾选
};
},
onLoad(options) {
const version = wx.getSystemInfoSync().SDKVersion;
console.log("当前版本号version", version);
if (this.compareVersion(version, "2.21.2") >= 0) {
uni.removeStorageSync("storage_USERPHONE");
this.getWxCode(); // 获取微信用户code码--登录使用
this.getAccessToken(); // 获取 accessToken --获取手机号使用
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: "提示",
content:
"当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
});
}
},
methods: {
// 获取微信用户code码--登录使用
async getWxCode() {
const result = await wx.login();
// console.log(result);
if (result.code) {
this.code = result.code;
console.log("登录使用的code =====>>>>>>", this.code);
}
},
// 获取 accessToken 注意:要从服务端获取,密钥不能写在前端。 --获取手机号使用
getAccessToken() {
this.$http.getAccessToken().then((res) => {
if (res.success) {
let resObj = res.datas && res.datas.obj;
console.log("resObj======>>>>>>", resObj);
this.access_token = resObj.access_token;
console.log("that.access_token======>>>>>>", this.access_token);
}
});
},
// 低版本兼容处理方法封装
compareVersion(v1, v2) {
v1 = v1.split(".");
v2 = v2.split(".");
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push("0");
}
while (v2.length < len) {
v2.push("0");
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i]);
const num2 = parseInt(v2[i]);
if (num1 > num2) {
return 1;
} else if (num1 < num2) {
return -1;
}
}
return 0;
},
// 获取用户手机号-接口
getUserPhone() {
this.$http
.getPhone({
code: this.phoneCode,
access_token: this.access_token,
})
.then((res) => {
// console.log("用户手机号res====>",res)
if (res.success) {
let resDatas = res.datas;
let phoneInfo = JSON.parse(resDatas.phone_info);
// console.log("获取到的用户手机号相关信息=====>>>>>>", phoneInfo)
this.phoneNumber = phoneInfo.phoneNumber;
console.log("获取到的用户手机号=====>>>>>>", this.phoneNumber);
uni.setStorageSync("storage_USERPHONE", this.phoneNumber);
this.login();
}
});
},
// 获取手机号的code并授权
getPhoneNumber(e) {
console.log("e=====>>>>>>", e);
if (this.checkStatus) {
let detail = e.detail;
if (detail.errMsg === "getPhoneNumber:ok") {
let that = this;
this.phoneCode = detail.code;
console.log("获取手机号使用的code =====>>>>>>", this.phoneCode);
if (this.phoneCode) {
this.getUserPhone();
} else {
this.login();
}
} else {
console.log("取消授权!");
}
} else {
uni.showToast({
icon: "none",
title: "请阅读并确认隐私政策和用户协议",
});
}
},
// 登录
async login() {
uni.showLoading({
title: "登录中.....",
mask: true,
});
const res = await this.$http.wxLogin({
code: this.code,
udid: "**************",
appletType: 4,
});
if (res.success) {
if (res.datas.token) {
uni.setStorageSync("ticket", res.datas.token);
}
if (res.datas.obj) {
uni.setStorageSync("userInfo", res.datas.obj);
this.id = res.datas.obj.extInfo.id;
}
this.getAppletVersion();
return;
}
},
getAppletVersion() {
uni.hideLoading();
uni.reLaunch({
url: `/pages/index/index`,
});
},
// 切换是否选中复选框
changeCheckStatus() {
this.checkStatus = !this.checkStatus;
},
// 进入《隐私政策》
onServiceAgreement() {
uni.navigateTo({
url: "/pages/privacy-policy/privacy-policy",
fail(e) {
console.log(e);
},
});
},
// 《用户协议》
onUserAgreement() {
uni.navigateTo({
url: "/pages/user-service-agreement/user-service-agreement",
fail(e) {
console.log(e);
},
});
},
},
};
</script>
<style lang="scss" scoped>
.flex {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: center;
position: fixed;
width: 100vw;
height: 100vh;
top: 200rpx;
left: 0;
padding: 0 64rpx;
.title {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 200rpx;
width: 240rpx;
.logo {
width: 360rpx;
height: 360rpx;
overflow: hidden;
image {
width: 100%;
height: auto;
}
text {
display: inline-block;
color: #404040;
}
}
}
.loginButton {
width: 100%;
height: 72rpx;
background: linear-gradient(142deg, #ff8677 11%, #ff424e 94%);
border-radius: 88rpx;
font-size: 32rpx;
font-family: PingFangSC, PingFangSC-Medium;
font-weight: 500;
text-align: center;
line-height: 52rpx;
color: #ffffff;
letter-spacing: 2rpx;
margin-bottom: 52rpx;
}
.serve-rule {
width: 100%;
margin-left: 16rpx;
display: flex;
align-items: center;
position: relative;
.serve-label {
color: #ff414e;
// transform: translateX(-10%);
}
.protocol-prompt {
display: inline-block;
position: absolute;
left: 34rpx;
}
}
.checkbox {
margin-right: 0;
}
.row {
padding: 10rpx;
flex-flow: row nowrap;
display: flex;
justify-content: center;
align-items: center;
.icon-text {
color: #007aff;
}
}
.ding-row {
flex-flow: row nowrap;
display: flex;
justify-content: center;
align-items: center;
.icon-text {
color: #007aff;
}
}
.icon {
margin-right: 10rpx;
display: flex;
align-items: center;
}
.btn {
width: 90%;
overflow: hidden;
text-align: center;
}
}
</style>