微信小程序uni-app+vue3实现手机号一键登录方法
网上的教程都挺乱,写得都不怎么全,我重新实现了一下,把具体的方法都分享出来。
uni-app/微信小程序官方API
1. uni.login
uni-app提供的统一登录接口,用于获取登录凭证(code)。
语法:
uni.login({
provider: 'weixin', // 登录服务提供商,微信小程序固定为'weixin'
success: (res) => {
// res.code: 登录凭证,有效期5分钟
// res.errMsg: 错误信息,成功为'login:ok'
},
fail: (err) => {
// 登录失败回调
// err.errMsg: 错误信息
},
complete: () => {
// 接口调用结束的回调(调用成功、失败都会执行)
}
})
**注意事项:**
- code只能使用一次,使用后失效
- code有效期为5分钟
- 需要在真机或开发者工具中调试
- 建议封装为Promise使用
**Promise封装示例:**
````typescript
const login = (): Promise<string> => {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: (res) => {
if (res.errMsg === 'login:ok') {
resolve(res.code)
} else {
reject(new Error(res.errMsg))
}
},
fail: (err) => {
reject(err)
}
})
})
}
2. 获取手机号相关
<template>
<!-- 登录按钮 -->
<button
class="login-button"
:loading="loading"
:disabled="loading"
open-type="getPhoneNumber"
@getphonenumber="handleGetPhoneNumber"
>
{{ loading ? '登录中...' : '手机号一键登录' }}
</button>
</template>
open-type="getPhoneNumber"
: 按钮的开放能力属性@getphonenumber
: 获取手机号回调事件- 回调参数
e.detail.code
: 用于换取手机号的code - 错误信息
e.errMsg
: 包含 ‘getPhoneNumber:fail user deny’ 等状态
3. 存储相关(可以调用自己相关的状态管理)
// 存储API
uni.setStorageSync('key', value) // 同步存储数据
uni.getStorageSync('key') // 同步获取数据
uni.removeStorageSync('key') // 同步删除数据
4. 界面交互
// 提示框
uni.showToast({
title: '提示内容',
icon: 'none' // 'success' | 'loading' | 'error' | 'none'
})
// 加载提示
uni.showLoading({
title: '加载中',
mask: true // 是否显示透明蒙层
})
uni.hideLoading()
完整登录流程示例
const handleGetPhoneNumber = async (e: any) => {
try {
// 1. 显示加载
uni.showLoading({
title: '登录中',
mask: true
})
// 2. 处理用户拒绝授权
if (e.errMsg === 'getPhoneNumber:fail user deny') {
throw new Error('用户拒绝授权')
}
// 3. 获取登录code
const loginResult = await login()
// 4. 调用后端登录接口
const loginRes = await request({
url: '/api/login',
method: 'POST',
data: {
code: loginResult,
phoneCode: e.detail.code
}
})
// 5. 存储token
uni.setStorageSync('token', loginRes.token)
// 6. 提示成功
uni.showToast({
title: '登录成功',
icon: 'success'
})
} catch (error) {
// 错误处理
uni.showToast({
title: error.message || '登录失败',
icon: 'error'
})
} finally {
// 隐藏加载
uni.hideLoading()
}
}
最佳实践
- 错误处理
// 统一的错误处理
const handleLoginError = (error: any) => {
let message = '登录失败'
if (error.errMsg) {
switch (error.errMsg) {
case 'login:fail':
message = '登录失败,请重试'
break
case 'getPhoneNumber:fail user deny':
message = '用户拒绝授权'
break
// ... 其他错误类型
}
}
uni.showToast({
title: message,
icon: 'error'
})
}
- 自动登录处理
const autoLogin = async () => {
try {
// 1. 检查本地token
const token = uni.getStorageSync('token')
if (!token) return false
// 2. 验证token有效性
const valid = await verifyToken(token)
return valid
} catch (error) {
// 3. 清除无效token
uni.removeStorageSync('token')
return false
}
}