一、内置组件是咩?
学过前端的都知道,一个组件就是由多个组件组成的,一个组件也可以是多个小组件组成的,组件就是一些什么导航栏、底部、按钮......啥的,但是组件分为【自定义组件】跟【内置组件】
【自定义组件】就是我们想要一个什么样的一块元素,就用一堆内置组件通过我们自己设置属性啥的,组合成一个【自定义组件】。
【内置组件】就是ArkTS原本就有的组件:图片、按钮、行元素、块元素、视频、音频.....
二、内置组件的简单写法
组件名( )
有的组件需要往“( )”里带参数,比如图片组件要带“路径参数”;有的就不用,但是不用参数也必须带上“( )”
然后如果要调整它的样式,就在【组件名( )】后.属性1( 值 ).属性2( 值 )......但是注意,有些属性是所有组件通用的,有些是各个组件自己特有的
例子:
三、各个内置组件
1、图片
图片组件【Image( )】,只需要往( )里传入图片路径即可用,但是有三种图片路径参数形式:
这里提示一下
我们的图片一般就放在【resources】目录下的【base.media】或【rawfile】
$r() 一般对应【base.media】的图片,当然也可以是别的目录,写的时候就是【app.别的目录.图片名】
$rawfile() 则是对应【rawfile】的图片,这个目录就不能改了,要真的用到【rawfile】里有的图片
示例:
第一种网络图片路径例子
但其实只是在这个模拟运行器里可以显示这个网络地址的图片,要是在真的模拟器或者手机上,就会显示不出来,这是因为没有申请网络访问权限
怎么申请网络访问权限?
官方文档:文档中心
找到在module.json5配置文件,在module下面复制这块配置代码(要了解为什么这么配置以后再说)
"requestPermissions": [{"name": "ohos.permission.INTERNET"} ],
第二种少用,就不演示了;
第三种本地路径的例子:
然后我们会发现有时候图片放大会有矩尺模糊、不好看,就需要用到图片组件的一个【特有属性】:.interpolation( )
当然如果我们记不住这么多属性,可以查看鸿蒙的内置API文档
点击【Help】——>点击【API Reference】就出来了API文档
然后搜索组件名,点到【ArkTS】就能看到属性详情
看外边框能看出一点差别
2、文字
文字组件【Text( )】
然后这里先提一下【resouces】这个目录的文件结构
【base】可以理解为一个默认基础陌路
下面的【en_US(英文)】【zh_CN(中文)】就是限定词目录,根据我们有什么限定词目录,将来翻译一些文本文件时,就可以找到对应的限定词目录的json文件的对应的内容
然后【限定词目录】的string.json文件里有的变量,在【base】也必须要有
第一种静态文字例子:
第二种根据本地源文件的变量显示的文字例子:
那我们刚刚设置了MyName这个变量的英文版,怎么看英文版?看下图
3、输入框
输入框组件【TextInput】
其中.type()属性有以下属性值
(注意,这些属性只是输入的【约束】,而非【校验】,校验需要我们自己手动)
名称 | 描述 |
InputType.Normal | 基本输入模式。支持输入数字、字母、下划线、空格、特殊字符 |
InputType.Password | 密码输入模式。支持输入数字、字母、下划线、空格、特殊字符 |
InputType.Email | 邮箱地址输入模式。支持数字,字母,下划线,以及@字符 |
InputType.Number | 纯数字输入模式 |
InputType.PhoneNumber | 电话号码输入模式。支持输入数字、+、-、*、# 长度不限 |
例子:
然后我们来做一个案例,用输入框输入的不同数字,当成一个变量,这个变量根据输入的数字来动态改变,同时还作为图片的宽度来控制图片大小
那么我们首先第一步:挂载、声明当前页面的这个变量
第二步:在用的地方 this.变量 就行了
看到这里,老铁们是不是觉得很熟悉,跟vue的data差不多
然后注意这里有个报错:输入的是一个string类型,不能让number类型的这个变量接收。可是我明明输入框的类型是数字啊
这是因为输入框其实一个“ 文本框 ”,即使输入的是数字,也只是字符串类型的数字,所以要把输入的 “ 字符串数字 ”转化成 “ 真数字 ” ,方法跟java的字符串转数字差不多【parseInt(字符串)】
还有,数字转字符串是 .toFix() ,括号里的参数值是保留的小数点位,0就是没有小数
4、按钮
按钮组件【Button】
其中.type( ) 有一下几种值
名称 | 描述 |
ButtonType.Capsule | 胶囊型按钮(圆角默认为高度的一半) |
ButtonType.Circle | 圆形按钮 |
ButtonType.Normal | 普通按钮(默认不带圆角) |
过于简单,直接看代码演示吧:
5、滑动条组件
这个玩意我们学HTML的时候就没有了,ArkTS特有的滑动条组件【Slider()】
示例:
注意一点,粗细不是靠高度来调的
完整的
8、行容器跟列容器
这个更简单,记住了【Column列容器】从上往下纵向排元素,【Row行容器】从左往右横向排元素
用HTML理解:【Column】=【div】,【Row】=【block】
用uniapp理解:【Column】=【view】,【Row】=【text】
然后调整这两个容器的布局通过下面这些属性:
这一看,老铁们熟悉得不能再熟悉了,对,就是CSS里面的【Flex弹性布局】啊!
就是有一点不同,主轴的属性值要FlexAlign.排列值(center、SpaceBetween、SpaceEvenly......)
然后交叉轴,Column容器是HorizontaAlign.排列值,Row容器是VerticalAlign.排列值
【Column容器的主轴方向排列参数】
【Column容器的交叉轴方向排列参数】
【Row容器的主轴方向排列参数】
【Row容器的交叉轴方向排列参数】
示例:
【这里强调一点!!!!!!】
想要这些排列值生效,必须必须必须!!!把要排列的方向设置好宽或者高
比如我希望一个Row容器里的元素自左往右均匀排列,那么我首先必须设置主轴的长度,也就是宽度!!这样才能根据宽度这个值来做参照,自动横向排列;
我希望一个Column容器里的元素自上往下均匀排列,我就要先设置好高,这样才能根据高度值做参照,自动纵向排列。
总结
四、样式
这个ArkTS的样式真是不想吐槽,对于我这种习惯了css、less、Vue......语法的人来说,真的麻烦得要死,大致上有些语法还是能用,但是还是有很多地方不一样:
像素单位
相信各位注意到了,我前面那么多例子里,没有出现过【px】、【vh】、【rpx】、【upx】这些常见单位
在ArkTS语法里,像素单位不需要写了,“组件()”这里取而代之的单位有两种形式:
- 要么直接填数值
.height(100)
- 要么填百分比,但是百分比形式必须要是字符串形式
.width('100%')
外边距、内边距
1、直接设置4个边的外边距的话,跟css一样直接写一个值就好
//内边距 .padding(20)//外边距 .margin(20)
2、如果你只要设置一边的有边距,在css的写法是:margin-top: ...、padding-left: ...、......
或者:margin: 上值 左值 下值 右值、padding: 上值 左值 下值 右值......
但是在ArkTS的写法是往【.margin( )】传入个对象参数,要哪个方向的边距就在对象设置:{ 方向1:值 , 方向2:值 , ...... }
//左右有内边距 .padding({ left: 10 , right: 10 })//上边有外边距 .margin({ top: 10 })
边框
css的写法贼鸡儿简单:
四边都有边框的话就是:border: 粗细 类型(虚线、实现...) 颜色
只要一边有边框就是:border-left: 粗细 类型(虚线、实现...) 颜色、border-top: 粗细 类型(虚线、实现...) 颜色 ......
但是ArkTS贼麻烦,记住了:
1、四边都有边框的话,颜色、粗细、类型啥的都有对应的属性名:
.borderWidth(1) //粗细 .borderColor('#afefef') //颜色 .borderStyle(BorderStyle.Solid) //线类型
当然也可以通过传对象的方式,把这些值全都放到一个对象传给【border( )】
.border({style: BorderStyle.Solid, width: 1,color: Color.Gray })
2、只要一个边的话,按各个属性名的方式写的话,每个属性里都传一个对象参数,对象里是对应的方向
.borderWidth({ bottom: 1 }) .borderColor({ bottom: '#afefef' }) .borderStyle({ bottom: BorderStyle.Solid })
或者按第二种传对象的方式,每个对象的值还是对象
.border({style: { bottom: BorderStyle.Solid }, width: { bottom: 1 },color: { bottom: Color.Gray } })
3、然后圆角的话也是,四个角都是圆角的话就直接写一个值
.borderRadius(20)
如果是只要单独某几个角,而不是四个角,还是传对象值
.borderRadius({ topLeft: 20,topRight: 20,bottomLeft: 20,bottomRight: 20 })
然后圆角的值也可以作为对象值,直接传入【border( )】
属性值
还有,注意一些属性值,跟我们css理解的属性值不一样,比如:
颜色,单词类型的不是:blue、black、white、yellow......,而是Color.Blue、Color.Black、Color.White、Color.Yellow......
边框的线的类型不是: solid、dotted、dashed,而是BorderStyle.Solid、BorderStyle.Dotted、 BorderStyle.Dashed
主轴排列justifyContent也不是:center、start、end、spaceBetween、spaceAround、spaceEvenly,而是FlexAlign.Center、 FlexAlign.Start、 FlexAlign.End、 FlexAlign.SpaceBetween、 FlexAlign.SpaceAround、 FlexAlign.SpaceEvenly
这里只说常见的,还有很多我就不一一列举了,以后用到的时候翻阅文档就知道了
五、循环
也很简单,就是Vue里面的v-for,只不过Vue是在<标签>里用v-for绑定数组名,它这个直接用ForEach()循环包住整个要循环的元素,也没问题,转换一下思维就好理解了
然后呢这玩意其实就是v-key
做个简单示例:
首先定义一个简单类
然后定义一个成员都是这个“ Item ”对象的数组
接下来直接循环它
有点难看,我们再调整一下样式,根据前面学的【Column】、【Row】,我们把 “ 图片 ” 和 “ 文字 ” 放到一个【Row容器】里左右排列,然后把文字部分的 “ item.name手机名字 ” 和 “ item.price手机价格 ” 放到一个【Column容器】里上下排列,然后再加点背景颜色、边框、外边距啥的,就nice了
但是还有问题!其实我们的元素是在整个页面居中排列的,现在是因为数组的成员多才撑到了顶
我们去掉几个元素,就会发现它是居中排列的
可是咱们要的是从页面顶部自上往下排列啊,那就要设置整个包住中间这些元素的Column容器,沿着主轴方向从开头排列【FlexAlign.Start】
用List()跟ListItem组件让页面可滑动
还没完......我们发现写完这个案例,没办法拖动屏幕看下面挡住的内容
就要加一个【List( )】这个组件包住【循环】,【List()】这个组件就是把这一块作为可滑动的区域。然后这个【List( )】里面必须必须必须包含有一个【ListItem( )】组件,这两组件暂时了解这么多够了
说白了【List( )】就是代替【Column容器】
完整样例代码:
//ArkTS的类的定义方法
class Item {//定义变量成员name: stringimgUrl: stringprice: numberdiscount: number//构造函数//换成java的写法:public Item(String name,String imgUrl,Int price)//discount: number = 0的意思是,可以不传这个参数,不传的话就默认是0constructor(name: string, imgUrl: string, price: number, discount: number = 0) {this.name = namethis.imgUrl = imgUrlthis.price = pricethis.discount = discount}
}
@Entry
@Component
struct Goods{private List: Array<Item> = [new Item('华为','https://gd-hbimg.huaban.com/a6d955ef4df395c734766c2ac56581123756c9c738a84-Jy0kKX_fw480webp',6999,500),new Item('苹果','https://gd-hbimg.huaban.com/6b9a7c00dc59e3d60aad6d714556414597ba8a1889ad8d-ECDC3P_fw480webp',7900),new Item('黄金手机','https://gd-hbimg.huaban.com/4569250f8d17c98d95a22914a2ca3a2e6edbb64b53233-J8uXwa_fw480webp',10000),new Item('小米','https://gd-hbimg.huaban.com/49626e33a18e743dd935d21f80c503917e14a4c612f5c-3wjWTv_fw480webp',2000),new Item('黑莓','https://gd-hbimg.huaban.com/cfa621505f7b96b05f66851639bf6c0b941f0e3e2c24e-b4Y08n_fw480webp',3450),new Item('诺基亚','https://gd-hbimg.huaban.com/dbce23ae86918485a72c3b568d2827e1fa77087cddca-UJdsZc_fw480webp',6000)]build() {Column({space: 20}) {Text('岑梓铭黑心手机店').width('100%').height(40).fontSize(34).fontWeight(500).margin({top: 20,left: 70})List({ space: 10 }){ForEach(this.List,(item:Item , index:Number) => {ListItem(){Row({space: 30}){Image(item.imgUrl).height(120).width(80).margin({left: 30})Column(){Text(item.name).fontSize(28)Text('$ '+item.price.toFixed(0)).fontSize(23).fontColor(Color.Red)}.height(130).justifyContent(FlexAlign.SpaceEvenly)}}.backgroundColor("#efefef").width('90%').borderRadius(20).borderWidth(1).borderColor('#afefef').borderStyle(BorderStyle.Solid).borderRadius(20).border({style: BorderStyle.Solid,width: 1,color: Color.Gray,radius: 20})})}.width('100%')//List按比例配高度,不写它的情况下就默认是0,那就默认自己配多高height就是多高//如果是1,那么就按比例,上面的元素是0,那么下面所有的高度都属于这个配了.layoutWeight(1)的元素.layoutWeight(1).alignListItem(ListItemAlign.Center)}.width('100%')//【第一】要想以Column的纵向排列,就必须设置高度,这样才能根据高度来排列.height('100%')//【第二】然后现在就可以根据Column的主轴的纵向,通过FlexAlign.Start从上往下排列了.justifyContent(FlexAlign.Start).backgroundColor('#afafaf')}
}
六、条件渲染
vue里的条件渲染是在<标签元素>里绑定 【v-if】、【v-else】、【v-show】
而ArkTS这里是直接在循环里写if-else,比较符合普通的编程语言的条件判断
那么我们在上面的案例增加一个条件渲染:当有折扣的时候,显示折扣,没有就照常按原样显示
修改后的完整代码:
//ArkTS的类的定义方法
class Item {//定义变量成员name: stringimgUrl: stringprice: numberdiscount: number//构造函数//换成java的写法:public Item(String name,String imgUrl,Int price)//discount: number = 0的意思是,可以不传这个参数,不传的话就默认是0constructor(name: string, imgUrl: string, price: number, discount: number = 0) {this.name = namethis.imgUrl = imgUrlthis.price = pricethis.discount = discount}
}
@Entry
@Component
struct Goods{private List: Array<Item> = [new Item('华为','https://gd-hbimg.huaban.com/a6d955ef4df395c734766c2ac56581123756c9c738a84-Jy0kKX_fw480webp',6999,500),new Item('苹果','https://gd-hbimg.huaban.com/6b9a7c00dc59e3d60aad6d714556414597ba8a1889ad8d-ECDC3P_fw480webp',7900),new Item('黄金手机','https://gd-hbimg.huaban.com/4569250f8d17c98d95a22914a2ca3a2e6edbb64b53233-J8uXwa_fw480webp',10000),new Item('小米','https://gd-hbimg.huaban.com/49626e33a18e743dd935d21f80c503917e14a4c612f5c-3wjWTv_fw480webp',2000),new Item('黑莓','https://gd-hbimg.huaban.com/cfa621505f7b96b05f66851639bf6c0b941f0e3e2c24e-b4Y08n_fw480webp',3450),new Item('诺基亚','https://gd-hbimg.huaban.com/dbce23ae86918485a72c3b568d2827e1fa77087cddca-UJdsZc_fw480webp',6000)]build() {Column({space: 20}) {Text('岑梓铭黑心手机店').width('100%').height(40).fontSize(34).fontWeight(500).margin({top: 20,left: 70})List({ space: 10 }){ForEach(this.List,(item:Item , index:Number) => {ListItem(){Row({space: 30}){Image(item.imgUrl).height(120).width(80).margin({left: 30})Column(){//当有discount这个成员时,显示折扣价这些if( item.discount ){Text(item.name).fontSize(28)Text('原价:$ ' + item.price.toFixed(0)).fontSize(19).fontColor(Color.Gray)//这是添加删除横线,TextDecorationType还有下划线、去掉线.......decoration({type: TextDecorationType.LineThrough})Text('折扣价:$ ' + (item.price - item.discount).toFixed(0)).fontSize(23).fontColor(Color.Red)Text('补贴:$ ' + item.discount.toFixed(0)).fontSize(20)}else{Text(item.name).fontSize(28)Text('$ '+item.price.toFixed(0)).fontSize(23).fontColor(Color.Red)}}.height(130).justifyContent(FlexAlign.SpaceEvenly)}}.backgroundColor("#efefef").width('90%').borderRadius(20).borderWidth(1).borderColor('#afefef').borderStyle(BorderStyle.Solid).borderRadius(20).border({style: BorderStyle.Solid,width: 1,color: Color.Gray,radius: 20})})}.width('100%')//List按比例配高度,不写它的情况下就默认是0,那就默认自己配多高height就是多高//如果是1,那么就按比例,上面的元素是0,那么下面所有的高度都属于这个配了.layoutWeight(1)的元素.layoutWeight(1).alignListItem(ListItemAlign.Center)}.width('100%')//【第一】要想以Column的纵向排列,就必须设置高度,这样才能根据高度来排列.height('100%')//【第二】然后现在就可以根据Column的主轴的纵向,通过FlexAlign.Start从上往下排列了.justifyContent(FlexAlign.Start).backgroundColor('#afafaf')}
}