
HarmonyOS Developer 兼容JS的类Web开发范式
构建用户界面
组件介绍
组件(Component)是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。关于组件的详细参考文档请参见组件。
开发者还可以通过组件间合理的搭配定义满足业务需求的新组件,减少开发量,自定义组件的开发方法请参见自定义组件。
组件分类
根据组件的功能,可以分为以下六大类:
组件类型 | 主要组件 |
容器组件 | badge、dialog、div、form、list、list-item、list-item-group、panel、popup、refresh、stack、stepper、stepper-item、swiper、tabs、tab-bar、tab-content |
基础组件 | button、chart、divider、image、image-animator、input、label、marquee、menu、option、picker、picker-view、piece、progress、qrcode、rating、richtext、search、select、slider、span、switch、text、textarea、toolbar、toolbar-item、toggle |
媒体组件 | video |
画布组件 | canvas |
栅格组件 | grid-container、grid-row、grid-col |
svg组件 | svg、rect、circle、ellipse、path、line、polyline、polygon、text、tspan、textPath、animate、animateMotion、animateTransform |
构建布局
‘’布局说明
设备的基准宽度为720px(px为逻辑像素,非物理像素),实际显示效果会根据实际屏幕宽度进行缩放。
其换算关系如下:
组件的width设为100px时,在宽度为720物理像素的屏幕上,实际显示为100物理像素;在宽度为1440物理像素的屏幕上,实际显示为200物理像素。
一个页面的基本元素包含标题区域、文本区域、图片区域等,每个基本元素内还可以包含多个子元素,开发者根据需求还可以添加按钮、开关、进度条等组件。在构建页面布局时,需要对每个基本元素思考以下几个问题:
- 该元素的尺寸和排列位置
- 是否有重叠的元素
- 是否需要设置对齐、内间距或者边界
- 是否包含子元素及其排列位置
- 是否需要容器组件及其类型
将页面中的元素分解之后再对每个基本元素按顺序实现,可以减少多层嵌套造成的视觉混乱和逻辑混乱,提高代码的可读性,方便对页面做后续的调整。以下图为例进行分解:
图1 页面布局分解
图2 留言区布局分解
添加标题行和文本区域
实现标题和文本区域最常用的是基础组件text。text组件用于展示文本,可以设置不同的属性和样式,文本内容需要写在标签内容区,完整属性和样式信息请参考text。在页面中插入标题和文本区域的示例如下:
添加图片区域
添加图片区域通常用image组件来实现,使用的方法和text组件类似。
图片资源建议放在js\default\common目录下,common目录需自行创建,详细的目录结构见目录结构。代码示例如下:
添加留言区域
留言框的功能为:用户输入留言后点击完成,留言区域即显示留言内容;用户点击右侧的删除按钮可删除当前留言内容并重新输入。
留言区域由div、text、input关联click事件实现。开发者可以使用input组件实现输入留言的部分,使用text组件实现留言完成部分,使用commentText的状态标记此时显示的组件(通过if属性控制)。在包含文本完成和删除的text组件中关联click事件,更新commentText状态和inputValue的内容。具体的实现示例如下:
添加容器
要将页面的基本元素组装在一起,需要使用容器组件。在页面布局中常用到三种容器组件,分别是div、list和tabs。在页面结构相对简单时,可以直接用div作为容器,因为div作为单纯的布局容器,可以支持多种子组件,使用起来更为方便。
List组件
当页面结构较为复杂时,如果使用div循环渲染,容易出现卡顿,因此推荐使用list组件代替div组件实现长列表布局,从而实现更加流畅的列表滚动体验。需要注意的是,list仅支持list-item作为子组件,具体的使用示例如下:
为避免示例代码过长,以上示例的list中只包含一个list-item,list-item中只有一个text组件。在实际应用中可以在list中加入多个list-item,同时list-item下可以包含多个其他子组件。
Tabs组件
当页面经常需要动态加载时,推荐使用tabs组件。tabs组件支持change事件,在页签切换后触发。tabs组件仅支持一个tab-bar和一个tab-content。具体的使用示例如下:
tab-content组件用来展示页签的内容区,高度默认充满tabs剩余空间。
添加交互
添加交互可以通过在组件上关联事件实现。本节将介绍如何用div、text、image组件关联click事件,构建一个如下图所示的点赞按钮。
图1 点赞按钮效果
点赞按钮通过一个div组件关联click事件实现。div组件包含一个image组件和一个text组件:
- image组件用于显示未点赞和点赞的效果。click事件函数会交替更新点赞和未点赞图片的路径。
- text组件用于显示点赞数,点赞数会在click事件的函数中同步更新。
click事件作为一个函数定义在js文件中,可以更改isPressed的状态,从而更新显示的image组件。如果isPressed为真,则点赞数加1。该函数在hml文件中对应的div组件上生效,点赞按钮各子组件的样式设置在css文件当中。具体的实现示例如下:
除此之外,还提供了很多表单组件,例如开关、标签、滑动选择器等,以便于开发者在页面布局时灵活使用和提高交互性,详见容器组件。
动画
动画分为静态动画和连续动画。
静态动画
静态动画的核心是transform样式,主要可以实现以下三种变换类型,一次样式设置只能实现一种类型变换。
- translate:沿水平或垂直方向将指定组件移动所需距离。
- scale:横向或纵向将指定组件缩小或放大到所需比例。
- rotate:将指定组件沿横轴或纵轴或中心点旋转指定的角度。
具体的使用示例如下,更多信息请参考组件方法。
图1 静态动画效果图
连续动画
静态动画只有开始状态和结束状态,没有中间状态,如果需要设置中间的过渡状态和转换效果,需要使用连续动画实现。
连续动画的核心是animation样式,它定义了动画的开始状态、结束状态以及时间和速度的变化曲线。通过animation样式可以实现的效果有:
- animation-name:设置动画执行后应用到组件上的背景颜色、透明度、宽高和变换类型。
- animation-delay和animation-duration:分别设置动画执行后元素延迟和持续的时间。
- animation-timing-function:描述动画执行的速度曲线,使动画更加平滑。
- animation-iteration-count:定义动画播放的次数。
- animation-fill-mode:指定动画执行结束后是否恢复初始状态。
animation样式需要在css文件中先定义keyframe,在keyframe中设置动画的过渡效果,并通过一个样式类型在hml文件中调用。animation-name的使用示例如下:
图2 连续动画效果图
手势事件
手势表示由单个或多个事件识别的语义动作(例如:点击、拖动和长按)。一个完整的手势也可能由多个事件组成,对应手势的生命周期。支持的事件有:
触摸
- touchstart:手指触摸动作开始。
- touchmove:手指触摸后移动。
- touchcancel:手指触摸动作被打断,如来电提醒、弹窗。
- touchend:手指触摸动作结束。
点击
click:用户快速轻敲屏幕。
长按
longpress:用户在相同位置长时间保持与屏幕接触。
具体的使用示例如下:
页面路由
很多应用由多个页面组成,比如用户可以从音乐列表页面点击歌曲,跳转到该歌曲的播放界面。开发者需要通过页面路由将这些页面串联起来,按需实现跳转。
页面路由router根据页面的uri找到目标页面,从而实现跳转。以最基础的两个页面之间的跳转为例,具体实现步骤如下:
- 在“Project“窗口,打开src > main >js >MainAbility,右键点击pages文件夹,选择NewJS Page,创建一个详情页。
- 调用router.push()路由到详情页。
- 调用router.back()回到首页。
构建页面布局
index和detail这两个页面均包含一个text组件和button组件:text组件用来指明当前页面,button组件用来实现两个页面之间的相互跳转。hml文件代码示例如下:
构建页面样式
构建index和detail页面的页面样式,text组件和button组件居中显示,两个组件之间间距为50px。css代码如下(两个页面样式代码一致):
实现跳转
为了使button组件的launch方法生效,需要在页面的js文件中实现跳转逻辑。调用router.push()接口将uri指定的页面添加到路由栈中,即跳转到uri指定的页面。在调用router方法之前,需要导入router模块。代码示例如下:
运行效果如下图所示:
