鸿蒙next 实现获取验证码倒计时功能

493 阅读2分钟

image.png

前言导读:

最近在开发发送短信验证码功能,所以不需要做一个倒计时再次获取短信验证码功能,这里就简单分享一个功能。

效果图:

7e5b9501d325d821f7703d58c8777d4b[00_00_01--00_00_21].gif

具体实现

  • 1 定义需要变量

一、核心实现方案

  1. 状态管理

    • 使用@State修饰符管理倒计时数值和按钮状态,实现数据驱动视图更新15
    • 定义countdownSeconds状态变量存储剩余秒数(默认60秒)
@State buttonText: string = '获取验证码';
@State countdownSeconds: number = TOTAL_COUNT;
private timerId: number = 0;
private isCounting: boolean = false;
  • 2 启动倒计时

定时器控制

  • 通过setInterval实现计时逻辑,并保存定时器ID到全局变量
// 启动倒计时
startCountdown() {
  if (this.isCounting) return;

  this.isCounting = true;
  this.countdownSeconds = TOTAL_COUNT;
  this.timerId = setInterval(() => {
    if (this.countdownSeconds <= 0) {
      this.resetCountdown();
      return;
    }
    this.countdownSeconds--;
    this.buttonText = `${this.countdownSeconds}s后重新获取`;
  }, 1000);
}
  • 3 重置倒计时

// 重置倒计时
resetCountdown() {
  clearInterval(this.timerId);
  this.isCounting = false;
  this.buttonText = '获取验证码';
}
  • 4 在页面的启动的生命周期方法里面调用 重置倒计时

  • aboutToDisappear生命周期清除定时器,避免内存泄漏
// 页面生命周期管理
aboutToDisappear() {
  this.resetCountdown();
}
  • 5 页面布局实现

build() {
  Column() {
    Button(this.buttonText)
      .onClick(() => {
        // 调用短信发送接口
        this.startCountdown();
      })
      .enabled(!this.isCounting).align(Alignment.Center)
  }.justifyContent(FlexAlign.Center).width("100%").height("100%")
}

完整代码实现


const TOTAL_COUNT = 60;
@Entry
@Component
struct Index  {
  @State buttonText: string = '获取验证码';
  @State countdownSeconds: number = TOTAL_COUNT;
  private timerId: number = 0;
  private isCounting: boolean = false;

  // 启动倒计时
  startCountdown() {
    if (this.isCounting) return;

    this.isCounting = true;
    this.countdownSeconds = TOTAL_COUNT;
    this.timerId = setInterval(() => {
      if (this.countdownSeconds <= 0) {
        this.resetCountdown();
        return;
      }
      this.countdownSeconds--;
      this.buttonText = `${this.countdownSeconds}s后重新获取`;
    }, 1000);
  }

  // 重置倒计时
  resetCountdown() {
    clearInterval(this.timerId);
    this.isCounting = false;
    this.buttonText = '获取验证码';
  }

  // 页面生命周期管理
  aboutToDisappear() {
    this.resetCountdown();
  }

  build() {
    Column() {
      Button(this.buttonText)
        .onClick(() => {
          // 调用短信发送接口
          this.startCountdown();
        })
        .enabled(!this.isCounting).align(Alignment.Center)
    }.justifyContent(FlexAlign.Center).width("100%").height("100%")
  }
}

三、注意事项

  1. 防重复点击‌:倒计时期间禁用按钮交互,通过enabled(!isCounting)控制5
  2. 全局状态保存‌:建议使用AppStorageLocalStorage持久化倒计时状态,应对应用重启场景6
  3. 性能优化‌:页面跳转时立即清除定时器,避免无效计时消耗资源15
  4. 组件化封装‌:可将倒计时逻辑封装为自定义组件,提高代码复用性6

四、进阶优化方向

  1. 支持后台计时‌:通过BackgroundTaskManager实现后台持续计时3
  2. 多通道验证‌:结合滑块验证等交互提高安全性5
  3. 异常处理‌:增加网络请求超时、短信发送失败等异常状态处理4
  4. 样式定制‌:通过@Extend实现不同状态下的按钮样式变化8

该方案已在实际项目中验证,能稳定实现倒计时功能并满足鸿蒙Next的生命周期管理要求13。开发者可根据具体业务需求扩展验证码发送失败重试、国际化等附加功能

最后总结

整个定时的实现比较简单 主要是对状态管理和定时器的使用, 各位同学可以拿到代码自己去尝试优化,特别是退到后和再次进到前台的时候都细节处理。这里就不展开讲了,今天的文章就讲到这里有兴趣的 关注我B站教程谢谢