鸿蒙案例----登陆界面详解

1,040 阅读4分钟

案例--登陆界面

前言

新手找案例练手的看过来

登录界面,几乎每个app都能用得到,可以说是十分具有代表性

因此拿来练手再合适不过了

下面进入正题

首先随便找一个App的登陆页面,然后开始实现

image-20240829105955438

这是我找的某米app的的登陆页面,首先把主要布局先实现

主要思路
  1. 一个大Column包括全部组件
  2. 下面一个image,两个textInput接收用户输入的账号、密码等信息,密码那栏的textInput设置一个password类型,防止密码泄露
  3. 一个button按钮,匹配已经储存的账号密码信息,核对是否正确,是,则提示弹窗登录成功,否则提示账号错误,或密码错误
  4. 剩余几个text文本在这里我没有去实现,因为涉及到页面的跳转,因此,在此只作为普通的text文本来使用

image-20240829110901746

主要代码(布局部分不过多赘述,原因很简单,过于重复和无趣,而且只可意会,不可言传,dddd)

Column() {
      Column() {
        Image($r('app.media.ic_xiaomi_logo'))
          .width(50)
        // 登录信息+密码登录
        Column({ space: 20 }) {
          // 账号输入框
          TextInput({ placeholder: '小米账号/手机号/邮箱' })
            .placeholderColor('#ccc')
            .backgroundColor(Color.Transparent)
            .border({ width: { bottom: .5 }, color: '#ccc' })
            .padding(0)
            .height(48)

          TextInput({ placeholder: '密码' })
            .placeholderColor('#ccc')
            .backgroundColor(Color.Transparent)
            .border({ width: { bottom: .5 }, color: '#ccc' })
            .padding(0)
            .height(48)

            .type(InputType.Password)
            .passwordIcon({
              offIconSrc: $r('app.media.ic_eyes_open'),
              onIconSrc: $r('app.media.ic_eyes_close'),
            })

        }
        .margin({ top: 30 })
        // 底部区域
        Column({ space: 15 }) {
          Row() {
            Text('忘记密码')
          }
          .width('100%')
          .justifyContent(FlexAlign.End)
          Button('登  录')
            .width('100%')
            .backgroundColor('#b6854e')
            .fontSize(14)
            .fontWeight(600)
          Row() {
            Text('立即注册')
            Text('短信登录')
          }
          .width('100%')
          .justifyContent(FlexAlign.SpaceBetween)
        }
        .margin({ top: 15 })
      }
      .margin({ top: 60 })
    }
    .padding({
      top: 30,
      left: 30,
      right: 30,
      bottom: 50
    })
    .height('100%')
主要功能实现
  1. 首先设置初始账号密码为了和用户的数据进行比较
  2. 接着设置两个状态变量来获取用户输入的账号密码信息,初始值给上空字符串
Num: string = 'admin'
pw: string = '123456'
@State phoneNumber: string = ''
@State password: string = ''
  1. 设置textInput的参数text,将两个状态变量设置给text并使用$$双向绑定,实现数据改变UI改变,UI改变数据改变
TextInput({ placeholder: '小米账号/手机号/邮箱', text: $$this.phoneNumber })
TextInput({ placeholder: '密码', text: $$this.password })
  1. 在点击事件中设置判断账号密码的语句,先判断账号是否正确,不正确则提示弹窗账号错误然后返回,正确则继续判断密码,如果不正确就提示弹窗密码错误然后返回,正确则提示登录成功,然后判断结束
.onClick(() => {
              if (this.phoneNumber != this.Num) {
                promptAction.showToast({ message: '账号错误' })
                return
              }
              if (this.password != this.pw) {
                promptAction.showToast({ message: '密码错误' })
                return
              }
              promptAction.showToast({ message: '登录成功' })
            })
  1. 补充

    TextInput使用

    TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController})
    

    参数

    参数名说明
    placeholder设置无输入时的提示文本
    text设置输入框当前的文本内容

    常用属性

    属性名描述
    type设置输入框类型InputType枚举值
    showUnderline是否开启下划线
    passwordIcononIconSrc:输入状态时图
    offIconSrc:隐藏状态时图标
    placeholderColor设置placeholder文本的颜色

    InputType枚举值常用

    名称描述
    Normal基本输入模式。 可输入数字、字母、下划线、空格、特殊字符
    Password密码输入模式。支持输入数字、字母、下划线、空格、特殊字符。密码显示小眼睛图标并且默认会将文字变成圆点。密码输入模式不支持下划线样式。在已启用密码保险箱的情况下,支持用户名、密码的自动保存和自动填充
    Email邮箱地址输入模式。支持数字,字母,下划线,.字符,以及@字符(只能存在一个@字符)
    Number纯数字输入模式

补充--验证码获取的功能

  1. 验证码获取有两种状态,一种是未获取时,一种是正在获取的倒计时

image-20240829152452101

image-20240829152508708

老样子,先把布局写出来

由于正常的验证码也是要核对的,因此我也用了TextInput来实现,

Row() {
            TextInput()
              .border({ width: 2, color: '#B6854D' })
              .borderRadius(0)
              .width("60%")
            Text(this.sel == true ? `${this.time}秒后再次获取` : `获取验证码`)
              .layoutWeight(1)
              .textAlign(TextAlign.Center)
}

注意这里我用了一个三元表达式,辅助实现两种状态的切换

  1. 具体实现

设置两个状态变量,一个控制倒计时,一个控制点击状态

  @State time: number = 60
  @State sel: boolean = false

设置一个定时器并设置一个变量a来保存定时器的id,点击后触发倒计时,1秒时间减一次,当减少到0把点击状态、时间重置,并使用该变量a清除定时器

.onClick(() => {
                this.sel = true
                this.time--
                let a = setInterval(() => {
                  this.time--
                  if (this.time == 0) {
                    this.time = 60
                    this.sel = false
                    clearInterval(a)
                  }
                }, 1000)
              })

还要设置该text的状态,防止点击事件被多次触发,导致启动多个定时器

.enabled(this.sel == false)
  1. 补充

    三元表达式

    条件语句  ?  语句1  :  语句2
    

    当条件语句成立,执行语句1,不成立,则执行语句2

    定时器

    setInterval(()=>{},时间)
    

    参数是一个回调函数,一个时间(单位毫秒)

    还有一个重要属性--返回值,为该定时器的ID,就是该例子中的a,用来清除定时器时使用

OVER-----OVER-----OVER