img

一、案例介绍

本案例将展示如何使用TextInput组件创建一个具有实时验证和格式化功能的手机号码输入框,包括号码格式化、验证码发送等功能。

二、代码实现

@Entry
@Component
struct PhoneInputExample {
  @State phoneNumber: string = ''
  @State verifyCode: string = ''
  @State countdown: number = 0
  @State isPhoneValid: boolean = false
  private timer: number = -1

  // 格式化手机号码
  formatPhoneNumber(phone: string): string {
    const cleaned = phone.replace(/\D/g, '')
    let formatted = cleaned
    if (cleaned.length > 3) {
      formatted = cleaned.slice(0, 3) + ' ' + cleaned.slice(3)
    }
    if (cleaned.length > 7) {
      formatted = formatted.slice(0, 8) + ' ' + formatted.slice(8)
    }
    return formatted
  }

  // 验证手机号码
  validatePhone(phone: string): boolean {
    const cleaned = phone.replace(/\D/g, '')
    return /^1[3-9]\d{9}$/.test(cleaned)
  }

  // 开始倒计时
  startCountdown() {
    this.countdown = 60
    this.timer = setInterval(() => {
      this.countdown--
      if (this.countdown <= 0) {
        clearInterval(this.timer)
        this.timer = -1
      }
    }, 1000)
  }

  // 发送验证码
  sendVerifyCode() {
    if (!this.validatePhone(this.phoneNumber)) {
      AlertDialog.show({
        title: '提示',
        message: '请输入正确的手机号码',
        confirm: {
          value: '确定',
          action: () => {}
        }
      })
      return
    }

    // 模拟发送验证码
    this.startCountdown()
    AlertDialog.show({
      title: '成功',
      message: '验证码已发送',
      confirm: {
        value: '确定',
        action: () => {}
      }
    })
  }

  aboutToDisappear() {
    if (this.timer !== -1) {
      clearInterval(this.timer)
    }
  }

  build() {
    Column() {
      // 标题
      Text('手机号验证')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 40, bottom: 40 })

      // 手机号输入区域
      Column({ space: 8 }) {
        Text('手机号')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)

        Row() {
          Text('+86')
            .fontSize(16)
            .fontColor('#666666')
            .margin({ right: 8 })

          TextInput({
            placeholder: '请输入手机号',
            text: this.phoneNumber
          })
            .type(InputType.Number)
            .maxLength(13)
            .onChange((value: string) => {
              this.phoneNumber = this.formatPhoneNumber(value)
              this.isPhoneValid = this.validatePhone(value)
            })
            .width('100%')
            .height(48)
            .fontSize(16)
            .backgroundColor('#F5F5F5')
            .borderRadius(8)
            .padding({ left: 12, right: 12 })
        }
        .width('100%')
        .margin({ bottom: 24 })

        // 验证码输入区域
        Text('验证码')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)

        Row() {
          TextInput({
            placeholder: '请输入验证码',
            text: this.verifyCode
          })
            .type(InputType.Number)
            .maxLength(6)
            .onChange((value: string) => {
              this.verifyCode = value
            })
            .width('70%')
            .height(48)
            .fontSize(16)
            .backgroundColor('#F5F5F5')
            .borderRadius(8)
            .margin({ right: 12 })
            .padding({ left: 12, right: 12 })

          Button({
            type: ButtonType.Capsule
          }) {
            Text(this.countdown > 0 ? `${this.countdown}秒后重试` : '获取验证码')
              .fontSize(14)
              .fontColor(this.isPhoneValid && this.countdown === 0 ? '#FFFFFF' : '#999999')
          }
          .width('25%')
          .height(48)
          .backgroundColor(this.isPhoneValid && this.countdown === 0 ? '#2196F3' : '#F5F5F5')
          .enabled(this.isPhoneValid && this.countdown === 0)
          .onClick(() => this.sendVerifyCode())
        }
        .width('100%')

        // 提示信息
        if (!this.isPhoneValid && this.phoneNumber.length > 0) {
          Text('请输入正确的手机号码')
            .fontSize(12)
            .fontColor('#FF0000')
            .margin({ top: 4 })
        }
      }
      .width('100%')
      .padding(16)

      // 说明文本
      Text('注:验证码将发送至您的手机,请注意查收')
        .fontSize(12)
        .fontColor('#999999')
        .margin({ top: 24 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}

三、代码解析

1. 状态管理

  • 管理手机号和验证码
  • 控制倒计时状态
  • 验证手机号有效性

2. 输入框设计

  • 实现手机号格式化
  • 添加验证码输入
  • 设置输入限制

3. 验证功能

  • 实现手机号验证
  • 控制验证码发送
  • 管理倒计时逻辑

4. 交互实现

  • 实时格式化显示
  • 验证码发送反馈
  • 倒计时显示

四、实现效果

运行代码后,将展示一个完整的手机号验证功能:

  1. 手机号输入框
  2. 验证码输入框
  3. 获取验证码按钮
  4. 实时验证提示

五、总结

本案例通过HarmonyOS NEXT的TextInput组件实现了一个功能完善的手机号码输入框,

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐