第一步开发环境搭建
操作系统-建议
官方要求 | windows | macOS |
---|---|---|
操作系统 | Windows10 64 位 | macOS 10.14/10.15/11.2.2 |
内存 | 8GB 及以上 | 8GB 及以上 |
硬盘 | 100GB 及以上 | 100GB 及以上 |
分辨率 | 1280*800 像素及以上 | 1280*800 像素及以上 |
node 环境搭建
HUAWEI DevEco Studio 下是开发EMUI应用的集成开发环境(IDE)
https://developer.harmonyos.com/cn/develop/deveco-studio
1.1选择自己对应版本下载(mac 版本)
解压文件 选择安装
1.2打开应用程序- 创建启动脚本不勾选
点击Start using Deveco Studio
1.3之后点击 同意按钮进入 npm 配置界面-会自动帮我们配置到华为云的npm 包地址
1.4 继续点击右下角的 Start using DevEco Studio 会出现sdk 安装界面
1.5 点击next 会出现当前版本的sdk 信息
1.6 勾选 接受sdk协议 点击next
1.7 开始安装 - 安装完成后点击 Finish
1.8 文件介绍
1.9 点击创建一个新的项目-选择支持的设备-这边选择Empty Ability js-的卡片上面显示
支持设备有 手机端-ipad 电视和穿戴设备 ,可以根据业务需要选择对应的模版
2.0
2.1
hml结尾的HML模板文件,这个文件用来描述卡片页面的模板布局结构。
.css结尾的CSS样式文件,这个文件用于描述页面样式。
.json结尾的JSON文件,这个文件用于配置卡片中使用的变量action事件。
config.js 介绍
它的数据结构是JSON格式的 可以看到主要的分为三个部分:app、deviceConfig、module,你可以理解为三个对象
① app 表示应用的全局配置信息。同一个应用的不同HAP包的“app”配置必须保持一致。(简单说就是你所有模块里面的config.json中的app对象都要一模一样)
② deviceConfig 表示应用在具体设备上的配置信息。
③ module 表示HAP包的配置信息。该标签下的配置只对当前HAP包生效 (安卓有apk )
{
"app": {
"bundleName": "com.example.zuozhetest", // 表示应用的包名,用于标识应用的唯一性。采用反域名形式的字符串表示(例如,com.llw.helloworld)。建议第一级为域名后缀“com”,第二级为厂商/个人名,第三级为应用名,也可以采用多级。支持的字符串长度为7~127字节。不可省缺。
"vendor": "example", // 表示对应用开发厂商的描述。字符串长度不超过255字节。可以省缺,省缺值为空
"version": { //这是一个对象,表示应用的版本信息。它里面有两个参数,code和name
"code": 1000000, // code 表示应用的版本号,仅用于HarmonyOS管理该应用,对用户不可见。取值为大于零的整数。
"name": "1.0.0" // name表示应用的版本号,用于向用户呈现。取值可以自定义。两个参数都不可省缺。
}
},
"deviceConfig": {}, //具体设备上的应用配置信息
"module": {
"package": "com.example.zuozhetest", //表示HAP的包结构名称,在应用内应保证唯一性。采用反向域名格式(建议与HAP的工程目录保持一致)。字符串长度不超过127字节。该标签仅适用于智慧屏、智能穿戴、车机。不可省缺。
"name": ".MyApplication", //表示HAP的类名。采用反向域名方式表示,前缀需要与同级的package标签指定的包名一致,也可采用“.”开头的命名方式。字符串长度不超过255字节。该标签仅适用于智慧屏、智能穿戴、车机。不可省缺。
"mainAbility": "com.example.zuozhetest.MainAbility",
"deviceType": [ //表示允许Ability运行的设备类型。系统预定义的设备类型包括 就是我们创建项目的时候勾选生成的
"phone",
"tv",
"wearable"
],
"distro": { // 表示HAP发布的具体描述。这是一个对象,该标签仅适用于智慧屏、智能穿戴、车机。不可省缺
"deliveryWithInstall": true, //表示当前HAP是否支持随应用安装。true:支持随应用安装。false:不支持随应用安装。不可省缺。
"moduleName": "entry", //表示当前HAP的名称。不可省缺
"moduleType": "entry", //表示当前HAP的类型,包括两种类型:entry和feature。不可省缺
"installationFree": false
},
"abilities": [ //表示当前模块内的所有Ability。采用对象数组格式,其中每个元素表示一个Ability对象。可缺省,缺省值为空
{
"skills": [
{
"entities": [ //表示能够接收的Intent的Ability的类别(如视频、桌面应用等),可以包含一个或多个entity。取值通常为系统预定义的类别,可缺省,缺省值为空。
"entity.system.home"
],
"actions": [ //表示能够接收的Intent的action值,可以包含一个或多个action。取值通常为系统预定义的action值,可缺省,缺省值为空
"action.system.home"
]
}
],
"name": "com.example.zuozhetest.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
}
],
"js": [
{
"pages": [ // 配置 页面路径 有开发过小程序的经验的话一看就明白了
"pages/index/index"
],
"name": "default",
"window": { //全局的默认窗口表现
"designWidth": 720,
"autoDesignWidth": true
}
}
]
}
}
各个文件夹的作用:
- pages目录用于存放卡片模板页面。
- common目录用于存放公共资源文件,比如:图片资源。
- resources目录用于存放资源配置文件,比如:多分辨率加载配置文件。
- i18n目录用于配置不同语言场景资源内容,比如应用文本词条,图片路径等资源
- i18n和resources是开发保留文件夹,不可重命名。
文件访问规则
应用资源可通过绝对路径或相对路径的方式进行访问,本开发框架中绝对路径以"/"开头,相对路径以"./"或"../"。具体访问规则如下:
引用代码文件,需使用相对路径,比如:../common/style.css。
引用资源文件,推荐使用绝对路径。比如:/common/xxx.png。
公共代码文件和资源文件推荐放在common下,通过规则1和规则2进行访问。
CSS样式文件中通过url()函数创建数据类型,如:url(/common/xxx.png)。
当代码文件A需要引用代码文件B时:
如果代码文件A和文件B位于同一目录,则代码文件B引用资源文件时可使用相对路径,也可使用绝对路径。
如果代码文件A和文件B位于不同目录,则代码文件B引用资源文件时必须使用绝对路径。因为Webpack打包时,代码文件B的目录会发生变化。
在json文件中定义的数据为资源文件路径时,需使用绝对路径。
预览器
预览器预览会输出编译后文件,支持热更新,也支持多设备同时预览。
进入到 src/main/js/default/pages/index 页面,打开 view -> Tool Windows -> Previewer 进行预览
使用模拟器进行模拟的时候,编辑器工具会自动打包输出 hap 文件,模拟器直接加载运行该文件,模拟器不支持热更新,
登陆过华为开发者账号实名认证过的的 可以点击菜单栏 tools 云真机 进行测试观看
vue 和小程序 及OpenHarmony JS 的对比
一、生命周期
二 、数据绑定
vue vue动态绑定一个变量的值为元素的某个属性的时候,会在变量前面加上冒号
微信小程序 绑定某个变量的值为元素属性时,会用两个大括号括起来,如果不加括号,为被认为是字符串。
OpenHarmony JS {{ 变量名 }}
三、列表渲染
vue <li v-for="item in items" :key="xxx">{{ item.message }}</li>
微信小程序 <text wx:for="{{items}}">{{item}}</text>
OpenHarmony JS
<!-- div列表渲染 -->
<!-- 默认$item代表数组中的元素, $idx代表数组中的元素索引 -->
<div for="{{array}}" tid="id">
<text>{{$item.name}}</text>
</div>
<!-- 自定义元素变量名称 -->
<div for="{{value in array}}" tid="id">
<text>{{value.name}}</text>
</div>
<!-- 自定义元素变量、索引名称 -->
<div for="{{(index, value) in array}}" tid="id">
<text>{{value.name}}</text>
</div>
显示与隐藏元素
Vue 使用 v-if 和 v-show控制元素的显示和隐藏
微信小程序 使用 wx:if和 hidden控制元素的显示与隐藏
OpenHarmony JS 条件渲染分为2种:if/elif/else和show 当使用if/elif/else写法时,节点必须是兄弟节点,否则编译无法通过。实例如下
<!-- xxx.hml -->
<div>
<text if="{{show}}"> Hello-TV </text>
<text elif="{{display}}"> Hello-Wearable </text>
<text else> Hello-World </text>
</div>
事件处理
Vue 使用 v-on:event绑定事件,或者使用 @event绑定事件
微信小程序 bindtap(bind+event),或者 catchtap(catch+event)绑定事件
OpenHarmony JS @click="handleClick"
数据双向绑定
vue 在vue中,只需要再表单元素上加上 v-model,然后再绑定 data中对应的一个值,当表单元素内容发生变化时, data中对应的值也会相应改变,这是vue非常nice的一点
微信小程序 当表单内容发生变化时,会触发表单元素上绑定的方法,然后在该方法中,通过 this.setData({key:value})来将表单上的值赋值给 data中的对应值。
OpenHarmony JS 在鸿蒙 JS 系统上没有 双向数据绑定,需要我们自行实现双向数据绑定
取值
vue vue中,通过 this.xxx取值
微信小程序 通过 this.data.xx取值
OpenHarmony JS 通过 this.xxx取值
绑定事件传参
vue 只需要在触发事件的方法中,把需要传递的数据作为形参传入就可以<button @click="say('免费看书100年')"></button>
微信小程序
// 在 小程序中,不能直接在绑定事件的方法中传入参数,需要将参数作为属性值,绑定到元素上的 data-属性上,然后在方法中,通过 // e.currentTarget.dataset.*的方式获取,从而完成参数的传递。
<view class='tr' bindtap='say' data-id="{{item.id}}"></view>
say(e) {
let id = e.currentTarget.dataset.id;
}
OpenHarmony JS 只需要在触发事件的方法中,把需要传递的数据作为形参传入就可以<button @click="say('免费看书100年')"></button>
路由跳转 传参
1. 不带参数
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
2. query传参
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
// html 取参 $route.query.id
// script 取参 this.$route.query.id
3. params传参
this.$router.push({name:'home',params: {id:'1'}}) // 只能用 name
// 页面跳转,URL地址是将要跳转的页面相对当前页面的路径
wx.navigateTo({
url: '../../help/help?data=' + {num:'33'},
})
help页面
onLoad: function (options) {
// 打印页面传递来的参数
console.log('options',options)
// 打印页面传递来的参数类型
console.log(typeof(options.data))
},
import router from '@system.router'; //导入模块
// 跳转页面
router.push ({
uri: 'pages/details/index',
params:{
id:id
}
});
要获取前一个页面的参数,有三种方式:
如果参数需要在页面中引用,可以直接在hml页面中使用{{参数名}}
的形式进行引用,例如{{id}}。
如果需要对参数进行操作,在detail.js中直接使用this.id参数名的形式。
可以在detail.js的data域中定义一个同名参数进行接收,注意这种方式接收的参数将覆盖已有的参数data:{id:””}。
单位
vue 支持“HTML中的常见长度单位 包括 px rem 等等 单位
微信小程序 rpx(responsive pixel): 是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应
OpenHarmony JS S-FA没有对相对单位的支持
- 逻辑像素px(文档中以表示):
- 默认屏幕具有的逻辑宽度为720px(配置见配置文件中的window小节),实际显示时会将页面布局缩放至屏幕实际宽度,如100px在实际宽度为1440物理像素的屏幕上,实际渲染为200物理像素(从720px向1440物理像素,所有尺寸放大2倍)。
- 额外配置autoDesignWidth为true时(配置见配置文件中的window小节),逻辑像素px将按照屏幕密度进行缩放,如100px在屏幕密度为3的设备上,实际渲染为300物理像素。应用需要适配多种设备时,建议采用此方法。
- 百分比(文档中以表示):表示该组件占父组件尺寸的百分比,如组件的width设置为50%,代表其宽度为父组件的50%
计算属性
vue 和 OpenHarmony JS 都可以 通过 computed 里面定义 参考vue官网计算属性
唯独微信小程序 不支持计算属性 但是提供另一种办法 通过 WXS
WXS(WeiXin Script)是小程序的一套脚本语言 需要注意的点 里面不能使用const let 声明变量
<wxs module="qimao">
var msg= "免费看书100年"
module.exports.message = msg;
</wxs>
<view>{{qimao.message}}</view>
监听器
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
如果需要观察组件中属性变化,可以通过$watch方法增加属性变化回调。使用方法如下:
export default {
props: ['title'],
onInit() {
this.$watch('title', 'onPropertyChange');
},
onPropertyChange(newV, oldV) {
console.info('title 属性变化 ' + newV + ' ' + oldV);
},
}
自定义组件通信 官网详细介绍:
vue官网组件介绍:https://cn.vuejs.org/v2/guide/components-registration.html
微信小程序 组件通信 介绍 :https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html
OpenHarmony JS : https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-custom-props-0000000000611785。基本和vue 通信一致
css 语法参考
vue 保持和 HTML css 的写法一致
<style scoped>
@media (min-width: 250px) {
.list-container:hover {
background: orange;
}
}
</style>
这个可选 scoped attribute 会自动添加一个唯一的 attribute (比如 data-v-21e5b78) 为组件内 CSS 指定作用域,编译的时候 .list-container:hover 会被编译成类似 .list-container[data-v-21e5b78]:hover。
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro |
选择所有拥有 class="intro" 的组件 |
#id | #firstname |
选择拥有 id="firstname" 的组件 |
element | view |
选择所有 view 组件 |
element, element | view, checkbox |
选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after |
在 view 组件后边插入内容 |
::before | view::before |
在 view 组件前边插入内容 |
为了模块化管理和代码复用,CSS样式文件支持 @import 语句,导入 CSS 文件 内部样式,支持使用style、class属性来控制组件的样式
选择器只支持:内联样式,id,class
样式预编译 目前支持less、sass和scss
本地数据储存
vue
可以使用 localStorage cookie
以及使用 vuex 具体介绍看官方
需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify
序列化的对象。
wx.setStorage({
key:"key",
data:"value"
})
import storage from '@system.storage'; // 导入模块
storage.get({
key: 'storage_key',
success: function(data) {
console.log('call storage.get success: ' + data);
},
fail: function(data, code) {
console.log('call storage.get fail, code: ' + code + ', data: ' + data);
},
complete: function() {
console.log('call complete');
},
});
OpenHarmony JS 组件介绍
- 组件(Component)是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。
- 鸿蒙 JS API 提供了完善的组件介绍官方文档: 组件 - 官方介绍
- 根据组件的功能,可以分为以下四大类:
组件类型 | 主要组件 |
---|---|
基础组件 | text、image、progress、rating、span、marquee、image-animator 、divider 、search、menu、chart |
容器组件 | div、list、list-item、stack、swiper、tabs、tab-bar、tab-content、list-item-group、refresh、dialog |
媒体组件 | video |
画布组件 | canvas |
OpenHarmony JS 网络访问
支持设备
API | 手机 | 平板 | 智慧屏 | 智能穿戴 |
---|---|---|---|---|
fetch.fetch | 支持 | 支持 | 支持 | 支持 |
// 导入模块
import fetch from '@system.fetch';
etch.fetch(OBJECT)
通过网络获取数据。
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
url | string | 是 | 资源地址。 |
data | string | Object | 否 | 请求的参数,可选类型是字符串或者json对象。 |
header | Object | 否 | 设置请求的header。 |
method | string | 否 | 请求方法默认为GET,可选值为:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE。 |
responseType | string | 否 | 默认会根据服务器返回header中的Content-Type确定返回类型,支持文本和json格式。详见success返回值。 |
success | Function | 否 | 接口调用成功的回调函数。 |
fail | Function | 否 | 接口调用失败的回调函数。 |
complete | Function | 否 | 接口调用结束的回调函数。 |
data | Content-Type | 说明 |
---|---|---|
string | 不设置 | Content-Type默认为 text/plain,data值作为请求的body。 |
string | 任意 Type | data值作为请求的body。 |
Object | 不设置 | Content-Type默认为application/x-www-form-urlencoded,data按照资源地址规则进行encode拼接作为请求的body。 |
Object | application/x-www-form-urlencoded | data按照资源地址规则进行encode拼接作为请求的body。 |
success返回值:
参数名 | 类型 | 说明 |
---|---|---|
code | number | 表示服务器的状态code。 |
data | string | Object | 返回数据类型由responseType确定,详见responseType与success中data关系。 |
headers | Object | 表示服务器response的所有header。 |
responseType | data | 说明 |
---|---|---|
无 | string | 服务器返回的header中的type如果是text/*或application/json、application/javascript、application/xml,值为文本内容。 |
text | string | 返回文本内容。 |
json | Object | 返回json格式的对象。 |
使用例子
import fetch from '@system.fetch'
export default {
data: {
responseData: 'NA',
url: "test_url",
},
fetch: function () {
var that = this;
fetch.fetch({
url: that.url,
success: function(response) {
console.info("fetch success");
that.responseData = JSON.stringify(response);
},
fail: function() {
console.info("fetch fail");
}
});
}
}
开发常见问题 鸿蒙官网已经总结 ✈️
OpenHarmony JS demo 演示
目前 OpenHarmony JS FA 2.0 学习资料相对较少 以上仅供参考