目录标题
授权手机号
新旧版本核心差异对比
触发方式
旧版(2023年前)通过 <button open-type="getPhoneNumber">
触发,新版(2023年后)沿用相同方式但要求企业资质。
数据返回
旧版返回 encryptedData
和 iv
需后端解密,新版直接返回 code
供后端换取手机号。
费用
旧版免费,新版每次调用需支付 0.03 元起。
兼容性
旧版仅支持基础库版本低于 2.21.2,新版强制要求基础库版本 ≥ 2.21.2。
强制使用新版的情况
新注册小程序
无论基础库版本如何,必须使用新版接口。
已过审小程序
若更新代码需适配新版接口,否则无法通过审核。
安全要求
新版需完成企业认证并开通微信支付。
代码实现方案
版本检测与兼容处理
const systemInfo = getCompatSystemInfo();
const isNewVersion = compareVersion(systemInfo.SDKVersion, '2.21.2') >= 0;
utils.js
/**
* 获取兼容性系统信息
* @returns {Object} 包含SDKVersion/windowWidth/system等字段的对象
*/
export const getCompatSystemInfo = () =>{
// 优先尝试新API组合 (2.20.1+)
if (uni.getDeviceInfo && uni.getWindowInfo) {
const deviceInfo = uni.getDeviceInfo();
const windowInfo = uni.getWindowInfo();
return {
SDKVersion: uni.getAppBaseInfo().SDKVersion,
windowWidth: windowInfo.windowWidth,
windowHeight: windowInfo.windowHeight,
system: deviceInfo.system,
platform: deviceInfo.platform
};
}
// 降级使用旧API
const legacyInfo = uni.getSystemInfoSync();
return {
SDKVersion: legacyInfo.SDKVersion,
windowWidth: legacyInfo.windowWidth,
windowHeight: legacyInfo.windowHeight,
system: legacyInfo.system,
platform: legacyInfo.platform
};
}
/**
* 比较两个版本号字符串的大小
* @param {string} v1 - 版本号1 (格式如"1.2.3")
* @param {string} v2 - 版本号2 (格式如"1.2.4")
* @returns {number}
* 1: v1 > v2
* -1: v1 < v2
* 0: v1 == v2
*/
export const compareVersion = (v1, v2) => {
// 将版本号字符串拆分为数字数组(如"1.2.3" → [1,2,3])
const v1Arr = v1.split('.').map(Number);
const v2Arr = v2.split('.').map(Number);
// 比较最多3位版本号(支持4位可修改循环条件)
for (let i = 0; i < 3; i++) {
// 如果当前位v1大于v2,直接返回1
if (v1Arr[i] > v2Arr[i]) return 1;
// 如果当前位v1小于v2,直接返回-1
if (v1Arr[i] < v2Arr[i]) return -1;
}
// 所有位都相同则返回0
return 0;
}
<button open-type="getPhoneNumber" @getphonenumber="registerUser">
授权手机号一键登录
</button>
旧版实现代码
getPhoneNumber(e) {
if (!isNewVersion && e.detail.encryptedData) {
uni.login({
success: (res) => {
uni.request({
url: 'YOUR_API',
data: {
code: res.code,
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
}
})
}
})
}
}
新版实现代码
getPhoneNumber(e) {
if (isNewVersion && e.detail.code) {
uni.login({
success: (res) => {
uni.request({
url: 'YOUR_API',
data: {
wx_code: res.code,
phone_code: e.detail.code
}
})
}
})
}
}
if (e.detail?.errMsg !== "getPhoneNumber:ok") {
console.log("授权失败")
return;
}
特殊处理逻辑
降级方案
通过 wx.canIUse()
检测接口可用性,确保兼容性。
错误处理
需捕获 getPhoneNumber
的 fail
回调,处理授权失败情况。
UI适配
建议使用条件渲染展示不同按钮文案,提升用户体验。
企业账号要求
旧版
仅需完成企业认证即可使用。
新版
需额外完成微信支付认证并开通相应权限。
测试号
提供 1000 次免费调用额度供开发测试使用。
最佳实践建议
新项目
必须使用新版接口,并提前规划调用预算。
存量项目
建议逐步迁移至新版接口,过渡期做好双版本兼容。
个人开发者
无法使用手机号授权功能,需升级为企业主体。
授权头像和昵称
新旧版本核心差异对比
微信小程序获取用户头像和昵称的新旧版本在API接口、触发条件、数据返回等方面存在显著差异:
旧版实现方式(2022年前)
- 使用
wx.getUserInfo
或wx.getUserProfile
接口 - 需要用户主动授权弹窗
- 直接返回包含用户信息的对象
- 对基础库版本无特殊要求
新版实现方式(2022年后)
- 使用
chooseAvatar
按钮和nickname
输入框 - 必须通过按钮点击触发
- 头像返回临时路径,昵称需安全检测
- 要求基础库版本≥2.21.2
强制使用新版的情况
- 新注册的小程序必须使用新版接口
- 已过审的小程序在更新代码时必须适配新版
- 头像内容需通过微信安全检测
代码实现方案
新版标准实现
chooseAvatar
接口返回的是临时文件路径。为了确保头像能够长期存储和展示,需要通过uni.uploadFile
将该路径上传至服务器,并保存服务器返回的永久URL。
<!-- 头像获取 -->
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
选择头像
</button>
<!-- 昵称获取 -->
<input type="nickname" @blur="onNicknameBlur" />
export default {
methods: {
onChooseAvatar(e) {
this.avatarUrl = e.detail.avatarUrl
this.uploadAvatar()
},
onNicknameBlur(e) {
this.nickName = e.detail.value
}
}
}
旧版兼容方案
如果不满足上述提及的使用旧版本的要求,以下代码获取得到的个人信息数据是默认数据,不是用户真实的头像和昵称。(加密的数据中存放的也是默认数据。)
<button v-if="showLegacy" open-type="getUserInfo" @getuserinfo="getLegacyInfo">
授权获取信息
</button>
export default {
data() {
return {
showLegacy: false
}
},
mounted() {
this.checkSDKVersion()
},
methods: {
checkSDKVersion() {
const { SDKVersion } = uni.getSystemInfoSync()
this.showLegacy = this.compareVersion(SDKVersion, '2.21.2') < 0
},
compareVersion(v1, v2) {
// 版本比较逻辑
},
getLegacyInfo(e) {
console.log(e.detail.userInfo)
}
}
}
最佳实践建议
- 新项目必须使用新版方案
- 存量项目建议通过条件编译实现多版本共存
注意事项
- 开发者工具与真机表现可能存在差异,需进行真机测试
- 头像临时路径需在24小时内上传到服务器
- 需提供用户拒绝授权时的备选方案