|
shev711
| 未知
从0开始在鸿蒙OS中制作一个APP
他来了他来了,他带着质疑走来了。无论怎么说,鸿蒙OS 2.0的发布对于程序员群体来说也应当是值得记住的时刻。毕竟有可能未来开发程序的时候,产品经理一定会问:兼容鸿蒙OS吗?
目前鸿蒙OS给大多数开发者的印象就是一个PPT系统。今天和同事们聊了聊鸿蒙OS发布,大多数人仍然持质疑的态度,似乎想要认真回答题主的问题,从0开始使用鸿蒙制作一个APP似乎是一个不错的想法。
我希望这个应用开发完成后,我和你都有了自己的答案。
利益相关:一名普通的前端工程师。没有安卓开发经验,开发过程中智障行为请谅解。 零、现阶段遇到的BUG汇总
我会将开发过程中遇到的bug汇总到这里,希望能帮到Harmony框架的开发人员
- IDE -- Project列表文件无法选中:可以选中文件夹,通过键盘操作移动到文件打开,但是有时候鼠标点击无法选中文件。比较频繁
- IDE -- 初次运行IDE没有提示安装模拟器。
- 在Chrome浏览器环境下,DevEco调转到网页无法停留在授权页面,导致无法触发登录回调(可能也是首次登录才会这样)。
- 模拟器中存在focus是 input type是checkbox时样式会丢失(有可能模拟器中focus会清空样式)
- 模拟器下,input组件type为time或者date时,呼出键盘为数字键盘
- input组件,有value属性时,输入文字后调用onchange事件会导致组件崩溃
一、环境搭建
华为为HarmonyOS设计了专门的开发IDE:DevEco Studio,目前只支持Windows10,目前而言对于常年使用MacOS的前端不太友好,不过这不是问题,bootcamp启动(mac的双系统)!
DevEco Studio,目前只支持Windows10
HUAWEI DevEco Studio(以下简称DevEco Studio)是面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的HarmonyOS应用开发服务。 根据华为的描述,这个IDE支持多语言的开发,构建,发布并支持多模拟器。同时需要注册华为开发者账号。
macOS即将上线,期待
IDE压缩包616M
DevEco支持多种语言,使用JS开发的话需要安装Nodejs。看起来HarmonyOS是支持使用HTML+CSS+JS方式开发WEB应用的。同时我们注意到DevEco支持的标签语言是HML,应该是华为对其进行了一些定制化的设置。
安装没有什么太多的配置,下载好软件后只要电脑可以联网,DevEco会下载相关依赖。(比如Java以及相关的工具链,看起来环境变量也自动配置了,很适合我。(可以好评)
安装完成后就会进入到软件主界面了,到目前为止还没有遇到坑。
二、开发一个小的Demo
我们回归到题主的问题,这个系统的前景怎么样。这个问题说实话现在回答为时尚早,毕竟一个系统有没有前途,很多时候不是这个系统决定的。
但是有一点可以肯定,一个好的系统,其生态圈是相对容易建立的。简单来说,如果我这种没有接触过HarmonyOS的人也能快速开发一个App,那他至少已经在答题卡上涂过答案了。
让我们先写一个各大前端框架介绍特性时最常用的例子:TODO List
2.1 创建 App
点击Create HarmonyOS Project:目前看来HarmonyOS支持TV,Wearable,Lite Wearable三种设备,有点少,考虑到Huawei是中国公司,应该不存在翻译问题,所以可以说目前来看HarmonyOS不支持PC与Mobile产品。
我们选择一个空的JS模板。(注意使用JS模板你需要安装Nodejs,如果是初学者的话很简单的,在官网下载以后就下一步下一步下一步。。。然后欢迎你成为前端工程师
起一个喜欢的名字
到目前为止还比较顺畅,初学者也可以开启一个应用。
2.2 启动应用
这里注意到新建项目后 IDE开始使用gradle下载相关的以来。其他的回答已经有人确认这次HarmonyOS不是安卓套壳了,所以我就重复证明了,开始写代码。
JS UI
看了下官方示例,使用JAVA UI采用XML编写页面。作为前端切图仔,怎么可能用那么后端的方法呢,看了看文档,华为提供了另外一种编写方式:JS UI。
根据华为的描述,JS UI是采用类HTML与CSS来进行页面开发。同时他也支持了JS FA的开发模式,可以将JS与JAVA混合开发。(我是不知道混合开发有什么用,或许是后端程序员的坚持吧。狗头)
初次运行需要安装模拟器,按照DevEco的文档说明安装模拟器是有提醒的,但是实际测试我这里没有提示。程序还没有跑起来,我就发现三个bug:后续我会把使用过程中的bug放到开头,希望能帮到华为的同行们。
- IDE初次运行没有弹出安装模拟器的提示,会影响使用者体验
- refresh模拟器列表反复要求登录华为开发者账号,但是我已经登录了。登录没有触发IDE内部的登录成功回调(使用chrome会出现这个问题)
- Project列表文件无法选中:可以选中文件夹,通过键盘操作移动到文件打开,但是有时候鼠标点击无法选中文件。频率比较频繁
开启模拟器后,将代码稍微做一下改动:
类似于vue的模板语法
从UI框架来看 HarmoneyOS应用与传统应用开发差异不大,数据双向绑定的语法来看有些类似Vue。
2.3 新建一个有状态的List
今天看了许多评论,大家的发言都很有道理。 我们先来明确一下这个小demo的需求:
- 一个有状态的List,能够勾选与取消想要完成的任务
- 能够新增新的任务
我们先来测试一下HarmonyOS自带组件。List,华为在文档里提供了各组件的api,地址如下:
HarmonyOS 文档中心按照文档的例子,我们将src → js → index中的页面代码简单修改一下
//index.hml
<div class=&#34;container&#34;>
<text class=&#34;title&#34;>
{{title}}
</text>
<list class=&#34;todo-wraper&#34;>
<list-item for=&#34;{{todolist}}&#34; class=&#34;todo-item&#34;>
<text class=&#34;todo-title&#34;>{{$item.title}}</text>
<text class=&#34;todo-title&#34;>{{$item.date}}</text>
</list-item>
</list>
</div>
//index.js
export default {
data: {
title: &#34;今日事,今日毕&#34;,
todolist: [
{title: &#39;吃饭&#39;,date: &#39;10:00:00&#39;,},
{title: &#39;睡觉&#39;,date: &#39;12:00:00&#39;,},
{title: &#39;打豆豆&#39;,date: &#39;20:00:00&#39;,}
],
},
onInit() {
}
}
/* index.css */
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction:column;
left: 0px;
top: 0px;
width: 80%;
height: 100%;
}
.title {
font-size: 40px;
}
.todo-wraper{
padding:20px;
}
.todo-item{
line-hight:100px;
flex:1;
}
.todo-title{
font-wight:bold;
margin-right:20px;
}
整个JS UI构建页面的方式与小程序是基本相同的,基本上是模板指令的一套。
谢谢@nobody 的评论
这个是快应用,类似微信小程序一样的东西,这个框架是由小米、中兴、华为、金立、联想、魅族、努比亚、OPPO、VIVO等九家联合制定标准的。 看起来HarmonyOS内核上原生程序UI构建应该都会是这种模式。但我认为HarmonyOS与快应用有本质的区别,HarmonyOS并不只是提供了UI层MVVM的框架。
Ability是应用所具备的能力的抽象,一个应用可以包含一个或多个Ability。Ability分为两种类型:FA(Feature Ability)和PA(Particle Ability)。FA/PA是应用的基本组成单元,能够实现特定的业务功能。FA有UI界面,而PA无UI界面。 我们现在编写的程序UI是就是一个FA,而PA包括Service与Model,分别做数据处理和逻辑处理的工作。(这不就是全栈吗 (#`O′))
2.3 测试数据绑定与MVVM特性
废话不多说,我们继续为应用增加一些交互能力。
反馈一个bug:模拟器中存在focus是 input type是checkbox时样式会丢失(有可能模拟器中focus会清空样式) 吐槽一下:没有热加载和ui调试工具,开发效率太低了。。
接下来我们为列表加入checkbox组件,添加全选和新增按钮,增加一个新增任务的Dialog。
这几个交互实现的逻辑与小程序是非常类似的,但是数据赋值不需要 setData方法,直接赋值即可
this.XXX = &#39;XXX&#39;;
发现一个有意思的地方,模拟器默认输入法是 百度
HarmonyOS的组件并没有像Vue一样有 v-model的概念,修改input需要编写onchange事件。
简单修改一下,一个简单的TodoList功能就完成了
提一个bug:
模拟器下,input组件type为time或者date时,呼出键盘为数字键盘
input组件,有value属性时,输入文字后调用onchange事件会导致组件崩溃 2.4 简单Demo的使用体验总结:
实际体验下来,对于前端JS UI来讲开发体验可以说是很差,
- 没有热加载与页面调试工具,每次修改需要重新编译,大约10s
- remote模拟器流畅度太差,使用体验介于不可用和用的想哭之间
- 代码编写阶段没有明显的报错提示,很多时候打错一个字都要找很久
- 代码的自动补全还不完善
- 前端组件部分官网缺乏例子,很多API使用的细节还需要不断测试
- 有些官方的例子也没有正常运行。(譬如这个例子)
虽然说这个开发体验让我有点崩溃,但是最近看文档逐渐发现HarmonyOS的内容其实很多,JSUI只是HarmonyOS架构最表层的东西。如果管中窥豹的讲,抛开华为当下的政治处境不说,我想就以目前HarmonyOS的成熟程度还远远没有达到商用的水平,现在这套开发体系和体验还不足以支撑起庞大的应用生态。
就目前而言,题主的问题我仍然没有得出一个答案。
但是HarmonyOS是一个开始,不可否认当前国家形式将它打造成了一面旗帜,我希望这面旗帜不会倒下,我也希望这样的旗帜越来越多。为了深入尝试HarmonyOS的能力,我会不定期进行后续测试。如果你有什么想要了解的请在评论区提出。
后续测试计划:
- 尽量多的调用系统API能力,可能调用 HarmonyOS 硬件的时间,声音,视频,网络。。
- 测试css性能,能否支持一些CSS3的动画特性
- 调用一些HarmonyOS的分布式任务能力
附:当前的代码
<! -- index.hml -->
<div class=&#34;container&#34;>
<text class=&#34;title&#34;>
{{title}}
</text>
<list class=&#34;todo-wraper&#34; focusable=&#34;false&#34;>
<list-item for=&#34;{{todoList}}&#34; class=&#34;todo-item&#34;>
<div>
<input type=&#34;checkbox&#34; checked=&#34;{{$item.checked}}&#34;></input>
<text class=&#34;todo-title&#34;>{{$item.title}}</text>
<text class=&#34;todo-title&#34;>{{$item.date}}</text>
</div>
</list-item>
</list>
<div class=&#34;todo-operation&#34; focusable=&#34;false&#34;>
<button type=&#34;capsule&#34; onclick=&#34;onSelectAll&#34;>全选</button>
<button type=&#34;capsule&#34; onclick=&#34;onAddTask&#34;>新增</button>
</div>
<dialog id=&#34;addDialog&#34;>
<div class=&#34;container addDialog&#34;>
<div class=&#34;add-title&#34;>
<label>新增任务</label>
</div>
<div>
<text class=&#34;add-label&#34;>名称:</text>
<input type=&#34;text&#34; onchange=&#34;onTextInput()&#34;></input>
</div>
<div>
<text class=&#34;add-label&#34;>时间:</text>
<input type=&#34;text&#34; onchange=&#34;onTimeInput()&#34;></input>
</div>
<div class=&#34;todo-operation&#34; focusable=&#34;false&#34;>
<button type=&#34;capsule&#34; onclick=&#34;onSubmit&#34;>确定</button>
</div>
</div>
</dialog>
</div>
// index.js
export default {
data: {
title: &#34;今日事,今日毕&#34;,
subTitle:&#39;今日事,今日毕&#39;,
todoList: [
{title: &#39;吃饭&#39;,date: &#39;10:00:00&#39;,checked:false},
{title: &#39;睡觉&#39;,date: &#39;12:00:00&#39;,checked:true},
{title: &#39;打豆豆&#39;,date: &#39;20:00:00&#39;,checked:false}
],
addText:&#39;shuijiao&#39;,
addTime:&#39;&#39;
},
onInit() {
},
onSelectAll(){
//如果存在checked为false,则全选表示均为true,如果已经全选,则为反选
if(this.todoList.filter(x=> {return x.checked == false}).length>0){
this.todoList.forEach(x => {
x.checked = true
});
}else{
this.todoList.forEach(x => {
x.checked = !x.checked
});
}
},
onAddTask(){
this.$element(&#39;addDialog&#39;).show();
},
onSubmit(){
this.todoList.push({
title: this.addText,date: this.addTime,checked:false
})
this.addText = &#39;&#39;;
this.addTime = &#39;&#39;;
this.$element(&#39;addDialog&#39;).close();
},
onTextInput(e) {
this.addText = e.text;
},
onTimeInput(e){
this.addTime = e.text;
}
}
/* index.css */
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction:column;
left: 0px;
top: 0px;
width: 80%;
height: 100%;
}
.title {
font-size: 40px;
}
.todo-wraper{
padding:20px;
}
.todo-item{
line-hight:100px;
}
.todo-title{
font-wight:bold;
margin-right:20px;
margin-left:20px;
}
.todo-check{
margin-right:20px;
}
.todo-operation{
flex:2;
width:100%;
height:100px;
display:flex;
flex-direction:row;
align-items: center;
}
.addDialog{
width: 90%;
width:500px;
}
.add-title{
padding:10px;
}
.add-label{
font-size:16px;
width:30%;
} |
|