HarmonyOS开发学习:项目案例实战-教务系统登录注册

46 篇文章 0 订阅
46 篇文章 0 订阅

 一、所需知识

完成组件学习
  • Text组件

  • Image组件

  • TextInput组件

  • Button组件

  • LoadingProgess组件

  • Flex组件

  • Column组件

  • Row组件

  • List组件

  • Swiper组件

  • Grid组件

二、效果图

三、详细知识点内容

1. Text组件:

显示一段文本的组件。

2. Image组件:

Image为图片组件,常用于在应用中显示图片。Image支持加载string、PixelMap和Resource类型的数据源,支持png、jpg、bmp、svg和gif类型的图片格式。

3. TextInput组件:

单行文本输入框组件。

4. Button组件:

按钮组件,可快速创建不同样式的按钮。

5. LoadingProgress组件:

用于显示加载动效的组件。

6. Flex组件:

以弹性方式布局子组件的容器组件。

7. Column组件:

沿垂直方向布局的容器。

8. Row组件:

沿水平方向布局容器。

9. List组件:

列表包含一系列相同宽度的列表项。适合连续、多行呈现同类数据,例如图片和文本。

10. Swiper组件:

滑块视图容器,提供子组件滑动轮播显示的能力。

11. Grid组件:

网格容器,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。

四、完整代码

1. 注册页:

import prompt from '@ohos.promptAction';
import router from '@ohos.router';
@Extend(TextInput)
function inputStyle() {
  .placeholderColor('#99182431')
  .height(48)
  .fontSize(45)
  .backgroundColor('#F1F3F5')
  .width('100%')
  .padding({ left: 0 })
  .margin({ top: 12 })
}

@Extend(Line)
function lineStyle() {
  .width('100%')
  .height(1)
  .backgroundColor('#33182431')
}

@Extend(Text)
function blueTextStyle() {
  .fontColor('#007DFF')
  .fontSize(14)
  .fontWeight(FontWeight.Medium)
}

/**
 * 注册页
 */
@Entry
@Component
struct LoginPage {
 @State account: string = '';
 @State password: string = '';
 @State rpassword: string = '';
 @State isShowProgress: boolean = false;
 private timeOutId: number = -1;
 @State isRegister: boolean = false;

 @Builder
 imageButton(src: Resource) {
  Button({ type: ButtonType.Circle, stateEffect: true }) {
   Image(src)
   }
   .height(48)
   .width(48)
   .backgroundColor('#F1F3F')
  }

 Register(): void {
  if (this.account === '' || this.password === '' || this.rpassword === '') {
   prompt.showToast({
    message: '输入不能为空'
    })
   } else {
   if (this.password != this.rpassword) {
    prompt.showToast({
     message: '输入的信息不正确,请核对后重新输入哟!!!'
     })
    } else {
    this.isShowProgress = true;
    if (this.timeOutId === -1) {
     this.timeOutId = setTimeout(() => {
      prompt.showToast({
       message: '注册成功'
       })
      this.isShowProgress = false;
      this.timeOutId = -1;
      router.pushUrl({
       url: 'pages/LoginPage',
       params:{
        account: this.account,
        password: this.password
        }
       });
      }, 2000);
     }
    }
   }
  }

 aboutToDisappear() {
  clearTimeout(this.timeOutId);
  this.timeOutId = -1;
  }

 build() {
  Column() {
   Image($r('app.media.logo'))
     .width(78)
     .height(78)
     .margin({ top: 100, bottom: 8 })
   Text('注册界面')
     .fontSize(24)
     .fontWeight(FontWeight.Medium)
     .fontColor('#182431')
   Text('注册以登录哟')
     .fontSize(16)
     .fontColor('#99182431')
     .margin({ bottom: 30, top: 8 })

   TextInput({ placeholder: '账号' })
     .maxLength(11)
     .type(InputType.Number)
     .inputStyle()
     .onChange((value: string) => {
     this.account = value;
     })
   Line().lineStyle()

   TextInput({ placeholder: '密码' })
     .maxLength(8)
     .type(InputType.Password)
     .inputStyle()
     .onChange((value: string) => {
      this.password = value;
     })
   Line().lineStyle()
   TextInput({ placeholder: '确认密码' })
     .maxLength(8)
     .type(InputType.Password)
     .inputStyle()
     .onChange((value: string) => {
      this.rpassword = value;
     })
   Line().lineStyle()

   Row() {
    Text('发送短信验证码').blueTextStyle()
    Text('重置').blueTextStyle()
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
    .margin({ top: 8 })

   Button('注册', { type: ButtonType.Capsule })
     .width('90%')
     .height(40)
     .fontSize(16)
     .fontWeight(FontWeight.Medium)
     .backgroundColor('#007DFF')
     .margin({ top: 87, bottom: 12 })
     .onClick(() => {
     this.Register();
     })
   Text('登录')
     .fontColor('#007DFF')
     .fontSize(16)
     .fontWeight(FontWeight.Medium)
    .onClick(() => {
    router.pushUrl({ url: 'pages/LoginPage'})
    })

   if (this.isShowProgress) {
    LoadingProgress()
      .color('#182431')
      .width(30)
      .height(30)
      .margin({ top: 20 })
    }

   Blank()
   Text('其他登录方式')
     .fontColor('#838D97')
     .fontSize(12)
     .fontWeight(FontWeight.Medium)
     .margin({ top: 50, bottom: 12 })
   Row({ space: 44 }) {
    this.imageButton($r('app.media.login_method1'))
    this.imageButton($r('app.media.login_method2'))
    this.imageButton($r('app.media.login_method3'))
    }
   }
   .backgroundColor('#F1F3F5')
   .height('100%')
   .width('100%')
   .padding({
   left: 12,
   right: 12,
   bottom: 24
   })
  }
}

2. 登录页:



import prompt from '@ohos.promptAction';
import router from '@ohos.router';
@Extend(TextInput)
function inputStyle() {
  .placeholderColor('#99182431')
  .height(48)
  .fontSize(45)
  .backgroundColor('#F1F3F5')
  .width('100%')
  .padding({ left: 0 })
  .margin({ top: 12 })
}


@Extend(Line)
function lineStyle() {
  .width('100%')
  .height(1)
  .backgroundColor('#33182431')
}


@Extend(Text)
function blueTextStyle() {
  .fontColor('#007DFF')
  .fontSize(14)
  .fontWeight(FontWeight.Medium)
}


/**
 * Login page
 */
@Entry
@Component
struct LoginPage {
 @State account: string = '';
 @State password: string = '';
 @State isShowProgress: boolean = false;
 private timeOutId: number = -1;
 @State isRegister: boolean = false;
 @State paccount: string = (router.getParams() as Record<string, string>)['account'];
 @State ppassword: string = (router.getParams() as Record<string, string>)['password'];


 @Builder
 imageButton(src: Resource) {
  Button({ type: ButtonType.Circle, stateEffect: true }) {
   Image(src)
   }
   .height(48)
   .width(48)
   .backgroundColor('#F1F3F')
  }


 login(): void {
  if (this.account === '' || this.password === '') {
   prompt.showToast({
    message: '输入不能为空'
    })
   } else {
   if ((this.account != this.paccount) || (this.password != this.ppassword)) {
    prompt.showToast({
     message: '用户名或密码不正确,请重新核对后输入'
     })
    } else {
    this.isShowProgress = true;
    if (this.timeOutId === -1) {
     this.timeOutId = setTimeout(() => {
      this.isShowProgress = false;
      this.timeOutId = -1;
      prompt.showToast({
       message: '登录成功!!!欢迎您' + this.account
       })
      router.pushUrl({ url: 'pages/MainPage' });
      }, 2000);
     }
    }
   }
  }


 aboutToDisappear() {
  clearTimeout(this.timeOutId);
  this.timeOutId = -1;
  }


 build() {
  Column() {
   Image($r('app.media.logo'))
     .width(78)
     .height(78)
     .margin({ top: 100, bottom: 8 })
   Text('登录界面')
     .fontSize(24)
     .fontWeight(FontWeight.Medium)
     .fontColor('#182431')
   Text('登录以获取更多服务')
     .fontSize(16)
     .fontColor('#99182431')
     .margin({ bottom: 30, top: 8 })


   TextInput({ placeholder: '账号' })
     .maxLength(11)
     .type(InputType.Number)
     .inputStyle()
     .onChange((value: string) => {
     this.account = value;
     })
   Line().lineStyle()


   TextInput({ placeholder: '密码' })
     .maxLength(8)
     .type(InputType.Password)
     .inputStyle()
     .onChange((value: string) => {
      this.password = value;
     })
   Line().lineStyle()


   Row() {
    Text('短信验证码登录').blueTextStyle()
    Text('忘记密码').blueTextStyle()
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
    .margin({ top: 8 })


   Button('登录', { type: ButtonType.Capsule })
     .width('90%')
     .height(40)
     .fontSize(16)
     .fontWeight(FontWeight.Medium)
     .backgroundColor('#007DFF')
     .margin({ top: 87, bottom: 12 })
     .onClick(() => {
     this.login();
     })
   Text('注册账号')
     .fontColor('#007DFF')
     .fontSize(16)
     .fontWeight(FontWeight.Medium)
    .onClick(() => {
    router.pushUrl({ url: 'pages/RegisterPage'})
    })


   if (this.isShowProgress) {
    LoadingProgress()
      .color('#182431')
      .width(30)
      .height(30)
      .margin({ top: 20 })
    }


   Blank()
   Text('其他登录方式')
     .fontColor('#838D97')
     .fontSize(12)
     .fontWeight(FontWeight.Medium)
     .margin({ top: 50, bottom: 12 })
   Row({ space: 44 }) {
    this.imageButton($r('app.media.login_method1'))
    this.imageButton($r('app.media.login_method2'))
    this.imageButton($r('app.media.login_method3'))
    }
   }
   .backgroundColor('#F1F3F5')
   .height('100%')
   .width('100%')
   .padding({
   left: 12,
   right: 12,
   bottom: 24
   })
  }
}

3. 主页面:



import prompt from '@ohos.prompt';
import Prompt from '@system.prompt';
import router from '@ohos.router';
/**
 * 主页面
 */
@Entry
@Component
struct MainPage {
 @State currentIndex: number = 0;
 private tabsController: TabsController = new TabsController();
 private swiperController: SwiperController = new SwiperController();
 @State pictures: any[] = [
   { Simg:$r('app.media.fig1')},
   { Simg:$r('app.media.fig2')},
   { Simg:$r('app.media.fig3')},
   { Simg:$r('app.media.fig4')}
  ]
 @State othersItems: any[] = [
   {title:'我的最爱', img:$r('app.media.love')},
   {title:'历史记录', img:$r('app.media.record')},
   {title:'消息', img:$r('app.media.message')},
   {title:'购物车', img:$r('app.media.shopping')},
   {title:'我的目标', img:$r('app.media.target')},
   {title:'圈子', img:$r('app.media.circle')},
   {title:'收藏', img:$r('app.media.favorite')},
   {title:'回收站', img:$r('app.media.recycle')}
  ]
 @State listItems: any[] = [
   {title:'排行榜', img:$r('app.media.top'), text: '厦门站,我们不见不散'},
   {title:'新品首发', img:$r('app.media.new'), text: '厦门站,我们不见不散'},
   {title:'大牌闪购', img:$r('app.media.brand'), text: '大牌闪购'},
   {title:'发现好物', img:$r('app.media.found'), text: '厦门站,我们不见不散'}
  ]
 @State setItems: any[] = [
   {title:'推送通知', img:$r('app.media.news'), textF:'开关'},
   {title:'数据管理', img:$r('app.media.data')},
   {title:'菜单设置', img:$r('app.media.menu')},
   {title:'关于', img:$r('app.media.about')},
   {title:'清除缓存', img:$r('app.media.storage')},
   {title:'隐私协议', img:$r('app.media.privacy')}
  ]


 @Builder TabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) {
  Column() {
   Image(this.currentIndex === index ? selectedImg : normalImg)
     .width(25)
     .height(25)
   Text(title)
     .margin({ top: 4 })
     .fontSize(10)
     .fontColor(this.currentIndex === index ? '#1698CE' : '#6B6B6B')
   }
   .justifyContent(FlexAlign.Center)
   .height(56)
   .width('100%')
   .onClick(() => {
   this.currentIndex = index;
   this.tabsController.changeIndex(this.currentIndex);
   })
  }
 @Builder settingCell(sI) {
  Row() {
   Row({ space: 12 }) {
    Image(sI.img)
      .width(22)
      .height(22)
    Text(sI.title)
      .fontSize(16)
    }


   if (sI.textF === null) {
    Image($r('app.media.right_grey'))
      .width(12)
      .height(24)
    } else {
    Toggle({ type: ToggleType.Switch, isOn: false })
    }
   }
   .justifyContent(FlexAlign.SpaceBetween)
   .width('100%')
   .padding({
   left: 8,
   right: 22
   })
  }


 build() {
  Tabs({
   barPosition: BarPosition.End,
   controller: this.tabsController
   }) {
   TabContent() {
    Scroll() {
     Column({ space: 12 }) {
      Column() {
       Text('首页')
         .fontWeight(FontWeight.Medium)
         .fontSize(24)
         .margin({ top: 12 })
         .padding({ left: 12 })
       }
       .width('100%')
       .alignItems(HorizontalAlign.Start)


      Swiper(this.swiperController) {
       ForEach(this.pictures, (img) => {
        Image(img.Simg).borderRadius(16)
        }, (img: Resource) => JSON.stringify(img.id))
       }
       .margin({ top: 24 })
       .autoPlay(true)


      Grid() {
       ForEach(this.othersItems, (oI) => {
        GridItem() {
         Column() {
          Image(oI.img)
            .width(24)
            .height(24)
          Text(oI.title)
            .fontSize(12)
            .margin({ top: 4 })
          }
         }
        })
       }
       .columnsTemplate('1fr 1fr 1fr 1fr')
       .rowsTemplate('1fr 1fr')
       .columnsGap(8)
       .rowsGap(12)
       .padding({ top: 12, bottom: 12 })
       .height(124)
       .backgroundColor(Color.White)
       .borderRadius(24)


      Text('列表')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .width('100%')
        .margin({ top: 12 })


      Grid() {
       ForEach(this.listItems, (lI) => {
        GridItem() {
         Column() {
          Text(lI.title)
            .fontSize(16)
            .fontWeight(FontWeight.Medium)
          Text(lI.text)
            .margin({ top: 4 })
            .fontSize(12)
            .fontColor('"#99182431"')
          }
          .alignItems(HorizontalAlign.Start)
         }
         .padding({ top: 8, left: 8 })
         .borderRadius(12)
         .align(Alignment.TopStart)
         .backgroundImage(lI.img)
         .backgroundImageSize(ImageSize.Cover)
         .width('100%')
         .height('100%')
        })
       }
       .width('100%')
       .height(260)
       .columnsTemplate('1fr 1fr')
       .rowsTemplate('1fr 1fr')
       .columnsGap(8)
       .rowsGap(12)
       .margin({ bottom: 55 })
      }
     }
     .height('100%')
    }
    .padding({ left: 12, right: 12 })
    .backgroundColor('#F1F3F5')
    .tabBar(this.TabBuilder('首页', 0,
    $r('app.media.home_selected'), $r('app.media.home_normal')))


   TabContent() {
    Scroll() {
     Column({ space: 12 }) {
      Column(){
       Text('我的')
         .fontWeight(FontWeight.Medium)
         .fontSize(24)
         .margin({ top: 12 })
         .padding({ left: 12 })
       }
       .width('100%')
       .alignItems(HorizontalAlign.Start)


      Row() {
       Image($r('app.media.account'))
         .width(48)
         .height(48)
       Column() {
        Text('Mr.Xie')
          .fontSize(20)
        Text('2521885390@qq.com')
          .fontSize(12)
          .margin({ top: 4 })
        }
        .alignItems(HorizontalAlign.Start)
        .margin({ left: 24 })
       }
       .margin({ top: 24 })
       .alignItems(VerticalAlign.Center)
       .width('100%')
       .height(96)
       .backgroundColor(Color.White)
       .padding({ left: 24 })
       .borderRadius(16)


      List() {
       ForEach(this.setItems, (sI) => {
        ListItem() {
         this.settingCell(sI)
         }
         .height(48)
        })
       }
       .backgroundColor(Color.White)
       .width('100%')
       .height('42%')
       .divider({
       strokeWidth: 0.25,
       color: Color.Grey,
       startMargin: 42,
       endMargin: 24
       })
       .borderRadius(16)
       .padding({ top: 4, bottom: 4 })


      Blank()


      Button('退出登录', { type: ButtonType.Capsule })
        .width('90%')
        .height(40)
        .fontSize(16)
        .fontColor('#FA2A2D')
        .fontWeight(FontWeight.Medium)
        .backgroundColor('#E5E8EA')
        .margin({ bottom: 55})
        .onClick(() => {
        AlertDialog.show({
         title:'提示消息',
         message: '确定退出登录吗?',
         offset:{ dx:0, dy: -20},
         alignment: DialogAlignment.Bottom,
         gridCount:4,
         autoCancel:true,
         primaryButton:{
          value:'取消',
          action:() => {
           //取消操作
           }
          },
         secondaryButton:{
          value:'确定',
          action:() => {
           router.back({ url: 'pages/LoginPage'})
           }
          },
         cancel:() => {
          //取消操作
          }
         })
        })
      }
      .height('100%')
     }
    }
    .padding({ left: 12, right: 12 })
    .backgroundColor('#F1F3F5')
    .tabBar(this.TabBuilder('我的', 1,
    $r('app.media.mine_selected'), $r('app.media.mine_normal')))
   }
   .width('100%')
   .backgroundColor(Color.White)
   .barHeight(56)
   .barMode(BarMode.Fixed)
   .onChange((index: number) => {
   this.currentIndex = index;
   })
  }
}

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?但是又不知道从哪里下手,而且学习时频繁踩坑,最终浪费大量时间。所以本人整理了一些比较合适的鸿蒙(HarmonyOS NEXT)学习路径和一些资料的整理供小伙伴学习

点击领取→纯血鸿蒙Next全套最新学习资料希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~~

一、鸿蒙(HarmonyOS NEXT)最新学习路线

​​

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)…等技术知识点。

获取以上完整版高清,请点击→纯血版全套鸿蒙HarmonyOS学习资料

二、HarmonyOS Next 最新全套视频教程

​​

三、《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

​​

四、大厂面试必问面试题

​​

五、鸿蒙南向开发技术

​​

六、鸿蒙APP开发必备

​​
完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结
总的来说,对于大家来说ye是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

                        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值