前言
最近基于Harmony OS最新版本开发了一个作品,本文来详细讲解一下,如何我是如何开发这个作品的。以及如何使用OpenHarmony,基于ArkTS,API 9来开发一个属于自己的元服务。
废话不多说,我的作品名称叫做Company Operate
公司运营,是一个根据会计公式来预测公司未来几个月的资产运营情况。
主要分为三部分,
第一部分:填写公司基本情况表单
第二部分:通过公司计算公司未来几个月的运营情况,使用扇形图,标识公司资金组成部分。
第三部分:使用元服务卡片来显示当前月份的公司资金状况。
具体动态效果图如下:
卡片展示效果
使用到的组件有:Gauge
,ForEach
,TextInput
,Radio
,Flex
,Text
,Row
,Column
,Button
。
下面开始讲解开发过程。
开发过程
由于我们要开发的应用是云服务,所有在IDE中创建项目时是按照下图来选择的:
参数解释
- Compile SDK: 3.1.0 (API 9) 目前最新版本,具有很有优秀的特性
- Model: Stage 目前有两种模式,Stage是持续迭代稳定的版本
- Enable Super Visual : disable。是否开始低代码编辑模式
- Language: ArkTS 当使用最新版本的时的SDK时,只能选择ArkTS开发语言
- Compatible SDK: 3.1.0(API 9) 兼容SDK版本
- Devuce type: Phone Tablet 需要支持的设备,手机和平板
创建项目后,IDE会自动将我们的项目依赖包拉取到本地。
注意在IDE里讲相关版本的SDK及套件下载到本地
打开 首页文件, 打开右侧的 预览。
这样就可以开始愉快地编写了。
这里的预览具有热更新的功能,修改页面后会自动更新页面。
表单设计
由于我们不考虑国家化,所以直接使用表单直接使用中文,
像素单位使用虚拟像素,
虚拟像素(virtual pixel)是一台设备针对应用而言所具有的虚拟尺寸(区别于屏幕硬件本身的像素单位)。它提供了一种灵活的方式来适应不同屏幕密度的显示效果。使用虚拟像素,使元素在不同密度的设备上具有一致的视觉体量。
每行40vp,表单项的lable长度为80vp,输入框为220vp。
每行间隔12vp,这项常量组成了我们表单的盒子模型。
定义表单的数据模型
@State formData: any = {name: '111',currentAssets: null,nonCurrentAssets: null,equityAccount: null,currency: null,unitPrice: null,variableCosts: null,quantity: null,fixedCost: null,month: 6
}
数据模型与输入框绑定起来
TextInput().width(220).height(ROW_HEIGHT).onChange((value: string) => {this.formData.name = value
})
与Counter组件绑定
Counter() { Text(this.formData.month.toString()) }.onInc(() => {this.formData.month++}).onDec(() => {this.formData.month--})
首页的效果图
不同于网页的Vue应用开发,数据模型与视图并不是双向绑定关系,开发者需要监听每个输入框,单选按钮的修改事件。修改事件的回调函数里给数据模型重新赋值。
组件公共属性,事件介绍,盒子模型
基于ArkTS的组件,都有通用的一些属性,如:width,height,padding,margin。这些通用通用属性就组成了盒子模型 布局的基础。 组件完整的通用属性可以查阅此链接
除了通用属性,所有的组件也有通用事件 如onClick,onTouch,onKeyEvent,onDragStart。
完整通用事件可以查阅此处
结果页
在首页输入公司的运营数据后,点击开始预测,就会进入结果页。从首页跳转到结果页时,会将所有的表单数据传递过去。
router.pushUrl({url:'pages/res', params: {...this.formData}})
在结果页,在onPageShow生命周期中获取从路由传递过的参数
onPageShow() {const params = router.getParams(); // 获取传递过来的参数对象this.formData = params as any // 赋值给数据模型console.log(JSON.stringify(this.formData), '1111')
}
通过计算传过来的值,我们能够得到一系列公司运营的数据。
并最终使用Text组件将其显示到页面上。
值的注意的是
Gauge组件和ForEach的使用。
Gauge组件的使用
Gauge({ value: 75 }).value(25).width(100).height(100).colors([[0x317AF7, 1], [0x5BA854, 1], [0xE08C3A, 1]])
colors
属性中填写所要显示的元素,元素的颜色值和0-1的比例。
ForEach 的使用
ForEach(arr: any[], itemGenerator: (item: any, index?: number) => void,keyGenerator?: (item: any, index?: number) => string
)
- ForEach必须在容器组件内使用。
- 生成的子组件应当是允许包含在ForEach父容器组件中的子组件。
- 允许子组件生成器函数中包含if/else条件渲染,同时也允许ForEach包含在if/else条件渲染语句中。
- itemGenerator函数的调用顺序不一定和数组中的数据项相同,在开发过程中不要假设
- itemGenerator和keyGenerator函数是否执行及其执行顺序。例如,以下示例可能无法正确运行:
最终效果图
遇到的问题
预览无法出现滚动条,没有下来
预览模式下,当内容超过一屏时,无法自动出现滚动条,不知道这是一个特性,还是bug。还是说需要特殊处理才能出现滚动条,比如使用滚动条组件。
缺少折线图
本来我想使用折线图来表现公司资产运营资产趋势,这也是普遍的做法。但是试了很多方法,都不太理想,使用canvas画折线图。缺少交互,标注,或者坐标轴的分割块显示不准确。总之,目前要想使用折线图,是需要一些技术的。或许也可以尝试从svg下手,尝试。
支持 API 9的设备太少
由于本应用使用的是最新版的API 9,要想使用真机模拟。结果 远程设备只有一个支持API 9,并且状态一直是 unavailable, 不可用状态。汗那,总不能为了开发一个应用,买一个Mate 50把。
总结
总的来讲,在开发云服务应用时,鸿蒙提供的文档还是很全的的,但是由于相对其他的成熟web技术,还是比较新的,所以生态还不算很完善。这也是可以理解的,生态还是要靠全体开发者来支持。