密码或验证码登录页面完整代码

对于登录主页的展示分为账号密码登录与短信验证码登录两种

密码或验证码登录页面完整代码-鸿蒙开发者社区

通过左边的蓝色按钮进行控制组件的选择展示

密码或验证码登录页面完整代码-鸿蒙开发者社区

HarmonyOS
2024-05-26 11:54:13
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
rhlee

OS核心APi

build() { 
 Column() { 
   Image($r('app.media.logo')) 
    .width($r('app.float.logo_image_size')) 
    .height($r('app.float.logo_image_size')) 
    .margin({ top: $r('app.float.logo_margin_top'), bottom: $r('app.float.logo_margin_bottom') }) 
   Text(this.loginMessage) 
    .fontSize($r('app.float.page_title_text_size')) 
    .fontWeight(FontWeight.Medium) 
    .fontColor($r('app.color.title_text_color')) 
   Text(this.isCode ? "新用户验证码登录后注册":$r('app.string.login_more')) 
    .fontSize($r('app.float.normal_text_size')) 
    .fontColor($r('app.color.login_more_text_color')) 
    .margin({ bottom: $r('app.float.login_more_margin_bottom'), top: $r('app.float.login_more_margin_top') }) 
    }

可以通过阅读代码发现,通过一个isCode判断登录是通过验证码还是账号密钥

Text(this.isCode ? "新用户验证码登录后注册":$r('app.string.login_more'))

将关注焦点移到此处

@State isCode: boolean = false;

​Row() { 
 Text(this.isCode ?  $r('app.string.passWord_login') : $r('app.string.message_login')).blueTextStyle() 
  .onClick(()=>{ 
     this.isCode=!this.isCode; 
     this.loginMessage=this.isCode? "短信验证码登录" : "账号密钥登录" 
     console.log(String(this.isCode)) 
     console.log(String(this.isShowProgress)) 
     // router.replaceUrl({ url: 'pages/MainPage' }); 
  }) 
​ 
 Text(this.isCode ?  "" :"游客模式").blueTextStyle() 
  .onClick(()=>{ 
     router.replaceUrl({ url: 'pages/MainPage' }) 
  }) 
}

核心代码解释

发现双向绑定的isCode控制组件展示,OnClick通过点击回调函数完成状态false与true的选择

Text(this.isCode ? "" :"游客模式").blueTextStyle() .onClick(()=>{ router.replaceUrl({ url: 'pages/MainPage' }) })

游客登录可以直接预览主页面,可能有人会有访问权限方面的顾虑,游客访问安全吗?

本项目设计了接口请求文档,并定义了访问白名单。用户未进行Token权限认证仅能预览页面,无法读取用户信息,

import { getCode, loginCode, userLogin } from '../Api/UserApi/UserApi'; 
import UserLoginDto from '../model/dto/UserLoginDto'; 
import ResponseResult from '../model/vo/ResponseResult'; 
import prompt from '@ohos.promptAction'; 
import router from '@ohos.router'; 
import { CommonConstants } from '../common/constants/CommonConstants'; 
import LoginCodeDto from '../model/dto/LoginCodeDto'; 
import { validMobile } from '../common/utils/CommonUtils'; 
// import PreferencesUtil from '../common/utils/PreferencesUtil' 
import UserToken from '../model/vo/UserToken'; 
import PreferenceModel from '../model/dataStorage/PreferenceModel'; 
​ 
​ 
@Extend(TextInput) 
function inputStyle() { 
.placeholderColor($r('app.color.placeholder_color')) 
.height($r('app.float.login_input_height')) 
.fontSize($r('app.float.big_text_size')) 
.backgroundColor($r('app.color.background')) 
.width(CommonConstants.FULL_PARENT) 
.padding({ left: CommonConstants.INPUT_PADDING_LEFT }) 
.margin({ left:0,top: $r('app.float.input_margin_top') }) 
} 
​ 
@Extend(Line) 
function lineStyle() { 
.width(CommonConstants.FULL_PARENT) 
.height($r('app.float.line_height')) 
.backgroundColor($r('app.color.line_color')) 
} 
​ 
@Extend(Text) 
function blueTextStyle() { 
.fontColor($r('app.color.login_blue_text_color')) 
.fontSize($r('app.float.small_text_size')) 
.fontWeight(FontWeight.Medium) 
} 
​ 
​ 
@Component 
export struct LoginByPassWordOrCode { 
 @State params: UserLoginDto = new UserLoginDto(); 
 @State isShowProgress: boolean = false; 
 @State isCode: boolean = false; 
 @State isCanSend: boolean = true; 
 @State sendMessage: string = "发送验证码"; 
 @State loginMessage: string = "账号密钥登录" 
 @State loginCodeDto: LoginCodeDto = new LoginCodeDto(); 
 @State userToken:UserToken=new UserToken(); 
 private timeOutId: number = -1; 
 private timeFun: number; 
 private data: ResponseResult; 
​ 
​ 
 @Builder 
 imageButton(src: Resource) { 
   Button({ type: ButtonType.Circle, stateEffect: true }) { 
     Image(src).objectFit(ImageFit.Contain) 
  } 
  .height($r('app.float.other_login_image_size')) 
  .width($r('app.float.other_login_image_size')) 
  .backgroundColor($r('app.color.background')) 
} 
​ 
 async loginByPassWord(): Promise<void> { 
   console.log(this.params.userName) 
​ 
   if ((this.params.userName === '' || this.params.userName === undefined) || (this.params.passWord === '' || this.params.passWord === undefined)) { 
     prompt.showToast({ 
       message: $r('app.string.input_empty_tips') 
    }) 
  } 
​ 
   this.data = await userLogin(this.params) 
   console.log(JSON.stringify(this.data)) 
   console.log(typeof (this.data.code)) 
   console.log(typeof (CommonConstants.SERVER_CODE_SUCCESS)) 
   if (Number(this.data.code) === CommonConstants.SERVER_CODE_SUCCESS) { 
     PreferenceModel.writeData(this.data.data,CommonConstants.KEY_TOKEN) 
     if (this.timeOutId === -1) { 
       this.isShowProgress = true; 
       this.timeOutId = setTimeout(() => { 
         this.isShowProgress = false; 
         this.timeOutId = -1; 
​ 
​ 
         router.replaceUrl({ url: 'pages/MainPage' }); 
      }, CommonConstants.LOGIN_DELAY_TIME); 
    } 
  } else { 
     prompt.showToast({ 
       message: this.data.msg 
    }) 
  } 
   PreferenceModel.getData(CommonConstants.KEY_TOKEN).then((resultData: UserToken) => { 
     if (resultData) { 
       this.userToken = resultData; 
    } 
     console.log("首选项userToken:"+JSON.stringify(this.userToken)) 
  }); 
​ 
} 
​ 
 async getCode(): Promise<void> { 
​ 
   // if (this.loginCodeDto.phone === '' || this.loginCodeDto.phone=== undefined ) { 
   //   prompt.showToast({ 
   //     message: "请输入手机号" 
   //   }) 
   // }else{ 
   //   if(!validMobile(this.loginCodeDto.phone)){ 
   //     prompt.showToast({ 
   //       message: "请输入正确格式的手机号" 
   //     }) 
   if (!validMobile(this.loginCodeDto)) { 
  } else { 
     this.isShowProgress = true; 
     this.data = await getCode(this.loginCodeDto) 
     console.log(JSON.stringify(this.data)) 
     this.isShowProgress = false; 
​ 
     this.isCanSend = false; 
     let timer = 60; 
     this.sendMessage = timer + "s"; 
     this.timeFun = setInterval(() => { 
       --timer; 
       this.sendMessage = timer + "s"; 
       if (timer == 0) { 
         this.isCanSend = true; 
         this.sendMessage = "重新发送"; 
         clearInterval(this.timeFun); 
      } 
    }, 1000); 
  } 
} 
​ 
 async loginByCode():Promise<void>{ 
       this.isShowProgress = true; 
       this.data = await loginCode(this.loginCodeDto); 
       // console.log(this.data.data.toString()) 
       this.userToken=this.data.data as unknown as UserToken 
       // PreferencesUtil.saveToken(this.userToken.token) 
       console.log(JSON.stringify(this.userToken)) 
       this.isShowProgress = false; 
​ 
      if (Number(this.data.code) === CommonConstants.SERVER_CODE_SUCCESS) { 
        PreferenceModel.writeData(this.data.data,CommonConstants.KEY_TOKEN) 
         router.replaceUrl({ url: 'pages/MainPage' }); 
​ 
  } else { 
     prompt.showToast({ 
       message: this.data.msg 
    }) 
  } 
​ 
   PreferenceModel.getData(CommonConstants.KEY_TOKEN).then((resultData: UserToken) => { 
     if (resultData) { 
       this.userToken = resultData; 
    } 
     console.log("首选项userToken:"+JSON.stringify(this.userToken)) 
  }); 
} 
​ 
​ 
 aboutToDisappear() { 
   clearTimeout(this.timeOutId); 
   this.timeOutId = -1; 
} 
​ 
 build() { 
   Column() { 
     Image($r('app.media.logo')) 
      .width($r('app.float.logo_image_size')) 
      .height($r('app.float.logo_image_size')) 
      .margin({ top: $r('app.float.logo_margin_top'), bottom: $r('app.float.logo_margin_bottom') }) 
     Text(this.loginMessage) 
      .fontSize($r('app.float.page_title_text_size')) 
      .fontWeight(FontWeight.Medium) 
      .fontColor($r('app.color.title_text_color')) 
     Text(this.isCode ? "新用户验证码登录后注册":$r('app.string.login_more')) 
      .fontSize($r('app.float.normal_text_size')) 
      .fontColor($r('app.color.login_more_text_color')) 
      .margin({ bottom: $r('app.float.login_more_margin_bottom'), top: $r('app.float.login_more_margin_top') }) 
​ 
     if(!this.isCode){ 
       TextInput({ placeholder:$r('app.string.account') }) 
        .maxLength(CommonConstants.INPUT_ACCOUNT_LENGTH) 
        .type(this.isCode?  InputType.Number : InputType.Normal ) 
        .inputStyle() 
        .onChange((value: string) => { 
           this.params.userName = value; 
        }) 
       Line().lineStyle() 
       TextInput({ placeholder: $r('app.string.password') }) 
        .maxLength(CommonConstants.INPUT_PASSWORD_LENGTH) 
        .type(InputType.Password) 
        .inputStyle() 
        .onChange((value: string) => { 
           this.params.passWord = value; 
        }) 
       Line().lineStyle() 
    }else { 
       TextInput({ placeholder: $r('app.string.phone') }) 
        .maxLength(CommonConstants.INPUT_ACCOUNT_LENGTH) 
        .type(this.isCode?  InputType.Number : InputType.Normal ) 
        .inputStyle() 
        .onChange((value: string) => { 
           this.loginCodeDto.phone = value; 
        }) 
       Line().lineStyle() 
       Row() { 
         TextInput({ placeholder: $r('app.string.code') }) 
          .maxLength(CommonConstants.INPUT_PASSWORD_LENGTH) 
          .type(InputType.Number) 
          .inputStyle() 
          .width("80%") 
          .onChange((value: string) => { 
             this.loginCodeDto.code=value; 
          }) 
​ 
         if (this.isCanSend) { 
           Text(this.sendMessage).blueTextStyle().width("30%") 
            .onClick(() => { 
               this.getCode() 
               // router.replaceUrl({ url: 'pages/MainPage' }); 
            }) 
        }else{ 
           Text(this.sendMessage).blueTextStyle().width("30%") 
        } 
      }.JUSTIFYCONTENT(FLEXALIGN.START) 
         LINE().LINESTYLE() 
    } 
​ 
     ROW() { 
       TEXT(THIS.ISCODE ?  $R('APP.STRING.PASSWORD_LOGIN') : $R('APP.STRING.MESSAGE_LOGIN')).BLUETEXTSTYLE() 
        .ONCLICK(()=>{ 
           THIS.ISCODE=!THIS.ISCODE; 
           THIS.LOGINMESSAGE=THIS.ISCODE? "短信验证码登录" : "账号密钥登录" 
           CONSOLE.LOG(STRING(THIS.ISCODE)) 
           CONSOLE.LOG(STRING(THIS.ISSHOWPROGRESS)) 
           // ROUTER.REPLACEURL({ URL: 'PAGES/MAINPAGE' }); 
        }) 
​ 
       TEXT(THIS.ISCODE ?  "" :"游客模式").BLUETEXTSTYLE() 
        .ONCLICK(()=>{ 
           ROUTER.REPLACEURL({ URL: 'PAGES/MAINPAGE' }) 
        }) 
    } 
    .JUSTIFYCONTENT(FLEXALIGN.SPACEBETWEEN) 
    .WIDTH(COMMONCONSTANTS.FULL_PARENT) 
    .MARGIN({ TOP: $R('APP.FLOAT.FORGOT_MARGIN_TOP') }) 
​ 
     BUTTON($R('APP.STRING.LOGIN'), { TYPE: BUTTONTYPE.CAPSULE }) 
      .WIDTH(COMMONCONSTANTS.BUTTON_WIDTH) 
      .HEIGHT($R('APP.FLOAT.LOGIN_BUTTON_HEIGHT')) 
      .FONTSIZE($R('APP.FLOAT.NORMAL_TEXT_SIZE')) 
      .FONTWEIGHT(FONTWEIGHT.MEDIUM) 
      .BACKGROUNDCOLOR($R('APP.COLOR.LOGIN_BUTTON_COLOR')) 
      .MARGIN({ TOP: $R('APP.FLOAT.LOGIN_BUTTON_MARGIN_TOP'), BOTTOM: $R('APP.FLOAT.LOGIN_BUTTON_MARGIN_BOTTOM') }) 
      .ONCLICK(() => { 
         THIS.ISCODE? THIS.LOGINBYCODE() :THIS.LOGINBYPASSWORD(); 
      }) 
​ 
     IF (THIS.ISSHOWPROGRESS) { 
       LOADINGPROGRESS() 
        .COLOR($R('APP.COLOR.LOADING_COLOR')) 
        .WIDTH($R('APP.FLOAT.LOGIN_PROGRESS_SIZE')) 
        .HEIGHT($R('APP.FLOAT.LOGIN_PROGRESS_SIZE')) 
        .MARGIN({ TOP: $R('APP.FLOAT.LOGIN_PROGRESS_MARGIN_TOP') }) 
    } 
​ 
     BLANK() 
     IF(!THIS.ISCODE) { 
       TEXT($R('APP.STRING.OTHER_LOGIN_METHOD')) 
        .FONTCOLOR($R('APP.COLOR.OTHER_LOGIN_TEXT_COLOR')) 
        .FONTSIZE($R('APP.FLOAT.LITTLE_TEXT_SIZE')) 
        .FONTWEIGHT(FONTWEIGHT.MEDIUM) 
        .MARGIN({ TOP: $R('APP.FLOAT.OTHER_LOGIN_MARGIN_TOP'), BOTTOM: $R('APP.FLOAT.OTHER_LOGIN_MARGIN_BOTTOM') }) 
       ROW({ SPACE: COMMONCONSTANTS.LOGIN_METHODS_SPACE }) { 
         THIS.IMAGEBUTTON($R('APP.MEDIA.HUAWEI')) 
         THIS.IMAGEBUTTON($R('APP.MEDIA.QQ')) 
         THIS.IMAGEBUTTON($R('APP.MEDIA.WEIXIN')) 
      } 
    } 
  } 
  .BACKGROUNDCOLOR($R('APP.COLOR.BACKGROUND')) 
  .HEIGHT(COMMONCONSTANTS.FULL_PARENT) 
  .WIDTH(COMMONCONSTANTS.FULL_PARENT) 
  .PADDING({ 
     LEFT: $R('APP.FLOAT.PAGE_PADDING_HOR'), 
     RIGHT: $R('APP.FLOAT.PAGE_PADDING_HOR'), 
     BOTTOM: $R('APP.FLOAT.LOGIN_PAGE_PADDING_BOTTOM') 
  }) 
} 
}

对此进行模块解析结构就清楚了

实现效果

  •  loginByPassWorfd 密钥登录方法
  • getCode获取验证码方法
  • loginByCode 验证码登录方法

通过isCode变量选择loginByPassWorfd 密钥登录方法或者loginByCode 验证码登录方法,其中封装了http请求发送数据并解析,对于返回的数据再写入到首选项数据库供项目全局使用,后面再通过请求携带token访问后端,再将数据解析渲染。

在后续通过token获得用户信息userInfo后,存入首选项数据库,在我的设置页面setting中取出显示。

分享
微博
QQ
微信
回复
2024-05-27 15:47:57
相关问题
前端验证码配合后端的实现思路?
2218浏览 • 1回复 待解决
使用华为账号服务登录的示例代码
599浏览 • 1回复 待解决
Web能直接加载h5代码吗?
1712浏览 • 2回复 待解决
如何调试H5代码,有人知道吗?
625浏览 • 1回复 待解决
工具类里 怎么跳转打开页面呢?
2475浏览 • 1回复 待解决
相册扫识别多失败
699浏览 • 1回复 待解决
版本新增taskpool的相关功能验证
407浏览 • 1回复 待解决
PolarDB MySQL如何验证读写分离?
1255浏览 • 1回复 待解决
验证手机号是否已被注册/绑定功能?
2488浏览 • 1回复 待解决