一、什么是鸿蒙

鸿蒙即 HarmonyOS ,是华为公司推出的反对手机、平板、智能穿戴、智慧屏、车机等多种终端设备的分布式操作系统,并且它提供了多语言开发的 API,反对 Java、XML、C/C++、JS、CSS、HML(类 html 的鸿蒙本人的标记语言)等开发语言,而且它提供多种响应式布局计划,反对栅格化布局,能够应用同一套代码部署在手机手表平板等多种不同尺寸屏幕的设施上。

二、开发筹备

2.1 环境装置

开发鸿蒙软件须要用到 HUAWEI DevEco Studio,它提供了模板创立、开发、编译、调试、公布等服务。

1、登录 HarmonysOS 利用开发门户,点击右上角注册按钮,注册开发者帐号。

2、进入 HUAWEI DevEco Studio 产品页,登录华为开发者账号后下载 DevEco Studio 安装包并进行装置。

3、启动 DevEco Studio,依据工具疏导下载 HarmonyOS SDK。

4、下载 HarmonyOS SDK 胜利后会进入欢送页,点击欢送页中的 Configure > Settings 关上设置窗口,点击 Apparance&behavior > System settings > HarmonyOS SDK,选中 JS SDK 进行下载。

至此开发环境装置实现。

2.2 新建我的项目

点击菜单栏中的 File > New > New Project

抉择须要开发的我的项目设施,而后抉择 Empty Featrue Ability(JS) 后,点击 Next,此时会呈现我的项目的信息配置

点击 Finish,一个新的我的项目就被创立进去了。

2.3 我的项目目录

应用 JS SDK 进行开发的话,须要关注的是 entry > src > main > js 文件夹,其中:

  • i18n 目录下寄存的是多语言的 json 文件

    en-US.json 为英文模式展现的内容
    zh-CN.json 为中文模式展现的内容
  • pages 下寄存的是我的项目的多个页面,每个页面都由 hml、js 和 css 组成

    hml 文件定义了页面的布局、页面中用到的组件,以及这些组件的层级关系
    js 文件定义了页面的业务逻辑,比方数据绑定、事件处理等
    css 文件定义了 index 页面的款式
  • app.js 中寄存的是全局的 js 逻辑和 app 的生命周期治理

除此之外,还能够本人创立 common 目录用于寄存公共资源文件,比方:公共款式和专用办法。

2.4 生命周期

生命周期分为利用的生命周期以及页面的生命周期

其中,利用的生命周期次要分为利用创立时调用的 onCreate,以及利用销毁时触发的 onDestroy。

而页面的生命周期分为:

  • onInit:页面数据筹备实现时触发;
  • onReady:页面编译实现时触发;
  • onShow:页面展现时触发;
  • onHide:页面被暗藏时触发;
  • onDestroy:页面被销毁时触发;

因为JS UI只反对利用同时运行并展现一个页面,因而当利用从页面 A 跳转到页面 B 时,首先触发页面 A 的 onHide、onDestroy 函数,而后顺次调用页面 B 的 onInit、onReady、onShow 函数来初始化和显示页面 B。

三、组件

在 hml 文件中,组件分为容器组件、根底组件、媒体组件、画布组件、栅格组件,因为篇幅无限,这里只列举一下组件名称和对应的形容,感兴趣的同学能够点击 组件文档 进行查阅。

3.1 容器组件

组件名形容
div根底容器
list列表容器
list-itemlist 的子组件,用来展现列表具体 item
list-item-grouplist 的子组件,用来展现分组,宽度默认充斥 list 组件
badge新事件标记容器
dialog自定义弹窗容器
panel弹出式可滑动面板容器
popup气泡提醒容器
refresh下拉刷新容器
stack重叠容器,子组件依照程序顺次入栈,后一个子组件笼罩前一个子组件
stepper步骤导航器。当实现一个工作须要多个步骤时,能够应用步骤导航器展现以后停顿
stepper-item步骤导航器子组件,作为步骤导航器某一个步骤的内容展现组件
swiper滑动切换容器
tabstab 页标签切换容器
tab-bartabs 的子组件,用来展现 tab 的标签区
tab-contenttabs 的子组件,用来展现 tab 的内容区

3.2 根底组件

组件名形容
image图片组件,用来渲染展现图片
image-animator图片帧动画播放器
text文本组件,用于展现文本信息
spantext 的子组件,提供文本润饰能力
textarea多行文本输入框
input交互式组件,包含单选框,多选框,按钮和单行文本输入框
button按钮组件,包含胶囊按钮、圆形按钮、文本按钮、弧形按钮、下载按钮
chart图表组件,用于出现线形图、柱状图、量规图界面
divider提供分隔器组件,分隔不同内容块/内容元素。可用于列表或界面布局
label为 input、button、textarea 组件定义相应的标注,点击该标注时会触发绑定组件的点击成果
marquee跑马灯组件,用于展现一段单行滚动的文字
menu菜单组件,作为临时性弹出窗口,用于展现用户可执行的操作
select下拉抉择组件,可让用户在多个选项之间抉择
option可作为 menu 或 select 组件的子组件,用来展现具体我的项目
picker滑动选择器组件,类型反对一般选择器,日期选择器,工夫选择器,工夫日期选择器,多列文本选择器
picker-view嵌入页面的滑动选择器
piece一种块状的入口组件,可蕴含图片和文本,罕用于展现收件人
progress进度条组件,用于显示内容加载或操作解决进度
qrcode二维码组件,用于生成并显示二维码
rating评分条组件
search搜寻框组件,用于提供用户搜寻内容的输出区域
slider滑动条组件,用来疾速调节设置值,如音量、亮度等
switch开关组件,用于开启或敞开某个性能
toolbar工具栏组件,放在界面底部,用于展现针对以后界面的操作选项
toolbar-itemtoolbar 子组件,用于展现工具栏上的一个操作选项
toggle状态按钮组件,用于从一组选项中进行抉择

3.3 媒体组件

媒体组件临时只有 video 组件一个,除了智能穿戴设施不反对外,手机、平板、智慧屏设施均反对该组件,它为设施提供了视频播放性能。

3.4 画布组件

画布组件展现只有 canvas 组件一个,手机、平板、智慧屏、智能穿戴设施均反对该组件,它为设施提供了自定义绘制图形的能力。

3.5 栅格组件

组件名形容
grid-container栅格布局容器根节点
grid-rowgrid-row 是栅格布局容器 grid-container 的子容器组件,应用 flex 横向布局,排列每个 grid-col 容器,justify-content 与 align-items 默认为 flex-start,反对折行显示
grid-colgrid-row 的子容器组件

栅格零碎有 Margins, Gutters, Columns 三个属性:

  • Margins:用于管制元素间隔屏幕最边缘的间隔
  • Gutters:用来管制元素和元素之间的间隔关系
  • Columns:用来辅助布局的次要定位工具,不同的屏幕尺寸匹配不同的 Columns 数量来辅助布局定位,它会依据理论设施的宽度和 Columns 数量主动计算每一个 Columns 的宽度

不同的设施依据程度宽度 px,显示不同数量的栅格数:

xs : 0px < 程度分辨率 < 320px:2 Columns 栅格;

sm : 320px <= 程度分辨率 < 600px:4 Columns 栅格;

md : 600px <= 程度分辨率 < 840px:8 Columns 栅格;

lg : 840px <= 程度分辨率:12 Columns 栅格。

四、HML语法

HML(HarmonyOS Markup Language)是一套类 HTML 的标记语言,通过组件,事件构建出页面的内容。页面具备事件绑定、数据绑定、列表渲染、条件渲染和逻辑管制等能力。

4.1 事件绑定

hml 中事件绑定默认返回一个事件对象参数,能够通过该参数获取事件信息,同时也能够传递额定参数。

<!-- xxx.hml --><div>  <!-- 失常格局 -->  <div onclick="clickfunc"></div>  <!-- 缩写 -->  <div @click="clickfunc('hello')"></div>  <!-- 应用事件冒泡模式绑定事件回调函数 -->  <div on:touchstart.bubble="touchstartfunc"></div>  <!-- 应用事件捕捉模式绑定事件回调函数 -->  <div on:touchstart.capture="touchstartfunc"></div>  <!-- on:{event}等价于on:{event}.bubble -->  <div on:touchstart="touchstartfunc"></div>  <!-- 绑定事件回调函数,但阻止事件向上传递 -->  <div grab:touchstart.bubble="touchstartfunc"></div>  <!-- 绑定事件回调函数,但阻止事件向下传递 -->  <div grab:touchstart.capture="touchstartfunc"></div>  <!-- grab:{event}等价于grab:{event}.bubble -->  <div grab:touchstart="touchstartfunc"></div></div>
// xxx.jsexport default {  data: {    text: '',  },  clickfunc: function(str, e) {    console.log(e);    this.text = str;  },  touchstartfunc: function(e) {    console.log(e);  }}

4.2 数据绑定

数据绑定的模式分两种:数据初始化,数据更新

hml 只反对数据层到视图层的单向数据绑定。
视图层想扭转数据层,只能通过绑定事件的形式实现。

4.2.1 数据初始化

hml 中的数据都来自于对应 js 中的 data 对象,因而在初始化页面时,在 data 对象中写入数据,hml 中就能够通过 {{}} 的模式绑定数据。

// xxx.jsexport default {  data: {    text: 'HELLO WORLD'  }}
<!-- xxx.hml --><div>{{text}}</div>

4.2.2 数据更新

通过为页面元素绑定事件,能够调用办法更新数据,从而触发视图更新数据

// xxx.jsexport default {  data: {    text: 'HELLO WORLD'  },  changeText: function() {    this.$set('text', '你好,世界');  }}
<!-- xxx.hml --><div @click='changeText'>{{text}}</div>

4.3 列表渲染

hml 中须要进行列表渲染的话只需在组件上增加 for 属性并绑定须要渲染的数据,同时可自定义变量和索引的名称:

// xxx.jsexport default {  data: {    array: [      {id: 1, name: '老周', age: 28},       {id: 2, name: '老李', age: 29},    ],  },  changeText: function(val, index) {    if (val === "老李"){      this.array.splice(index, 1, {id:2, name: '老王', age: 30});    } else {      this.array.splice(index, 1, {id:3, name: '老郑', age: 31});    }  },}
<!-- xxx.hml --><div class="array-container">  <!-- div列表渲染 -->  <!-- 默认$item代表数组中的元素, $idx代表数组中的元素索引 -->  <div for="{{array}}" tid="id" onclick="changeText($item.name, $idx)">    <text>{{$idx}}.{{$item.name}}</text>  </div>  <!-- 自定义元素变量名称 -->  <div for="{{value in array}}" tid="id" onclick="changeText(value.name, $idx)">        <text>{{$idx}}.{{value.name}}</text>  </div>  <!-- 自定义元素变量、索引名称 -->  <div for="{{(index, value) in array}}" tid="id" onclick="changeText(value.name, index)">        <text>{{index}}.{{value.name}}</text>  </div></div>
数组中的每个元素必须存在 tid 指定的数据属性,且必须具备唯一性。
针对数组内的数据批改,请应用 splice 办法失效数据绑定变更

4.4 条件渲染

hml 中实现条件渲染有两种形式,别离是为组件增加 if/elif/else 或 show 属性,它们的区别在于 if/elif/else 属性不符合条件判断则不会在 vdom 中构建,而 show 属性为 false 时尽管不会渲染,然而会在 vdom 中构建,只是设置了 display 款式为 none。

因而出于性能因素思考,显示暗藏状态须要频繁切换举荐应用 show,显示状态扭转次数较少则应用 if/elif/else。

// xxx.jsexport default {  data: {    show: false,    display: true,    visible: false  },  toggle: function() {    this.visible = !this.visible;  }}
<!-- xxx.hml --><div class="container">  <text if="{{show}}"> 你好,世界 </text>  <text elif="{{display}}"> hi </text>  <text else> Hello World </text>    <button class="btn" type="capsule" value="toggle" onclick="toggle"></button>  <text show="{{visible}}" > Hello World! </text></div>
当应用 if/elif/else 写法时,节点必须是兄弟节点,否则编译无奈通过
禁止在同一个元素上同时设置 for 和 if 属性

4.5 逻辑管制块

hml 中提供了 <block> 管制块,它不会被当作实在的节点编译,然而只反对 for 和 if 属性。

4.6 自定义组件

HML 能够通过 element 标签援用模板文件,通过它能够实现自定义组件。

<!-- template.hml --><div class="item">   <text>Name: {{name}}</text>  <text>Age: {{age}}</text></div>
<!-- index.hml --><element name='man' src='../../common/template.hml'></element><div>  <man name="老朱" age="28"></man></div>

其中 element 标签的 name 属性则为自定义组件的名称,src 属性为自定义组件绝对该文件的门路,能够为自定义组件标签增加属性向其传递数据,自定义组件内也可应用 $emit 办法向父组件传递参数。

五、JS语法

鸿蒙中的 js 文件反对 ES6 语法。

5.1 援用

鸿蒙中能够应用 import 办法引入功能模块或 js 代码:

import router from '@system.router'import utils from '../../common/utils.js'

5.2 获取app对象

在页面中能够应用 this.$app.$def 获取在 app.js 中裸露的对象。

// app.jsexport default {  onCreate() {    console.info('App onCreate');  },  onDestroy() {    console.info('App onDestroy');  },  globalData: {    appData: 'appData',    appVersion: '2.0',  },  changeAppVer () {    this.globalData.appVersion = '3.0';  }};
// index.jsexport default {  data: {    appData: 'localData',    appVersion:'1.0',  },  onInit() {    this.appData = this.$app.$def.globalData.appData;    this.appVersion = this.$app.$def.globalData.appVersion;  },  pageMethod() {    this.$app.$def.changeAppVer();  }}

5.3 页面对象

属性类型形容
dataObject/Function页面的数据模型
$refsObject持有注册过 ref 属性的 DOM 元素或子组件实例的对象
propsArray/Objectprops 用于接管父组件传递过去的参数
computedObject计算属性,用于在读取或设置进行事后解决,计算属性的后果会被缓存
privateObject页面的数据模型,private 下的数据属性只能由以后页面批改
publicObject页面的数据模型,public 下的数据属性的行为与 data 保持一致

5.4 办法

5.4.1 数据办法

属性类型参数形容
$setFunctionkey: string, value: any增加新的数据属性或者批改已有数据属性。用法:this.$set('key',value)。
$deleteFunctionkey: string删除数据属性。用法:this.$delete('key')。
export default {  data: {    appInfo: {      OS: 'HarmonyOS',      Version: '2.0',    },  },  changeAppInfo() {    this.$set('appInfo.Version', '3.0');    console.log(this.appInfo);    this.$delete('appInfo');    console.log(this.appInfo);  }}

5.4.2 事件办法

鸿蒙中能够应用 $watch 办法察看 data 中的属性变动,如果属性值扭转,则会触发绑定的事件。

export default {   props: ['title'],  onInit() {    this.$watch('title', 'onPropChange');  },  onPropChange(newV, oldV) {    console.info('title属性由'+ oldV +'变动为' + newV);  },}

5.5 路由

{  "pages": [    "pages/index/index",    "pages/detail/index"  ]}

鸿蒙 app 中页面的路由信息保留在 src > main > config.json 文件中的 pages 内,引入 @system.router 后,调用其 push 办法传入须要跳转页面的 uri,即可实现跳转,也可应用其 back 办法回到首页。

import router from '@system.router';export default {  launch() {    router.push ({      uri: 'pages/detail/index',    });  },  goBack() {    router.back();  }}

六、CSS语法

CSS 是形容 HML 页面构造的款式语言,所有组件均存在零碎默认款式,也可在页面 CSS 款式文件中对组件、页面自定义不同的款式。

6.1 尺寸单位

鸿蒙中尺寸单位有两种,px(逻辑像素) 以及百分比。

{  "window": {    "designWidth": 720,    "autoDesignWidth": false  }}

逻辑像素的配置在 src > main > config.json 文件中的 window 内,designWidth 为屏幕的逻辑宽度,默认为720px,理论显示时会将页面布局缩放至屏幕理论宽度,如100px在理论宽度为1440物理像素的屏幕上,理论渲染为200物理像素。

当 autoDesignWidth 设置为 true 时,逻辑像素 px 将依照屏幕密度进行缩放,如 100px 在屏幕密度为3的设施上,理论渲染为300物理像素。

而百分比单位示意该组件占父组件尺寸的百分比,如组件的 width 设置为50%,代表其宽度为父组件的50%。

6.2 款式导入

CSS 款式文件反对 @import 语句,导入 CSS 文件。

@import '../../common/style.css';

七、总结

应用鸿蒙的 JS SDK 开发 App,整体的我的项目构造、生命周期以及开发流程很像微信的小程序,而 hml 和 JS 的语法又很像 Vue,整个流程走下来,感觉对 web 开发者而言还是很敌对的,置信有 Web 前端开发根底的小伙伴们都能够疾速的上手。

因为篇幅无限,文中还有很多没有提到的鸿蒙赋予开发者的硬件调用能力,心愿鸿蒙能够越做越好,让越来越多的开发者和用户退出到鸿蒙的大生态中来。

八、参考

  • HarmonyOS Developer

    欢送关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。