使用Axios请求实现目标效果图:
短信验证码登录
-
校验图形验证码,校验通过
-
发送短信验证码到用户手机上,可通过在线 WebSocket查看:wss://guardian-api.itheima.net/verifyCode
-
根据 手机号 + 短信验证码 实现登录
更新图形验证码
准备一个 @State,用于更新图形验证码
手机号+验证码登录
获取图形验证码
TypeScript
// 校验图形验证码
async onGraphicCodeSubmit() {
try {
// 1. 把手机号,图形验证码发送到后端,校验图形验证码(防机器)
await postCodeGraphicCheckAPI({
bizType: BizType.PhoneLogin, // 业务类型,1:手机号短信验证码登录
phone: this.phoneNumber, // 手机号
verifyCode: this.graphicCode // 图形验证码
})
// 2. 关闭半模态转场
this.isShowSheet = false
// 3. 清空输入框
this.graphicCode = ''
// 4. 调用发送短信接口
this.onSendSmsCode()
} catch (error) {
// 刷新验证码
this.timestamp = Date.now()
}
}
// 半模态转场
@Builder
SheetBuilder() {
Column() {
Text('图形验证码')
.fontSize(16)
.fontColor($r('app.color.font'))
.margin({ top: 20, bottom: 50 })
Column({ space: 20 }) {
Row({ space: 10 }) {
TextInput({ placeholder: '图形验证码' })
.fontSize(14)
.height(42)
.layoutWeight(1)
.maxLength(4)
.onChange((value) => {
this.graphicCode = value
})
.onSubmit(() => {
// 提交图形验证码
this.onGraphicCodeSubmit()
})
Image(`${BASE_URL}/code/graphic?phone=${this.phoneNumber}&bizType=${BizType.PhoneLogin}×tamp=${this.timestamp}`)
.width(108)
.height(42)
.objectFit(ImageFit.Contain)
.onClick(() => {
this.timestamp = Date.now()
})
}
Button("提交")
.height(42)
.backgroundColor($r('app.color.brand'))
.width('100%')
.enabled(this.graphicCode.length > 0)
.onClick(() => {
// 提交图形验证码
this.onGraphicCodeSubmit()
})
}
}
.padding({ left: 30, right: 30 })
.width('100%')
.height('100%')
}
.bindSheet($$this.isShowSheet, this.SheetBuilder(), {
// 半模态转场,屏幕高度一半,无法修改关闭图标样式
detents: [SheetSize.MEDIUM],
backgroundColor: $r('app.color.white')
})
发送短信验证码
1、发送验证码
2、开始倒计时
3、验证码可以通过接口文档的 WebScoket 测试接口获取,模拟手机收到短信。
可通过 在线 WebSocket 工具,模拟查看验证码信息: 服务连接地址 wss://guardian-api.itheima.net/verifyCode
TypeScript
// 发送短信验证码
async onSendSmsCode() {
// 发送验证码
await postCodeSmsSendAPI({
bizType: BizType.PhoneLogin,
phone: this.phoneNumber,
})
// 用户提醒
promptAction.showToast({ message: '短信发送到手机上,请注意查收' })
// 界面更新倒计时
this.startCountDown()
}
// 开始倒计时
startCountDown() {
// 初始化倒计时秒数
this.count = 120
// 关闭旧的定时器
clearInterval(this.intervalID)
// 开启定时器
this.intervalID = setInterval(() => {
this.count--
if (this.count <= 0) {
clearInterval(this.intervalID)
}
}, 1000)
}
// 页面销毁,停止倒计时,释放资源
aboutToDisappear() {
clearInterval(this.intervalID)
}
登录提交
1、登录成功持久化存储用户信息
2、axios 拦截器添加 token 信息
TypeScript
// 用户信息持久化
@StorageLink(LOGIN_INFO) loginInfo: LoginInfoResponse = {}
// 登录提交
async onLoginSubmit() {
const res = await postUserLoginVerifyCodeAPI({
phone: this.phoneNumber,
verifyCode: this.verifyCode
})
//
promptAction.showToast({ message: '登录成功' })
// 更新持久化存储的信息
this.loginInfo = res.data.result
// 返回上一页
router.back()
}
3、pages/Index.ets 初始化持久化存储
TypeScript
// 持久化存储
PersistentStorage.persistProp<PrivacySettings>(PRIVACY_SETTINGS, {})
PersistentStorage.pers