【最新鸿蒙应用开发】——类Web开发范式2——前端语法
兼容JS的类Web开发范式
JS FA应用的JS模块(entry/src/main/js/module)的典型开发目录结构如下:
1. 项目基本结构
1.1. 目录结构

1.2. 项目文件分类如下:
-
.hml结尾的HML模板文件,这个文件用来描述当前页面的文件布局结构。
-
.css结尾的CSS样式文件,这个文件用于描述页面样式。
-
.js结尾的JS文件,这个文件用于处理页面和用户的交互。
1.3. 目录模块划分:
-
app.js文件用于全局JavaScript逻辑和应用生命周期管理。
-
pages目录用于存放所有组件页面。
-
common目录用于存放公共资源文件,比如:媒体资源和JS文件。
-
i18n目录用于配置不同语言场景资源内容,比如应用文本词条,图片路径等资源。
说明
-
i18n是开发保留文件夹,不可重命名。
-
在使用DevEco Studio进行应用开发时,目录结构中的可选文件夹需要开发者根据实际情况自行创建。
1.4. 文件访问规则
应用资源可通过绝对路径或相对路径的方式进行访问,本开发框架中绝对路径以"/"开头,相对路径以"./"或"../"。具体访问规则如下:
-
引用代码文件,需使用相对路径,比如:../common/utils.js。
-
引用资源文件,推荐使用绝对路径。比如:/common/xxx.png。
-
公共代码文件和资源文件推荐放在common下,通过以上两条规则进行访问。
-
CSS样式文件中通过url()函数创建<url>数据类型,如:url(/common/xxx.png)。
说明
当代码文件A需要引用代码文件B时:
-
如果代码文件A和文件B位于同一目录,则代码文件B引用资源文件时可使用相对路径,也可使用绝对路径。
-
如果代码文件A和文件B位于不同目录,则代码文件B引用资源文件时必须使用绝对路径。因为Webpack打包时,代码文件B的目录会发生变化。
2. 语法
2.1. HML语法
HML是一套类HTML的标记语言,通过组件,事件构建出页面的内容。页面具备数据绑定、事件绑定、列表渲染、条件渲染等高级能力。
2.1.1. 页面结构
<!-- xxx.hml -->
<div class="item-container"><text class="item-title">Image Show</text><div class="item-content"><image src="/common/xxx.png" class="image"></image></div>
</div>
2.1.2. 数据绑定
<!-- xxx.hml -->
<div onclick="changeText"><text> {{content[1]}} </text>
</div>
// xxx.js
export default {data: {content: ['Hello World!', 'Welcome to my world!']},changeText: function() {this.content.splice(1, 1, this.content[0]);}
}
说明
-
针对数组内的数据修改,请使用splice方法生效数据绑定变更。
-
hml中的js表达式不支持ES6语法。
2.1.3. 事件绑定
事件绑定的回调函数接收一个事件对象参数,可以通过访问该事件对象获取事件信息。
<!-- xxx.hml -->
<div><!-- 通过'@'绑定事件 --><div @click="clickfunc"></div><!-- 通过'on'绑定事件 --><div onclick="clickfunc"></div><!-- 通过'on'绑定事件,不推荐使用5+ --><div onclick="clickfunc"></div><!-- 使用事件冒泡模式绑定事件回调函数。5+ --><div on:click.bubble="clickfunc"></div><!-- on:{event}等价于on:{event}.bubble。5+ --><div on:click="clickfunc"></div><!-- 绑定事件回调函数,但阻止事件向上传递。5+ --><div grab:click.bubble="clickfunc"></div><!-- grab:{event}等价于grab:{event}.bubble。5+ --><div grab:click="clickfunc"></div>
</div>
// xxx.js
export default {data: {obj: '',},clickfunc: function(e) {this.obj = 'Hello World';console.log(e);},
}
说明
事件冒泡机制从API Version 5开始支持。升级SDK后,运行存量JS应用,采用旧写法(onclick)的事件绑定还是按事件不冒泡进行处理。但如果使用新版本SDK重新打包JS应用,将旧写法按事件冒泡进行处理。为了避免业务逻辑错误,建议将旧写法(如onclick)改成新写法(grab:click)。
示例:
<!-- xxx.hml -->
<div class="container"><text class="title">{{count}}</text><div class="box"><input type="button" class="btn" value="increase" onclick="increase" /><input type="button" class="btn" value="decrease" @click="decrease" /><!-- 传递额外参数 --><input type="button" class="btn" value="double" @click="multiply(2)" /><input type="button" class="btn" value="decuple" @click="multiply(10)" /><input type="button" class="btn" value="square" @click="multiply(count)" /></div>
</div>
// xxx.js
export default {data: {count: 0},increase() {this.count++;},decrease() {this.count--;},multiply(multiplier) {this.count = multiplier * this.count;}
};
/* xxx.css */
.container {display: flex;flex-direction: column;justify-content: center;align-items: center;left: 0px;top: 0px;width: 454px;height: 454px;
}
.title {font-size: 30px;text-align: center;width: 200px;height: 100px;
}
.box {width: 454px;height: 200px;justify-content: center;align-items: center;flex-wrap: wrap;
}
.btn {width: 200px;border-radius: 0;margin-top: 10px;margin-left: 10px;
}
2.1.4. 列表渲染
<!-- xxx.hml -->
<div class="array-container"><!-- div列表渲染 --><!-- 默认$item代表数组中的元素, $idx代表数组中的元素索引 --><div class="item-container" for="{{array}}" tid="id" onclick="changeText"><text>{{$idx}}.{{$item.name}}</text></div><!-- 自定义元素变量名称 --><div class="item-container" for="{{value in array}}" tid="id" onclick="changeText"><text>{{$idx}}.{{value.name}}</text></div><!-- 自定义元素变量、索引名称 --><div class="item-container" for="{{(index, value) in array}}" tid="id" onclick="changeText"><text>{{index}}.{{value.name}}</text></div>
</div>
// xxx.js
export default {data: {array: [{id: 1, name: 'jack', age: 18}, {id: 2, name: 'tony', age: 18},],},changeText: function() {if (this.array[1].name === "tony"){this.array.splice(1, 1, {id:2, name: 'Isabella', age: 18});} else {this.array.splice(2, 1, {id:3, name: 'Bary', age: 18});}},
}
.array-container {width: 100%;height: 100%;justify-content: center;align-items: center;flex-direction: column;
}
.item-container {margin-top: 10px;width: 200px;height: 50px;flex-direction: column;
}
tid属性主要用来加速for循环的重渲染,旨在列表中的数据有变更时,提高重新渲染的效率。tid属性是用来指定数组中每个元素的唯一标识,如果未指定,数组中每个元素的索引为该元素的唯一id。例如上述tid="id"表示数组中的每个元素的id属性为该元素的唯一标识。for循环支持的写法如下:
-
for="array":其中array为数组对象,array的元素变量默认为$item。
-
for="v in array":其中v为自定义的元素变量,元素索引默认为$idx。
-
for="(i, v) in array":其中元素索引为i,元素变量为v,遍历数组对象array。
说明
-
数组中的每个元素必须存在tid指定的数据属性,否则运行时可能会导致异常。
-
数组中被tid指定的属性要保证唯一性,如果不是则会造成性能损耗。比如,示例中只有id和name可以作为tid字段,因为它们属于唯一字段。
-
tid不支持表达式。
2.1.5. 条件渲染
条件渲染分为2种:if/elif/else和show。两种写法的区别在于:第一种写法里if为false时,组件不会在vdom中构建,也不会渲染,而第二种写法里show为false时虽然也不渲染,但会在vdom中构建;另外,当使用if/elif/else写法时,节点必须是兄弟节点,否则编译无法通过。实例如下:
<!-- xxx.hml -->
<div class="container"><button class="btn" type="capsule" value="toggleShow" onclick="toggleShow"></button><button class="btn" type="capsule" value="toggleDisplay" onclick="toggleDisplay"></button><text if="{{show}}"> Hello-One </text><text elif="{{display}}"> Hello-Two </text><text else> Hello-World </text>
</div>
// xxx.js
export default {data: {show: false,display: true,},toggleShow: function() {this.show = !this.show;},toggleDisplay: function() {this.display = !this.display;}
}
优化渲染优化:show方法。当show为真时,节点正常渲染;当为假时,仅仅设置display样式为none。
<!-- xxx.hml -->
<div class="container"><button class="btn" type="capsule" value="toggle" onclick="toggle"></button><text show="{{visible}}" > Hello World </text>
</div>
// xxx.js
export default {data: {visible: false,},toggle: function() {this.visible = !this.visible;},
}
说明
-
禁止在同一个元素上同时设置for和if属性。
2.2. CSS语法
CSS是描述HML页面结构的样式语言。所有组件均存在系统默认样式,也可在页面CSS样式文件中对组件、页面自定义不同的样式。
2.2.1. 样式导入
为了模块化管理和代码复用,CSS样式文件支持 @import 语句,导入 CSS 文件。
2.2.2. 声明样式
每个页面目录下存在一个与布局hml文件同名的css文件,用来描述该hml页面中组件的样式,决定组件应该如何显示。
-
内部样式,支持使用style、class属性来控制组件的样式。例如:
<!-- index.hml --><div class="container"> <text style="color: red">Hello World</text></div> /* index.css */.container { justify-content: center;} -
文件导入,合并外部样式文件。例如,在common目录中定义样式文件style.css,并在index.css文件首行中进行导入:
/* style.css */.title { font-size: 50px;} /* index.css */@import '../../common/style.css';.container { justify-content: center;}
2.2.3. 选择器
css选择器用于选择需要添加样式的元素,支持的选择器如下表所示:
| 选择器 | 样例 | 样例描述 |
|---|---|---|
| .class | .container | 用于选择class="container"的组件。 |
| #id | #titleId | 用于选择id="titleId"的组件。 |
| , | .title, .content | 用于选择class="title"和class="content"的组件。 |
示例:
<!-- 页面布局xxx.hml --><div id="containerId" class="container"> <text id="titleId" class="title">标题</text> <div class="content"> <text id="contentId">内容</text> </div></div>
/* 页面样式xxx.css *//* 对class="title"的组件设置样式 */.title { font-size: 30px;}/* 对id="contentId"的组件设置样式 */#contentId { font-size: 20px;}/* 对所有class="title"以及class="content"的组件都设置padding为5px */.title, .content { padding: 5px;}
2.2.4. 伪类
css伪类是选择器中的关键字,用于指定要选择元素的特殊状态。
| 名称 | 支持组件 | 描述 |
|---|---|---|
| :active | input[type="button"] | 表示被用户激活的元素,如:被用户按下的按钮。轻量级智能穿戴上伪类选择器上仅支持background-color 和background-image 的样式设置。 |
| :checked | input[type="checkbox"、type="radio"] | 表示checked属性为true的元素。轻量级智能穿戴上伪类选择器上仅支持background-color 和background-image 的样式设置。 |
伪类示例如下,设置按钮的:active伪类可以控制被用户按下时的样式:
<!-- index.hml --><div class="container"> <input type="button" class="button" value="Button"></input></div>
/* index.css */.button:active { background-color: #888888;/*按钮被激活时,背景颜色变为#888888 */}
2.2.5. 样式预编译
预编译提供了利用特有语法生成css的程序,可以提供变量、运算等功能,令开发者更便捷地定义组件样式,目前支持less、sass和scss的预编译。使用样式预编译时,需要将原css文件后缀改为less、sass或scss,如index.css改为index.less、index.sass或index.scss。
-
当前文件使用样式预编译,例如将原index.css改为index.less:
/* index.less *//* 定义变量 */@colorBackground: #000000;.container { background-color: @colorBackground; /* 使用当前less文件中定义的变量 */} -
引用预编译文件,例如common中存在style.scss文件,将原index.css改为index.scss,并引入style.scss:
/* style.scss *//* 定义变量 */$colorBackground: #000000;在index.scss中引用:
/* index.scss *//* 引入外部scss文件 */@import '../../common/style.scss';.container { background-color: $colorBackground; /* 使用style.scss中定义的变量 */}
说明
引用的预编译文件建议放在common目录进行管理。
2.3. JS语法参考
JS文件用来定义HML页面的业务逻辑,支持ECMA规范的JavaScript语言。基于JavaScript语言的动态化能力,可以使应用更加富有表现力,具备更加灵活的设计。下面讲述JS文件的编译和运行的支持情况。
2.3.1. 语法
支持ES6语法。轻量级智能穿戴支持的ES6语法有限,仅支持以下ES6 语法:
-
let/const
-
arrow functions
-
class
-
default value
-
destructuring assignment
-
destructuring binding pattern
-
enhanced object initializer
-
for-of
-
rest parameter
-
template strings
-
模块声明
使用import方法引入功能模块:
import router from '@ohos.router'; -
代码引用
使用import方法导入js代码:
import utils from '../../common/utils.js';
2.3.2. 对象
-
页面对象
属性 类型 描述 data Object/Function 页面的数据模型,类型是对象或者函数,如果类型是函数,返回值必须是对象。属性名不能以$或_开头,不要使用保留字for, if, show, tid。 $refs Object 持有注册过ref 属性的DOM元素或子组件实例的对象。
2.3.4. 获取DOM元素
-
通过$refs获取DOM元素
<!-- index.hml --> <div class="container"><image-animator class="image-player" ref="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator> </div>// index.js export default {data: {images: [{ src: '/common/frame1.png' },{ src: '/common/frame2.png' },{ src: '/common/frame3.png' },],},handleClick() {const animator = this.$refs.animator; // 获取ref属性为animator的DOM元素const state = animator.getState();if (state === 'paused') {animator.resume();} else if (state === 'stopped') {animator.start();} else {animator.pause();}}, };
以上就是关于js在ArkUI方舟UI框架中的语法使用规则。
参考文档:
语法-框架说明-兼容JS的类Web开发范式 (ArkUI.Lite)-ArkTS组件-ArkUI API参考-开发 | 华为开发者联盟 (huawei.com)
相关文章:
【最新鸿蒙应用开发】——类Web开发范式2——前端语法
兼容JS的类Web开发范式 JS FA应用的JS模块(entry/src/main/js/module)的典型开发目录结构如下: 1. 项目基本结构 1.1. 目录结构 1.2. 项目文件分类如下: .hml结尾的HML模板文件,这个文件用来描述当前页面的文件布局结构。 .css结尾的CSS样…...
前端的强缓存和协商缓存
前端缓存机制 前端缓存主要分为两种类型:强缓存和协商缓存。 强缓存(HTTP Cache-Control) 通过设置HTTP响应头中的Cache-Control实现。浏览器根据Cache-Control的值决定是否重新请求资源。指令示例: no-cache:重新验…...
JSON如何处理包含特殊字符的字段
在JSON中处理包含特殊字符的字段时,你通常不需要直接处理这些特殊字符,因为JSON格式本身就会对特殊字符进行转义。当你使用编程语言或工具来生成或解析JSON时,这些转义通常是自动处理的。 然而,如果你需要手动处理或理解这些转义…...
JavaScript 中的 AbortController
AbortController 接口是 JavaScript 中 Fetch API 的一部分,引入它是为了处理和控制中止 fetch 请求的信号。这在需要取消正在进行的网络请求时特别有用,例如用户发起的动作取消,通过避免不必要的请求来提高性能,或优雅地处理超时…...
【前端】vue在线编辑器
以下是几个推荐的在线编辑器: CodeSandbox URL: https://codesandbox.io/特点: 支持 Vue、React、Angular 等多种前端框架,功能强大,社区活跃。 JSFiddle URL: https://jsfiddle.net/特点: 轻量级的在线编辑器,支持 Vueÿ…...
leetcode67:二进制求和
题目链接:67. 二进制求和 - 力扣(LeetCode) class Solution { public:string addBinary(string a, string b) {int stralen a.size(), strblen b.size();int curtc;int Maxlen max(stralen, strblen);vector<int> stra;vector<i…...
程序员必备的职业素养:专业精神、沟通能力与持续学习
🍎个人博客:个人主页 🏆个人专栏:日常聊聊 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 专业精神:技术的执着追求 沟通能力:团队合作的桥梁 持续学习:不断进步的动力 结语 我的…...
Spring源码:核心类的介绍
1. 前言 核心类代表了Spring框架中最基本的组件和功能,通过介绍这些类,学习者可以更好地理解Spring框架的核心工作原理和关键组件之间的关系。同时,了解这些核心类有助于学习者深入掌握Spring框架的使用和扩展方法。 2. ApplicationContextI…...
文化融合,市场共赢:品牌海外推广中的符号与象征策略
在全球化的今天,品牌海外推广不再仅仅是产品的输出,更是一种文化的交流和融合。品牌如何在保持自身特色的同时,又能融入当地文化,成为品牌海外拓展成功与否的关键。本文Nox聚星将和大家分析品牌如何运用具有当地文化特色的符号和象…...
fabric.util.enlivenObjects是什么意思
在Fabric.js中,fabric.util.enlivenObjects是一个实用函数,用于将一组对象的描述(通常是JSON格式的对象数组)转换回Fabric.js的对象实例。这个函数非常有用,特别是在涉及到从JSON恢复画布状态时,例如在实现…...
几个阶段性的面试难点整理
一、JVM篇 1、如何排查CPU、内存飙升的问题? 2、是否处理过线上问题?是怎么解决的? 3、谈谈G1收集器对比CMS收集器的优点?什么情况下适合用G1? 4、JVM调优的参数主要指哪方面的调优? 5、堆、栈中分别存放了…...
CTFHUB-技能树-web-信息泄露
目录 1.目录遍历 2.PHPINFO 3.备份文件下载 3.1 网站源码 3.2 bak文件 3.3 vim缓存 3.4 .DS_Store 4.Git泄露 4.1 Log 4.2 Stash 4.3 Index 5.SVN泄露 6.HG泄露 1.目录遍历 这个没什么好讲的,进去直接点击找flag,然后在下面目录翻,就找到了 …...
面试计算机网络八股文十问十答第八期
面试计算机网络八股文十问十答第八期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1) TCP到底是什么连接? …...
0605-JavaSE-单例模式-饿懒汉模式
不能放在方法里面(因为每个线程调用都会在方法里面实例化一个locker对象,但不属于同一个对象),然后要用static修饰成静态变量才会起到效果 //单例设计模式 //饿汉模式:在加载类的时候就已经开始创建 /…...
TCP和UDP区别
TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议)都是Internet协议套件中的传输层协议,但它们在工作方式、特性和适用场景上有显著区别ÿ…...
[Shell编程学习路线]——编制第一个shell脚本入门篇
🏡作者主页:点击! 🛠️Shell编程专栏:点击! ⏰️创作时间:2024年6月12日10点23分 🀄️文章质量:93分 目录 ——前言—— 💥常用的几种shell Bash Sh …...
python数据处理分析库(一)
目录 一、NumPy 二、Pandas 三、Matplotlib and Seaborn 一、NumPy 场景:处理大规模数组和矩阵运算,可以用于科学计算、数据预处理简单示例: import numpy as npdata np.array([1, 2, 3, 4, 5]) mean np.mean(data) std_dev np.std(da…...
使用Transformer进行抄袭检测
动机 在许多行业中,尤其是在学术界,抄袭是一个重大问题。随着互联网和开放信息的兴起,这种现象甚至变得更加严重,任何人都可以通过点击访问特定主题的任何信息。 基于这一观察,研究人员一直在尝试使用不同的文本分析…...
基于深度学习的电池健康状态预测(Python)
电池的故障预测和健康管理PHM是为了保障设备或系统的稳定运行,提供参考的电池健康管理信息,从而提醒决策者及时更换电源设备。不难发现,PHM的核心问题就是确定电池的健康状态,并预测电池剩余使用寿命。但是锂电池的退化过程影响因…...
【吊打面试官系列-Mysql面试题】MySQL 如何优化 DISTINCT?
大家好,我是锋哥。今天分享关于 【MySQL 如何优化 DISTINCT?】面试题,希望对大家有帮助; MySQL 如何优化 DISTINCT? DISTINCT 在所有列上转换为 GROUP BY,并与 ORDER BY 子句结合使用。 SELECT DISTINCT t…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
