赞
踩
从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?
抱着这样的疑问和对鸿蒙开发的好奇,让我们开始今天对ArkTS语言的了解以及对组件的掌握吧!
目录
ArkTS是HarmonyOS优选的主力应用开发语言,它在 TypeScript(简称TS) 的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。要了解什么是ArkTS,我们要先了解一下ArkTS、TypeScript 和 JavaScript 之间的关系,如下:
学习ArkTS之前还是推荐先了解并掌握一下 JS 和 TS ,这两门语言的掌握再回头看ArkTS的话可谓是上手很快了。ArkTS兼容TypeScript语言,拓展了声明式UI、状态管理、并发任务等能力。在学习ArkTS语言之前,建议开发者具备ts语言的开发能力,当前ArkTS在ts的基础上主要扩展了如下能力:
基本语法:
ArkTS定义了声明式 UI 描述、自定义组件和动态扩展UI元素的能力,再配ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。
状态管理:
ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和UI的联动。
渲染控制:
ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
未来,ArkTS会结合应用开发/运行的需求持续演进,逐步提供并行和并发能力增强、系统类型增强、分布式开发范式等更多特性。
在ArkTS的布局结构方面,开发者需要在页面上声明对应的元素,其布局的结构通常是分层级的,代表了用户界面中的整体架构,一个常见的页面结构如下:
其中Page表示页面的根节点,Column/Row等元素为系统组件。针对不同的页面结构,ArkUI提供了不同的布局组件来帮助开发者实现对应布局的效果,例如Row用于实现线性布局等,我会给大家详细讲解对应的布局。
接下来将对ArkUI常用的基础组件进行一个简单的演示与应用,掌握ArkUI的基本使用。
声明Image组件并设置图片源方式如下:
Image(src: string|PixelMap|Resource)
1)string格式,通常用来加载网络图片,需要申请网络访问权限:ohos.permission.INTERNET
Image('https://xxx.png')
打开 module.json5 文件夹下,配置如下 requestPermissions 选项,可以看到图片出现。
2)PixelMap格式,可以加载像素图,常用在图片编辑中
Image(pixelMapObject)
3)Resource格式,加载本地图片,推荐使用
Image($r('app.media.mate'60.png)
Image($rawfile('mate60.png'))
Text(content?: string|Resource)
1)string格式,直接填写文本内容
Text('文本内容')
2)Resource格式,读取本地资源文件
Text($r('app.string.width_label'))
这里我们设置了一个动态的文本显示:
TextInput( {placeholder?: ResourceStr, text?: ResourceStr} )
1)placeHolder:输入框无输入时的提示文本
TextInput({placeholder: '请输入账号或手机号'})
2)text:输入框当前的文本内容
TextInput({text: '文本内容'})
比如我们用输入框动态的改变一个图片的大小操作如下:
下面是输入框的各种类型描述:
名称 | 描述 |
---|---|
Normal | 基本输入模式。支持输入数字、字母、下划线、空格、特殊字符。 |
Password | 密码输入模式。支持输入数字、字母、下划线、空格、特殊字符。 |
邮箱地址输入模式。支持数字,字母,下划线,以及@字符。 | |
Number | 纯数字输入模式。 |
PhoneNumber | 电话号码输入模式。支持输入数字、+、-、*、#、长度不限。 |
Button(label?: ResourceStr)
1)文字型按钮
Button('点我')
2)自定义按钮,在Button内嵌套其它组件
Button(){
Image($r('app.media.search')).width(20).margin(10)
}
比如我们用按钮动态的改变一个图片的大小操作如下:
下面是按钮的各种类型描述:
名称 | 描述 |
---|---|
Capsule | 胶囊型按钮(圆角默认为高度的一半)。 |
Circle | 圆形按钮。 |
Normal | 普通按钮(默认不带圆角)。 |
滑动条的组件的功能实现很简单,只需要在Slider里面设置其功能,外部设置其样式即可:
Column容器与Row容器其对应的对齐方式使用的参数如下表格所示:
属性方法名 | 说明 | 参数 |
---|---|---|
justifyContent | 设置子元素在主轴方向的对齐格式 | FlexAlign枚举 |
alignItems | 设置子元素在交叉轴方向的对齐格式 | Row容器使用VerticalAlign枚举 |
Column容器使用HorizontalAlign枚举 |
Column容器中使用FlexAlign的主轴对齐方式函数及其特点如下所示:
Row容器中使用FlexAlign的主轴对齐方式函数及其特点如下所示:
两者在交叉轴上的对齐方式如下所示:
Column容器:纵向布局,先从上往下,再从左往右。
Row容器:横向布局,先从左往右,再从上往下。
以下给出使用Column和Row容器的例子:
- @Entry
- @Component
-
- struct Index {
- // 设置状态变量
- @State ImageWidth: number = 150
-
- build() {
- Column() {
- Row(){
- Image($r('app.media.icon'))
- .width(this.ImageWidth)
- .interpolation(ImageInterpolation.High)
- }
- .width('100%')
- .height(400)
- .justifyContent(FlexAlign.Center)
- Row(){
- Text($r('app.string.width_label'))
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- .fontColor('#008c8c')
- TextInput({text: this.ImageWidth.toString()})
- .backgroundColor('#fff')
- .width(200)
- .type(InputType.Number) // 只能输入数字类型
- .onChange(value=>{
- if (!value) {
- this.ImageWidth = 0
- }else {
- this.ImageWidth = parseInt(value)
- }
- })
- }
- .width('100%')
- .padding({left: 10, right: 10})
- .justifyContent(FlexAlign.SpaceBetween)
- Divider().width('91%')
- Row(){
- Button('缩小')
- .width(80)
- .fontSize(20)
- .onClick(()=>{
- if(this.ImageWidth >= 10){
- this.ImageWidth -= 10
- }
- })
- Button('放大')
- .width(80)
- .fontSize(20)
- .onClick(() => {
- if (this.ImageWidth <= 300) {
- this.ImageWidth += 10
- }
- })
- }
- .width('100%')
- .justifyContent(FlexAlign.SpaceAround)
- .margin({top: 30, bottom: 30})
-
- Slider({
- min: 100,
- max: 300,
- value: this.ImageWidth,
- step: 10, // 步长
- })
- .width('90%')
- .blockColor('#36D')
- .trackThickness(5) // 滑动条的粗细
- .showTips(true) // 显示气泡百分比
- .onChange(value => {
- this.ImageWidth = value
- })
- }
- .width('100%')
- .height('100%')
- }
- }
呈现的效果如下所示:
ForEach循环遍历数组,根据数组内容渲染页面组件,以下是其基本格式:
- ForEach(
- arr: Array, // 要遍历的数据数组
- (item: any, index?: number) => {
- // 页面组件生成函数
- }
- keyGenerator?: (item: any, index?: number): string => {
- // 键生成函数,为数组每一项生产一个唯一标识,组件是否重新渲染的判断标准
- }
- )
以下是通过ForEach生成页面的组件的基本案例:
- class Item {
- name: string
- image: ResourceStr
- price: number
- discount: number
-
- constructor(name: string, image: ResourceStr, price: number, discount = 0) {
- this.name = name
- this.image = image
- this.price = price
- this.discount = discount
- }
- }
-
- @Entry
- @Component
-
- struct Index {
- // 商品数据
- private items: Array<Item> = [
- new Item('华为', $r('app.media.icon'), 6999, 500),
- new Item('小米', $r('app.media.icon'), 7999),
- new Item('苹果', $r('app.media.icon'), 9999),
- new Item('三星', $r('app.media.icon'), 3999),
- new Item('oppo', $r('app.media.icon'), 1999),
-
- ]
- build(){
- Column({space: 4}){
- Row(){
- Text('商品列表')
- .fontSize(30)
- .fontWeight(FontWeight.Bold)
- }
- .width('100%')
- .margin({bottom: 20})
-
- ForEach(
- this.items,
- (item: Item) => {
- Row({space: 10}){
- Image(item.image)
- .width(100)
- Column({space: 4}){
- if (item.discount) {
- Text(item.name)
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- Text('原价:¥ '+ item.price)
- .fontColor('#ccc')
- .fontSize(14)
- .decoration({type: TextDecorationType.LineThrough})
- Text('折扣价:¥ '+ (item.price - item.discount))
- .fontColor('#F36')
- .fontSize(18)
- Text('补贴:¥ '+ item.discount)
- .fontColor('#F36')
- .fontSize(18)
- }else {
- Text(item.name)
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- Text('¥ '+ item.price)
- .fontColor('#F36')
- .fontSize(18)
- }
- }
- .margin({left: 10})
- .height('100%')
- .alignItems(HorizontalAlign.Start)
- }
- .width('100%')
- .height(120)
- .borderRadius(20)
- .backgroundColor('#EFEFEF')
- .padding(20)
- .margin({bottom: 10})
- }
- )
- }
- .width('100%')
- .height('100%')
- .padding(20)
- }
- }
呈现的结果如下所示:
List是一种复杂的容器,当页面内容数量过多超出屏幕后,其列表项ListItem会自动提供滚动功能,当然列表项既可以纵向排列也可以横向排列,其基本格式代码如下:
- List({space: 10}){
- ForEach([1, 2, 3, 4], item => {
- ListItem(){
- // 列表项内容,只能包含一个根组件
- Text('ListItem')
- }
- })
- }
- .width('100%')
- .listDirection(Axis.Vertical) // 列表方向,默认纵向(垂直)
在ForEarch外面我们嵌套一层List容器,在ForEach里面我们嵌套ListItem,来实现页面的滚动:
最终呈现的效果如下:
ArtTS提供了一些自定义组件及函数的方式,让繁杂的代码抽离出来,便于代码的可维护性和可阅读性,增强了代码的健壮性,以下是ArkTS进行自定义组件等相关的方法:
自定义组件:自定义组件很简单,可以在一个ets中进行书写,将一部分代码处理出来新设置一个 struct 构造函数即可,也可以将代码单独抽离出来形成一个新的文件,如下将上面案例的头部组件抽离出来形成一个新的组件Header,然后再在原本书写头部代码的位置引用Header组件即可:
自定义函数:自定义函数可以将烦长的代码单独抽离出一个函数当中,然后在原位置调用我们设置的函数即可,自定义函数可以定义在全局或组件内,如下:
如果想设置组件内自定义函数,则需要设置与build()函数平级然后去掉function,然后引用函数的位置需要通过this指向即可:
@Styles装饰器: 用来设置组件公共样式,可以定义在全局或者组件内,和自定义函数的方式一致,如下:
@Extend装饰器:仅可定义在全局,用来设置组件的特有属性,使用方式与上面一致:
- // 继承模式,只能写在全局
- @Extend(Text) function priceText() {
- .fontSize(18)
- .fontColor('#F36')
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。