HarmonyOS NEXT - 项目底子框架的搭建

打印 上一主题 下一主题

主题 1030|帖子 1030|积分 3090

demo 所在: https://github.com/iotjin/JhHarmonyDemo
代码不定时更新,请前往github查看最新代码
  
  


   项目基于鸿蒙 OpenHarmony SDK 5.0 ,API12实现
主模块是entry模块,组件和工具类在JhCommon模块 ,通用图片资源放在了AppScope内,三方库在oh-package.json5管理。
项目标入口文件index.ets通过本地存储的用户信息判断是切换到登录页面还是主页面。
    达到项目最低限度的要求要把项目结构定好,要可以网络哀求,有一些必要组件和工具类,有登录页面和主页面,可以进行路由跳转
  前置工作

   

  • 在demo中这些组件和工具类都通过module实现了,具体可以参考HarmonyOS NEXT - 通过 module 模块化引用公共组件和utils
  • HarmonyOS NEXT - 三方库axios的使用和封装
  • HarmonyOS NEXT - Navigation组件封装BaseNavigation
  • HarmonyOS NEXT - 数据长期化存储(key,value进行AES加密处理)
  项目标目录结构


主界面实现

   App的主页面是由三部门构成:Navigation+ 主体内容 + tabbar。所以必要创建Navigation组件和tabbar组件,然后通过路由连通单个页面
demo这里是使用BaseTabBar页面放置tabbar和4个子页面,子页面内部再实现Navigation+ 主体内容

  


BaseTabBar代码实现

  1. import { OnePage } from './one/OnePage';
  2. import { TwoPage } from './two/TwoPage';
  3. import { ThreePage } from './three/ThreePage';
  4. import { FourPage } from './four/FourPage';
  5. export interface TabType {
  6.   text: string,
  7.   imgPath: string,
  8. }
  9. @Preview
  10. @Entry
  11. @Component
  12. export struct BaseTabBar {
  13.   @State currentIndex: number = 0
  14.   tabsController: TabsController = new TabsController()
  15.   tabList: TabType[] = [{
  16.     imgPath: 'tab/nav_tab_1',
  17.     text: '微信',
  18.   }, {
  19.     text: '通讯录',
  20.     imgPath: 'tab/nav_tab_2',
  21.   }, {
  22.     text: '发现',
  23.     imgPath: 'tab/nav_tab_3',
  24.   }, {
  25.     text: '我的',
  26.     imgPath: 'tab/nav_tab_4',
  27.   }]
  28.   build() {
  29.     Column() {
  30.       Tabs({ barPosition: BarPosition.End }) {
  31.         ForEach(this.tabList, (item: TabType, index: number) => {
  32.           TabContent() {
  33.             if (index == 0) {
  34.               OnePage()
  35.             } else if (index == 1) {
  36.               TwoPage()
  37.             } else if (index == 2) {
  38.               ThreePage()
  39.             } else {
  40.               FourPage()
  41.             }
  42.           }
  43.           .tabBar(this.TabBarBuilder(item.text, index, $rawfile(`${item.imgPath}.png`),
  44.             $rawfile(`${item.imgPath}_on.png`)))
  45.         })
  46.       }
  47.       .scrollable(false) //去掉左右滑动的效果
  48.       .animationDuration(0) //去掉左右滑动的动画
  49.       // .barHeight(156)
  50.       .onChange((index: number) => {
  51.         this.currentIndex = index
  52.         this.tabsController.changeIndex(this.currentIndex)
  53.       })
  54.     }
  55.     .backgroundColor("#eeeeee")
  56.     .width('100%')
  57.     .height('100%')
  58.   }
  59.   @Builder
  60.   TabBarBuilder(title: string, index: number, normalImg: Resource, selectedImg: Resource) {
  61.     Column() {
  62.       Image(this.currentIndex == index ? selectedImg : normalImg)
  63.         .width(24)
  64.         .height(24)
  65.       Text(title)
  66.         .fontSize(14)
  67.         .margin({ top: 4 })
  68.         .fontColor(this.currentIndex == index ? '#45C461' : '#999999')
  69.     }
  70.     .backgroundColor(Color.White)
  71.     .width('100%')
  72.     .height(50)
  73.     .padding({ top: 6, bottom: 6 })
  74.     .justifyContent(FlexAlign.Center)
  75.     .alignItems(HorizontalAlign.Center)
  76.     .id(`tabBar${index}`)
  77.   }
  78. }
复制代码
子页面实现

   这里只举列第一个页面,
  1. import { router } from '@kit.ArkUI';
  2. import { BaseNavigation } from 'JhCommon';
  3. @Entry
  4. @Component
  5. export struct OnePage {
  6.   @State message: string = 'One'
  7.   build() {
  8.     Column() {
  9.       BaseNavigation({ title: "One", leftItem: {} })
  10.       Button('DemoList').onClick(() => {
  11.         router.pushUrl({ url: 'pages/demos/DemoListPage' })
  12.       })
  13.       RelativeContainer() {
  14.         Text(this.message)
  15.           .id('OnePage')
  16.           .fontSize(50)
  17.           .fontWeight(FontWeight.Bold)
  18.           .alignRules({
  19.             center: { anchor: '__container__', align: VerticalAlign.Center },
  20.             middle: { anchor: '__container__', align: HorizontalAlign.Center }
  21.           })
  22.       }
  23.       .height('100%')
  24.       .width('100%')
  25.     }
  26.   }
  27. }
复制代码
路由跳转

demo中都是通过@ohos.router实现的跳转,因为Router必要Navigation 包着页面的内容,多一层嵌套
页面路由 (@ohos.router)(不推荐)
Router切换Navigation
  1. import { router } from '@kit.ArkUI';
  2. router.replaceUrl({ url: 'pages/login/LoginPage' })
  3. router.pushUrl({ url: 'pages/demos/DemoListPage' })
复制代码
登录页面和主页面切换

   切换通过在程序的第一个页面内处理,根据登录信息做判断显示登录页还是主页面
  1.   build() {
  2.     Column() {
  3.       if (this.switchRootPage() == 'BaseTabBar') {
  4.         BaseTabBar()
  5.       } else {
  6.         LoginPage()
  7.       }
  8.     }
  9.     .backgroundColor("#eeeeee")
  10.     .width('100%')
  11.     .height('100%')
  12.   }
  13.   
  14.   switchRootPage(): 'BaseTabBar' | 'LoginPage' {
  15.     const userInfo = JhAESPreferencesUtils.getModel(kUserDefault_UserInfo)
  16.     if (userInfo) {
  17.       console.log('本地取出的 userInfo', JSON.stringify(userInfo))
  18.       return 'BaseTabBar'
  19.     } else {
  20.       return 'LoginPage'
  21.     }
  22.   }
复制代码
登录实现

  1. import { router } from '@kit.ArkUI';
  2. import { APIs, HttpUtils, JhAESPreferencesUtils, JhColorUtils, JhProgressHUD, kUserDefault_UserInfo, ResType } from 'JhCommon';
  3. import { JhButton } from 'JhCommon/src/main/ets/JhCommon/components/JhButton';
  4. @Entry
  5. @Component
  6. export struct LoginPage {
  7.   @State @Watch('onChange') name: string = 'jin'
  8.   @State @Watch('onChange') pwd: string = ''
  9.   @State disabled: boolean = true
  10.   // onChangeName(propName: string) {}
  11.   // onChangePwd(propName: string) {}
  12.   onChange() {
  13.     let isClick = true
  14.     if (this.name.length < 3) {
  15.       isClick = false
  16.     }
  17.     if (this.pwd.length < 6) {
  18.       isClick = false
  19.     }
  20.     this.disabled = !isClick
  21.   }
  22.   build() {
  23.     Scroll() {
  24.       Column() {
  25.         Row() {
  26.           Text('注册')
  27.             .fontSize(18)
  28.         }
  29.         .justifyContent(FlexAlign.End)
  30.         .width('100%')
  31.         Row() {
  32.           Text('Logo')
  33.             .fontSize(20)
  34.             .fontColor(Color.White)
  35.         }
  36.         .justifyContent(FlexAlign.Center)
  37.         .alignItems(VerticalAlign.Center)
  38.         .width(100)
  39.         .height(100)
  40.         .margin({ top: 80, bottom: 30 })
  41.         .backgroundColor(JhColorUtils.randomColor())
  42.         .borderRadius(50)
  43.         TextInput({
  44.           text: this.name,
  45.           placeholder: '请输入用户名'
  46.         })
  47.           .height(50)
  48.           .margin({ top: 20 })
  49.           .onChange((value) => {
  50.             this.name = value
  51.           })
  52.           .onSubmit((EnterKeyType) => {
  53.             console.info(EnterKeyType + '输入法回车键的类型值')
  54.           })
  55.         TextInput({
  56.           text: this.pwd,
  57.           placeholder: '请输入密码',
  58.         })
  59.           .height(50)
  60.           .type(InputType.Password)
  61.           .margin({ top: 20 })
  62.           .onChange((value) => {
  63.             this.pwd = value
  64.           })
  65.           .onSubmit((EnterKeyType) => {
  66.             console.info(EnterKeyType + '输入法回车键的类型值')
  67.           })
  68.         // Button('登录')
  69.         //   .width('100%')
  70.         //   .margin({ top: 50, bottom: 30 })
  71.         //   .opacity(this.disabled ? 0.6 : 1)
  72.         //   .backgroundColor(KColors.kThemeColor)
  73.         //   .onClick(() => this.clickLogin())
  74.         JhButton({
  75.           text: '登录',
  76.           disabled: this.disabled,
  77.           onPressed: (): void => this.clickLogin()
  78.         })
  79.           .margin({ top: 50, bottom: 30 })
  80.         Row() {
  81.           Text('验证码登录')
  82.             .fontSize(18)
  83.           Text('忘记密码')
  84.             .fontSize(18)
  85.         }
  86.         .justifyContent(FlexAlign.SpaceBetween)
  87.         .width('100%')
  88.       }
  89.       .alignItems(HorizontalAlign.Center)
  90.       .justifyContent(FlexAlign.Start)
  91.       .height('100%')
  92.       .width('100%')
  93.       .padding(15)
  94.     }
  95.   }
  96.   clickLogin() {
  97.     const params: object = Object({ 'userName': this.name, 'pwd': this.pwd })
  98.     HttpUtils.post(APIs.login, params, '正在登录...').then((res: ResType) => {
  99.       console.log('登录返回数据:', JSON.stringify(res))
  100.       JhProgressHUD.showSuccess(res.msg)
  101.       JhAESPreferencesUtils.saveModel(kUserDefault_UserInfo, res.data)
  102.       router.replaceUrl({ url: 'pages/BaseTabBar' })
  103.     })
  104.   }
  105. }
复制代码
退出登录

   退出登录把用户信息清掉,并把路由更换掉即可
  1. import { router } from '@kit.ArkUI';
  2. exitLogin() {
  3.     JhProgressHUD.showLoadingText('正在退出...')
  4.     setTimeout(() => {
  5.       JhAESPreferencesUtils.delete(kUserDefault_UserInfo)
  6.       router.replaceUrl({ url: 'pages/login/LoginPage' })
  7.       JhProgressHUD.hide()
  8.     }, 1000)
  9.   }
复制代码
至此大框架已经出来了

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

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

立聪堂德州十三局店

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