我的鸿蒙开发之旅 - 万物归一

1,712 阅读6分钟

“万物互联时代,没有人会是一座孤岛”。

⭕ 必先利其器的器

HUAWEI DevEco Studio:跟小程序开发工具差不多。有基本的代码开发、智能高亮、编译、构建、调试、测试等等功能。

  • 高效智能代码编辑
  • 低代码可视化开发
  • 多端双向实时预览
  • 多端设备模拟仿真

⭕ 应用/服务开发流程

1、开发准备:安装DevEco Studio、配置开发环境

2、开发应用:创建应用工程、编写应用代码、使用预览器查看界面布局效果

3、运行、调试和测试应用:申请调测证书、运行应用、调试应用、隐私/漏洞/性能等测试

4、发布应用:申请发布证书、发布至华为应用市场

⭕ 快速入门

创建一个Phone设备项目:

1、打开DevEco studio,点击Create Project

image.png

2、保持项目配置默认值就好,点击完成

image.png

🔴 项目目录结构

一个鸿蒙APP(Application Package),由多个HAP包(Harmony app)和pack.info组成的。

那么一个HAP里面又是啥呢:

一个项目有基于Stage或者FA模型,不同模型里面的目录结构不同。

  • HAP
    • Entry (应用入口)
    • Feature (根据你要什么需求或者什么设备进行安装)

image.png

🔴 基本写法

在entry/src/main/etc/pages下面创建两个文件,分别是Index.etsSecond.ets.

image.png

Index.ets

image.png

Second.ets

image.png

在resources/base/profile找到main_pages.json, 内容如下:

image.png

效果如下:

Kapture 2024-07-08 at 16.08.45.gif

对,说的是简单的hello world. 问一句:你的第一次“hello world”给了谁?

image.png

🔴 运行

这里说一下鸿蒙的模拟器运行预览吧。就是写完那些UI和事件,实时界面预览。

image.png

⭕ 进阶

🔴 ArkTS

开发语言用ArkTs, UI用方舟ArkUI

开发语言: ArkTS

  • 基本语法:写UI(包括css那些),写事件。
  • 状态管理:数据状态管理(不同组件层级间传递数据-父子组件、爷孙组件、全局范围、跨设备)。
  • 渲染控制:条件渲染、循环渲染、数据懒加载。

页面结构,如下图所示:

image.png

🔴 页面入口配置

入口文件:

image.png

文件EntryAbility.ts:

image.png

第一个进来的页面Index.ets

image.png

文件main_pages.json:

image.png

🔴 页面基本组成

一个组件页面基本组成如下:

image.png

🔴 生命周期

image.png

  • 页面的生命周期:onPageShow、onPageHide、onBackPress

  • 组件的生命周期: aboutToAppear、aboutToDisappear

  • 页面: 可以由一个或者多个自定义组件组成。组件用@Entry修饰的,代表是根节点,一个页面只能有一个@Entry。可以调用组件的生命周期,也可以调用页面的生命周期

  • 自定义组件: 用@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期

举个例子:

image.png

image.png

image.png

🔴 资源分类和访问

开发一个app,需要应用到资源。

资源目录如下:

image.png

这些什么中文啊、英文啊,是基于用户的手机或者说手表那些鸿蒙生态的设备是什么语言,我们中国人可能经常用中文,所以我们先看zh_CN这一块和base这一块。

  • json资源: 一些json文件 —— 着重讲zh_CN,其他的同理可得。
  • 媒体资源:一些图、视频等(.jpg .png .gif .svg .webp .mp4 等)。—— 就是UI妹妹给我们的那些图放的base这一块。

zh_CN/element目录下就放一些json数据的,比如color.jsonfloat.jsonstring.jsonplural.json(复数.json)

举个例子,定义一个color.json放中文目录的element下面: color.json

image.png

上面说完我们自定义的一些资源,我们也可以用系统已有的资源。系统资源用$r('sys.type.resource_id')这样子用。

  • r或者r 或者 rawfile 都可以,我们一般用缩写,少点字母
  • sys 代表 系统资源
  • type 代表 资源类型
  • resource_id 代表 资源id

image.png

🔴 权限申请和管控

向用户申请权限:摄像头、麦克风、通讯录、联网、打电话等。其中有些是向系统索要权限(叫 system_grant),一些是向用户索要权限的(叫 user_grant)。

image.png

要权限, 在 entry/src/ohosTest/module.json5这个文件里面定义requestPermissions, 用大数组包对象的结构去一个个写我们要的权限,如下:

image.png

比如下面这个申请麦克风🎤的例子:

image.png

🔴 http请求接口

通过HTTP发起一个数据请求。

封装请求接口,放到下图中的utils下的request.ts: image.png

/utils/request.ts

import { http } from '@kit.NetworkKit'
import resultVO from '../common/resultVO'
import { CommonConstants } from '../constants/CommonConstants'
import { promptAction } from '@kit.ArkUI'

export const request = async <T>(params): Promise<resultVO<T>> => {
  const baseURL: string = CommonConstants.BASE_URL
  let httpRequest = http.createHttp()

  let requestUrl = baseURL + params.url

  console.info('params', JSON.stringify(params))

  let options = {
    method: params.method ?? http.RequestMethod.GET,
    header: {
      'Content-Type': 'application/json'
    },
    extraData: params,
    expectDataType: http.HttpDataType.OBJECT
  }

  return new Promise(async (resolve, reject) => {
    httpRequest.request(
      requestUrl,
      options,
      (err, data) => {
        console.log('data', JSON.stringify(data))
        if (!err) {
          const res = data.result as resultVO<T>

          if (res.code == CommonConstants.CODE_SUCCESS) {
            resolve(res)
          } else {
            promptAction.showToast({ message: res.msg })
            return
          }

        } else {
          promptAction.showToast({ message: CommonConstants.REQUEST_ERROR})
          console.error('error:' + JSON.stringify(err))
          reject(err)
        }

        httpRequest.destroy()
      }
    )
  })
}

common/requestParams.ts:

image.png

common/resultVO.ts:

image.png

constants/CommonConstants.ts

image.png

写完这些,开一下权限,module.json5文件修改如下:

image.png

页面中调接口:

image.png

前端打印:

image.png

后端接收:

image.png

🔴 组件

components/MyHeader.ets:

@Component
export default struct MyHeader {
  build() {
    Column(){
      Column(){
        Text('我是头')
          .width('100%')
          .fontSize(30)
          .fontColor('#e4393c')
          .textAlign(TextAlign.Center)
      }
    }
  }
}

引用:

import MyHeader from '../components/MyHeader'

// ...
build() {
    MyHeader()
}
// ...

🔴 🔴 组件传参

第一种办法: @Prop: 改子父不变

1、只支持 string|number|boolean|enum类型,不能是数组或者any
2、单向的,子组件不允许改父组件的值
3、父组件用({xxx: xxx})传过去,子组件用@Prop收值且用this.xxx取值。

父组件:

image.png

子组件:

image.png

第二种办法:@Link:

父组件跟第一种办法一样传,子组件把@Prop改成@Link就行。改子父也变

image.png

image.png

第三种办法: 直接传,子组件初始化值:

跟第一种办法一样,只是子组件需要初始化值:

image.png

🔴 像素单位

像素单位解释
px屏幕物理像素单位。
vp屏幕密度相关像素。数值不带单位,默认是vp。在实际宽度为1140物理像素的屏幕上,1vp约等于3px。
fp字体像素,与vp类似适用屏幕密度变化,随系统字体大小设置变化。
lpx视窗逻辑像素单位,lpx档位为实际屏幕宽度与逻辑宽度(通过designWith配置)的比值。
  • px: 在不同手机或设备上的大小不同,差别较大,适配性太差,不建议使用。
  • vp: 使用虚拟像素vp,使元素在不同密度的设备上具有一致的视觉体量。
  • fp: 主要用于字体大小,
  • lpx: 手机、pc、pad、手表等不同端存在视窗可以拉长缩小的情况,适配多端场景。

image.png

一般用vp,或者用vp2px(数字)+'px'这种写法。

🔴 列表循环

image.png

image.png

🔴 打包发布下载

build - 新建秘钥、填秘钥 - 申请证书 - 选应用 - 选证书(去调试或发布)

image.png

华为应用商店下载:HUAWEI AppGallery

相应学习链接

OpenHarmony三方库

image.png

注:基于API 12 Beta1,开发者可以自行选择兼容JS的类Web开发范式写法。

“一生万物,万物归一”。

image.png

☎️ 希望对大家有所帮助,本文有些地方可能考虑不够周到,有些纰漏,就当抛砖引玉,还望您海涵,如有错误,望不吝赐教,欢迎评论区留言互相学习。感谢阅读,祝您开发有乐趣。