HarmonyOS NEXT - 项目基础框架的搭建

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

HarmonyOS NEXT - 项目基础框架的搭建

项目基于鸿蒙 OpenHarmony SDK 5.0API12实现

主模块是entry模块,组件和工具类在JhCommon模块 ,通用图片资源放在了AppScope内,三方库在oh-package.json5管理。

项目的入口文件index.ets通过本地存储的用户信息判断是切换到登录页面还是主页面。
达到项目最低限度的要求要把项目结构定好,要可以网络请求,有一些必要组件和工具类,有登录页面和主页面,可以进行路由跳转

前置工作

项目的目录结构

主界面实现

App的主页面是由三部分构成:Navigation+ 主体内容 + tabbar。所以需要创建Navigation组件和tabbar组件,然后通过路由连通单个页面

demo这里是使用BaseTabBar页面放置tabbar和4个子页面,子页面内部再实现Navigation+ 主体内容

BaseTabBar代码实现

js 复制代码
import { OnePage } from './one/OnePage';
import { TwoPage } from './two/TwoPage';
import { ThreePage } from './three/ThreePage';
import { FourPage } from './four/FourPage';

export interface TabType {
  text: string,
  imgPath: string,
}

@Preview
@Entry
@Component
export struct BaseTabBar {
  @State currentIndex: number = 0
  tabsController: TabsController = new TabsController()
  tabList: TabType[] = [{
    imgPath: 'tab/nav_tab_1',
    text: '微信',
  }, {
    text: '通讯录',
    imgPath: 'tab/nav_tab_2',
  }, {
    text: '发现',
    imgPath: 'tab/nav_tab_3',
  }, {
    text: '我的',
    imgPath: 'tab/nav_tab_4',
  }]

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.End }) {
        ForEach(this.tabList, (item: TabType, index: number) => {
          TabContent() {
            if (index == 0) {
              OnePage()
            } else if (index == 1) {
              TwoPage()
            } else if (index == 2) {
              ThreePage()
            } else {
              FourPage()
            }
          }
          .tabBar(this.TabBarBuilder(item.text, index, $rawfile(`${item.imgPath}.png`),
            $rawfile(`${item.imgPath}_on.png`)))
        })
      }
      .scrollable(false) //去掉左右滑动的效果
      .animationDuration(0) //去掉左右滑动的动画
      // .barHeight(156)
      .onChange((index: number) => {
        this.currentIndex = index
        this.tabsController.changeIndex(this.currentIndex)
      })
    }
    .backgroundColor("#eeeeee")
    .width('100%')
    .height('100%')
  }

  @Builder
  TabBarBuilder(title: string, index: number, normalImg: Resource, selectedImg: Resource) {
    Column() {
      Image(this.currentIndex == index ? selectedImg : normalImg)
        .width(24)
        .height(24)

      Text(title)
        .fontSize(14)
        .margin({ top: 4 })
        .fontColor(this.currentIndex == index ? '#45C461' : '#999999')
    }
    .backgroundColor(Color.White)
    .width('100%')
    .height(50)
    .padding({ top: 6, bottom: 6 })
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .id(`tabBar${index}`)
  }
}

子页面实现

这里只举列第一个页面,

js 复制代码
import { router } from '@kit.ArkUI';
import { BaseNavigation } from 'JhCommon';

@Entry
@Component
export struct OnePage {
  @State message: string = 'One'

  build() {
    Column() {
      BaseNavigation({ title: "One", leftItem: {} })
      Button('DemoList').onClick(() => {
        router.pushUrl({ url: 'pages/demos/DemoListPage' })
      })
      RelativeContainer() {
        Text(this.message)
          .id('OnePage')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .alignRules({
            center: { anchor: '__container__', align: VerticalAlign.Center },
            middle: { anchor: '__container__', align: HorizontalAlign.Center }
          })
      }
      .height('100%')
      .width('100%')
    }
  }
}

路由跳转

demo中都是通过@ohos.router实现的跳转,因为Router需要Navigation 包着页面的内容,多一层嵌套

页面路由 (@ohos.router)(不推荐)
Router切换Navigation

js 复制代码
import { router } from '@kit.ArkUI';

router.replaceUrl({ url: 'pages/login/LoginPage' }) 
router.pushUrl({ url: 'pages/demos/DemoListPage' })

登录页面和主页面切换

切换通过在程序的第一个页面内处理,根据登录信息做判断显示登录页还是主页面

js 复制代码
  build() {
    Column() {
      if (this.switchRootPage() == 'BaseTabBar') {
        BaseTabBar()
      } else {
        LoginPage()
      }
    }
    .backgroundColor("#eeeeee")
    .width('100%')
    .height('100%')
  }
  
  switchRootPage(): 'BaseTabBar' | 'LoginPage' {
    const userInfo = JhAESPreferencesUtils.getModel(kUserDefault_UserInfo)
    if (userInfo) {
      console.log('本地取出的 userInfo', JSON.stringify(userInfo))
      return 'BaseTabBar'
    } else {
      return 'LoginPage'
    }
  }

登录实现

js 复制代码
import { router } from '@kit.ArkUI';
import { APIs, HttpUtils, JhAESPreferencesUtils, JhColorUtils, JhProgressHUD, kUserDefault_UserInfo, ResType } from 'JhCommon';
import { JhButton } from 'JhCommon/src/main/ets/JhCommon/components/JhButton';

@Entry
@Component
export struct LoginPage {
  @State @Watch('onChange') name: string = 'jin'
  @State @Watch('onChange') pwd: string = ''
  @State disabled: boolean = true

  // onChangeName(propName: string) {}
  // onChangePwd(propName: string) {}

  onChange() {
    let isClick = true
    if (this.name.length < 3) {
      isClick = false
    }
    if (this.pwd.length < 6) {
      isClick = false
    }
    this.disabled = !isClick
  }

  build() {
    Scroll() {
      Column() {
        Row() {
          Text('注册')
            .fontSize(18)
        }
        .justifyContent(FlexAlign.End)
        .width('100%')

        Row() {
          Text('Logo')
            .fontSize(20)
            .fontColor(Color.White)
        }
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center)
        .width(100)
        .height(100)
        .margin({ top: 80, bottom: 30 })
        .backgroundColor(JhColorUtils.randomColor())
        .borderRadius(50)

        TextInput({
          text: this.name,
          placeholder: '请输入用户名'
        })
          .height(50)
          .margin({ top: 20 })
          .onChange((value) => {
            this.name = value
          })
          .onSubmit((EnterKeyType) => {
            console.info(EnterKeyType + '输入法回车键的类型值')
          })
        TextInput({
          text: this.pwd,
          placeholder: '请输入密码',
        })
          .height(50)
          .type(InputType.Password)
          .margin({ top: 20 })
          .onChange((value) => {
            this.pwd = value
          })
          .onSubmit((EnterKeyType) => {
            console.info(EnterKeyType + '输入法回车键的类型值')
          })
        // Button('登录')
        //   .width('100%')
        //   .margin({ top: 50, bottom: 30 })
        //   .opacity(this.disabled ? 0.6 : 1)
        //   .backgroundColor(KColors.kThemeColor)
        //   .onClick(() => this.clickLogin())
        JhButton({
          text: '登录',
          disabled: this.disabled,
          onPressed: (): void => this.clickLogin()
        })
          .margin({ top: 50, bottom: 30 })
        Row() {
          Text('验证码登录')
            .fontSize(18)
          Text('忘记密码')
            .fontSize(18)
        }
        .justifyContent(FlexAlign.SpaceBetween)
        .width('100%')
      }
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Start)
      .height('100%')
      .width('100%')
      .padding(15)
    }
  }

  clickLogin() {
    const params: object = Object({ 'userName': this.name, 'pwd': this.pwd })
    HttpUtils.post(APIs.login, params, '正在登录...').then((res: ResType) => {
      console.log('登录返回数据:', JSON.stringify(res))
      JhProgressHUD.showSuccess(res.msg)
      JhAESPreferencesUtils.saveModel(kUserDefault_UserInfo, res.data)
      router.replaceUrl({ url: 'pages/BaseTabBar' })
    })
  }
}

退出登录

退出登录把用户信息清掉,并把路由替换掉即可

js 复制代码
import { router } from '@kit.ArkUI';

exitLogin() {
    JhProgressHUD.showLoadingText('正在退出...')
    setTimeout(() => {
      JhAESPreferencesUtils.delete(kUserDefault_UserInfo)
      router.replaceUrl({ url: 'pages/login/LoginPage' })
      JhProgressHUD.hide()
    }, 1000)
  }

至此大框架已经出来了

相关推荐
dawn3 小时前
鸿蒙ArkTS中的获取网络数据
华为·harmonyos
桃花键神3 小时前
鸿蒙5.0时代:原生鸿蒙应用市场引领开发者服务新篇章
华为·harmonyos
鸿蒙自习室3 小时前
鸿蒙多线程开发——并发模型对比(Actor与内存共享)
华为·harmonyos
JavaPub-rodert4 小时前
鸿蒙生态崛起:开发者的机遇与挑战
华为·harmonyos
帅比九日6 小时前
【HarmonyOS Next】封装一个网络请求模块
前端·harmonyos
yilylong7 小时前
鸿蒙(Harmony)实现滑块验证码
华为·harmonyos·鸿蒙
baby_hua7 小时前
HarmonyOS第一课——DevEco Studio的使用
华为·harmonyos
HarmonyOS_SDK8 小时前
融合虚拟与现实,AR Engine为用户提供沉浸式交互体验
harmonyos
- 羊羊不超越 -9 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
长弓三石11 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙