HarmonyOSNext模块化计划实践:打造简洁高效的登录注册页面 ...

打印 上一主题 下一主题

主题 1036|帖子 1036|积分 3108

涉及知识点和装饰器



  • @ComponentV2,@Local, @Builder,@Extend, @Event,!!双向绑定,@Require ,@Param,preferences首选项
先上结果图




完备代码

登录页

  1. import { Route } from '@hzw/zrouter'
  2. import { CommonConst, NavName } from 'utils'
  3. import { ToastUtil } from '@pura/harmony-utils'
  4. import { SwitchLoginTypeComp } from '../components/SwitchLoginTypeComp'
  5. import { LoginService } from '../service/LoginService'
  6. import json from '@ohos.util.json'
  7. @Preview
  8. @ComponentV2
  9. @Route({ name: NavName.LOGIN_VIEW, description: '登录/注册页' })
  10. export struct LoginView {
  11.   @Local account: string = '' //  用户名
  12.   @Local password: string = '' // 密码
  13.   @Local isLogin: boolean = true // 登录注册切换
  14.   aboutToAppear(): void {
  15.     // console.log(`xxx : ---` + 'LoginView')
  16.     // console.log(`xxx获取参数 : ---` + ZRouter.getInstance().getParamByName(NavName.LOGIN_VIEW).toString())
  17.   }
  18.   build() {
  19.     NavDestination() {
  20.       Column() {
  21.         this.headBuilder()
  22.        // 登录,注册页面
  23.         SwitchLoginTypeComp({
  24.           changeFactory: (account: string, password: string, isLogin: boolean) => {
  25.             console.log(`xxx : ---account--` + account + ',password--' + password + ',isLogin--' + isLogin)
  26.             this.account = account
  27.             this.password = password
  28.             this.loadNet()
  29.           }
  30.         })
  31.       }.width(CommonConst.FULL_PARENT)
  32.       .height(CommonConst.FULL_PARENT)
  33.     }
  34.     .hideTitleBar(true)
  35.     .backgroundColor($r('app.color.white'))
  36.     .width(CommonConst.FULL_PARENT)
  37.     .height(CommonConst.FULL_PARENT)
  38.   }
  39.   async loadNet() {
  40.     let login = await LoginService.login({
  41.       'username': this.account,
  42.       'password': this.password
  43.     })
  44.     console.log('xxxlogin--' + '' + json.stringify(login))
  45.     if (login.data?.getSuccess()) {
  46.       console.log('xxxxxdata参数--' + '' + json.stringify(login.data.getData()))
  47.     } else {
  48.       console.log('xxx--' + login.data?.getMsg())
  49.       ToastUtil.showToast(login.data?.getMsg())
  50.     }
  51.   }
  52.   /** 头部 */
  53.   @Builder
  54.   headBuilder() {
  55.     Stack({ alignContent: Alignment.Top }) {
  56.       Text()
  57.         .width(CommonConst.FULL_PARENT)
  58.         .height(250)
  59.         .backgroundColor($r('app.color.colorPrimary'))
  60.       Text()
  61.         .width(CommonConst.FULL_PARENT)
  62.         .height(100)
  63.         .backgroundColor(Color.White)
  64.         .borderRadius(50)
  65.         .margin({ top: 210 })
  66.       Image($r('app.media.ic_close'))
  67.         .width(20)
  68.         .height(20)
  69.         .position({ x: 20, y: 20 })
  70.         .onClick(() => {
  71.           ToastUtil.showToast('关闭')
  72.         })
  73.       Column({ space: 7 }) {
  74.         Image($r('app.media.startIcon')).width(100).height(100)
  75.         Text('欢迎使用').fontSize(22).fontColor($r('app.color.white')).fontWeight(FontWeight.Bold)
  76.         Text('本APP由JasonYin独立开发').fontSize(12).fontColor($r('app.color.white'))
  77.       }.margin({ top: 44 })
  78.     }.width(CommonConst.FULL_PARENT)
  79.   }
  80. }
复制代码
登录/注册页面自界说组件

  1. import { ToastUtil } from '@pura/harmony-utils'
  2. import { CommonConst } from "utils"
  3. import { ProtocolComp } from "./ProtocolComp"
  4. @Extend(TextInput)
  5. function inputStyle() {
  6.   .height(44)
  7.   .fontColor($r('app.color.color_222222'))
  8.   .fontSize(16)
  9.   .placeholderColor($r('app.color.color_999999'))
  10.   .placeholderFont({ size: 16 })
  11.   .backgroundColor($r('app.color.white'))
  12.   .caretColor($r('app.color.colorPrimary'))
  13.   .padding({ left: 8 })
  14. }
  15. @Extend(Divider)
  16. function dividerStyle() {
  17.   .strokeWidth(1)
  18.   .color($r('app.color.color_F0F0F0'))
  19.   .padding({ left: 60, right: 60 })
  20. }
  21. /**
  22. * Author:J
  23. * Describe: 登录,注册页面
  24. */
  25. @ComponentV2
  26. export struct SwitchLoginTypeComp {
  27.   @Local account: string = '鸿蒙屌爆了' //  用户名
  28.   @Local password: string = '123456' // 密码
  29.   @Local confirmPassword: string = '' // 确认密码
  30.   @Local isLogin: boolean = true // 登录注册切换
  31.   @Local selectProtocol: boolean = false; //是否勾选协议
  32.   @Local confirm: boolean = false; //是否弹窗协议
  33.   @Event changeFactory: (account: string, password: string, isLogin: boolean) => void = () => {
  34.   }
  35.   build() {
  36.     Column() {
  37.       Text() {
  38.         ImageSpan($r('app.media.ic_next'))
  39.           .width(15)
  40.           .colorBlend($r('app.color.colorPrimary'))
  41.           .rotate({ angle: 180 })
  42.           .margin({ right: 8, bottom: 2 })
  43.           .visibility(this.isLogin ? Visibility.Hidden : Visibility.Visible)
  44.         Span(this.isLogin ? '去注册' : '去登录')
  45.         ImageSpan($r('app.media.ic_next'))
  46.           .width(15).colorBlend($r('app.color.colorPrimary'))
  47.           .margin({ left: 8, bottom: 2 })
  48.           .visibility(this.isLogin ? Visibility.Visible : Visibility.Hidden)
  49.       }
  50.       .fontSize(15)
  51.       .fontColor($r('app.color.colorPrimary'))
  52.       .onClick(() => {
  53.         this.isLogin = !this.isLogin
  54.         this.account = ''
  55.         this.password = ''
  56.         this.confirmPassword = ''
  57.       })
  58.       Row() {
  59.         Image($r('app.media.ic_account_normal')).width(24).height(24)
  60.         TextInput({ placeholder: '请输入用户名', text: `${this.account}` })
  61.           .inputStyle()
  62.           .onChange((value: string) => {
  63.             this.account = value
  64.           })
  65.         Image($r('app.media.ic_delete')).width(14).height(14)
  66.           .visibility(this.account.length > 0 ? Visibility.Visible : Visibility.None)
  67.           .onClick(() => {
  68.             this.account = ''
  69.           })
  70.       }.width(CommonConst.FULL_PARENT).height(44).padding({ left: 60, right: 100 }).margin({ top: 40 })
  71.       Divider().dividerStyle()
  72.       Row() {
  73.         Image($r('app.media.ic_password_normal')).width(24).height(24)
  74.         TextInput({ placeholder: '请输入密码', text: `${this.password}` })
  75.           .inputStyle()
  76.           .type(InputType.Password)
  77.           .onChange((value: string) => {
  78.             this.password = value
  79.           })
  80.       }.width(CommonConst.FULL_PARENT).height(44).padding({ left: 60, right: 60 })
  81.       Divider().dividerStyle()
  82.       Row() {
  83.         Image($r('app.media.ic_password_normal')).width(24).height(24)
  84.         TextInput({ placeholder: '请确认密码', text: `${this.confirmPassword}` })
  85.           .inputStyle()
  86.           .type(InputType.Password)
  87.           .onChange((value: string) => {
  88.             this.confirmPassword = value
  89.           })
  90.       }
  91.       .width(CommonConst.FULL_PARENT)
  92.       .height(44)
  93.       .padding({ left: 60, right: 60 })
  94.       .visibility(this.isLogin ? Visibility.None : Visibility.Visible)
  95.       Divider().dividerStyle()
  96.       // 协议相关
  97.       ProtocolComp({ selectProtocol: this.selectProtocol!!, confirm: this.confirm!! })
  98.       Button(this.isLogin ? '登录' : '注册')
  99.         .width('80%')
  100.         .height(44)
  101.         .fontSize(15)
  102.         .fontColor($r('app.color.white'))
  103.         .backgroundColor($r('app.color.colorPrimary'))
  104.         .margin({ top: 31 })
  105.         .enabled(this.account.length > 0 && this.password.length > 0)
  106.         .onClick(() => {
  107.           if (!this.isLogin && this.password != this.confirmPassword) {
  108.             ToastUtil.showToast('两次密码不一致')
  109.             return
  110.           }
  111.           if (!this.selectProtocol) {
  112.             // ToastUtil.showToast('' + '请勾选协议')
  113.             this.confirm = !this.selectProtocol
  114.             return
  115.           }
  116.           this.changeFactory(this.account, this.password, this.isLogin)
  117.         })
  118.     }
  119.     .width(CommonConst.FULL_PARENT)
  120.     .margin({ top: -80 })
  121.   }
  122. }
复制代码
用户协议、隐私政策相关

  1. import { ToastUtil } from '@pura/harmony-utils'
  2. import { CommonConst } from "utils";
  3. /**
  4. * Author:J
  5. * Describe:协议
  6. */
  7. @ComponentV2
  8. export struct ProtocolComp {
  9.   @Require @Param selectProtocol: boolean=false //是否勾选协议
  10.   @Event $selectProtocol: (val: boolean) => void = () => {
  11.   }
  12.   @Require @Param confirm: boolean=false //是否弹窗协议
  13.   @Event $confirm: (val: boolean) => void = () => {
  14.   }
  15.   build() {
  16.     Column() {
  17.       Row() {
  18.         Checkbox()
  19.           .select(this.selectProtocol)
  20.           .selectedColor($r('app.color.colorPrimary'))
  21.           .onChange((value: boolean) => {
  22.             this.$selectProtocol(value)
  23.             //协议不选中,不赋值confirm
  24.             if (!value) {
  25.               return
  26.             }
  27.             this.$confirm(!value)
  28.           })
  29.         Text() {
  30.           span('登录即表示您已同意我们的 ', $r('app.color.color_999999'))
  31.           span('《隐私政策》', $r('app.color.colorPrimary'), 1, true)
  32.           span('、', $r('app.color.color_999999'))
  33.           span('《用户服务协议》', $r('app.color.colorPrimary'), 2, true)
  34.           span('、', $r('app.color.color_999999'))
  35.           span('《服务条款》', $r('app.color.colorPrimary'), 3, true)
  36.         }
  37.       }
  38.       .justifyContent(FlexAlign.Start)
  39.       .alignItems(VerticalAlign.Top)
  40.       .margin({ top: 14, right: 30 })
  41.       // 若没有勾选协议,则会出现提示文本:“请阅读并勾选协议”
  42.       if (this.confirm) {
  43.         Row() {
  44.           Column() {
  45.             Image($r('app.media.login_popup'))
  46.               .width(10)
  47.               .height(10)
  48.               .position({ x: 7, y: 1 })
  49.               .opacity(0.8)
  50.             Text('请阅读并勾选协议')
  51.               .fontColor($r('app.color.white'))
  52.               .fontSize(10)
  53.               .textAlign(TextAlign.Center)
  54.               .backgroundColor($r('app.color.black'))
  55.               .width(100)
  56.               .height(20)
  57.               .position({ x: 3, y: 9 })
  58.               .borderRadius(4)
  59.               .opacity(0.8)
  60.           }
  61.           .width(100)
  62.           .height(30)
  63.         }
  64.         .height(30)
  65.         .width('100%')
  66.       }
  67.     }.width(CommonConst.FULL_PARENT)
  68.     .height(50)
  69.     .padding({ left: 60, right: 60 })
  70.   }
  71. }
  72. @Builder
  73. function span(value: string | Resource, fontColor: ResourceColor, k: number = 0, isClick: boolean = false) {
  74.   Span(value)
  75.     .fontColor(fontColor)
  76.     .fontSize(12)
  77.     .onClick(() => {
  78.       if (!isClick) {
  79.         return
  80.       }
  81.       ToastUtil.showToast(`我要进web页面了k:${value}=====值:${k}`)
  82.     })
  83. }
复制代码
使用首选项存储用户信息到本地

  1. // 存
  2. PreferencesUtil.put(PreferencesConst.KEY_LOGIN_USER_BEAN, JSONUtil.beanToJsonStr(login.data?.getData()))
  3. // 取
  4. let user = await PreferencesUtil.getString(PreferencesConst.KEY_LOGIN_USER_BEAN)
  5. let userBean = JSONUtil.jsonToBean(UserLoginBean, user)
复制代码
以往系列文章


  • 《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 模块化底子篇》
  • 《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 构建底子特性层》
  • 《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 构建公共能力层》
  • 《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— Tabs底部导航栏》
  • 《探索 HarmonyOS NEXT (5.0):开启构建模块化项目架构奇幻之旅 —— 动态路由 ZRouter:引领高效模块通讯的智慧中枢》
  • 《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 ——第三方库的使用:网络哀求RCP、二次封装上下拉革新、弹窗》
  • HarmonyOS NEXT:模块化项目 ——修改应用图标+启动页等
若本文对您稍有资助,诚望您不吝点赞,多谢。
有兴趣的同砚可以点击检察源码



  • gitee:https://gitee.com/jiaojiaoone/explore-harmony-next/tree/case%2Fwanandroid/
  • github:https://github.com/JasonYinH/ExploreHarmonyNext.git
接待加我微信一起交换:+V:yinshiyuba


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

圆咕噜咕噜

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表