鸿蒙_入门
HarmonyOS入门
图标库:https://developer.huawei.com/consumer/cn/design/harmonyos-icon/
系统UI:https://developer.huawei.com/consumer/cn/design/harmonyos-symbol/
文档:https://developer.huawei.com/consumer/cn/doc/
常用组件
文本 Text
默认靠左
Text('测试文本')
文本属性
// 文字颜色
.fontColor(Color.Yellow) // 枚举值
.fontColor('#df3c50') // 16进制值
.fontSize(20) // 文字大小
.fontWeight(FontWeight.Bold) // 文字粗细
.fontWeight(700) // 100 ~ 900的数字 加粗700 默认400
.fontStyle(FontStyle.Italic) // 文字倾斜
.textAlign(TextAlign.Start) // 文字居左 (默认)
.textAlign(TextAlign.Center) // 文字居中
.textAlign(TextAlign.End) // 文字居右
文字溢出显示省略号 \ 行高
.textOverflow({
overflow:TextOverflow.Ellipsis
})
.maxLines(2) // 最大显示行数
.lineHeight(30) // 行高
overflow:TextOverflow. 支持的值
None 超出部分不显示
clip 超出部分不显示
Ellipsis 超出部分显示省略号,需要配合 maxLines 出效果
MARQUEE 只显示一行,滚动显示, maxLines 在这里没有用
Text( ) 里面可以包含的主键
// 文字
text(){
Span('测试案例一')
Span('测试案例二')
Span('测试案例三')
}
// 图标
text(){
ImageSpan($r('app.media.XXX'))
}
输入框 TextInput
TextInput({placeholder:'写评论...'})
.placeholderColor('#f40') // 设置文本占位符颜色
.backgroundColor(Color.Transparent) // 背景透明色
TestInput().type(InputType.Password) // 密码框
TestInput({text:'admin'}) // 可以默认展示在输入框,实现免输入
参数对象: placeholder 提示文本
设置输入框 type 类型 .type(InputType.xxx)
type值 | 解释说明 |
---|---|
Normal | 基本输入模式,无特殊限制 |
Password | 密码输入 |
文字和边框的距离,是由通用属性控制padding
padding的默认值为:
{
top: 8 vp,
right: 16 vp,
bottom: 8 vp,
left: 16 vp
}
设置输入文本在输入框中的对齐方式。默认值:TextAlign.Start (水平方向,前中后)
按钮 Button
Button('登录')
.type(ButtonType.Capsule) // 胶囊按钮 (默认)
//.type(ButtonType.Circle) // 圆形
//.type(ButtonType.Normal) // 方形
.enabled(this.selectedUris.length > 0) // 判断是否可以点击
Button('发布',{stateEffect:false})
选择框 CheckBox
Checkbox()
图片 Image
Image('http://www.XXX.COM/icon/XX.png') // 网片
Image($r('app.media.startIcon')) // 本地资源库
Image($r('sys.media.ohos_icon_mask_svg')) // 资源库,官方图标
等比例
Image('http://www.XXX.COM/icon/XX.png')
.width:100
.aspectRatio(1) 表示和宽一样
内边距 Padding
.padding(20) // 给四周都加20内边距
.padding({
top: 5,
bottom: 5,
left: 10,
right: 10
})
外边距 margin
.margin(20) // 给四个方向添加外边距都为20
.margin({
top:10,
left:10,
right:10,
bottom:10
})
边框 border
.border({
width:1, // 宽度(必须设置)
color:Color.Green, // 颜色
style:BorderStyle.Solid // 样式
})
边框样式: 实线/虚线/点线
单边框,可以通过 left right bottom top 配置四个方向,width color style 都支持
.border({
width:{
left:1,
right:1
},
color:{
left:Color.Red,
right:'#f40'
},
style:{
left:BorderStyle.Solid,
right:BorderStyle.Dashed
}
})
圆角设置 borderRadius
.borderRadius(20)
.borderRadius({
topLeft:10, // 左上角
topRight:10, // 右上角
bottomLeft:19, // 左下角
bottomRight:19 // 右下角
})
背景图片
.backgroundColor(Color.Transparent) // 背景颜色透明
颜色是十六进制色值,如果是八位,前两位,就是透明度
背景图片位置
.backgroundImagePosition(Alignment.Center) // 枚举值,居中
.backgroundImagePosition(Alignment.TopStart) // 左上角
.backgroundImagePosition(Alignment.TopEnd ) // 右上角
.backgroundImagePosition(Alignment.BottomStart) // 左下角
.backgroundImagePosition(Alignment.BottomEnd) // 右下角
.backgroundImagePosition({x:100,y:100}) // 坐标值,图片的参考点的左上角
单位 vp 和 px
px 是实际的物理像素点,也就是分辨率的单位
vp 虚拟像素,相对于不同设备会自动转换,保证不同设备的视觉一致 (宽高的默认单位)
函数: vp2px(数值) 将vp进行转换,得到px的数值
.backgroundImagePosition({x:vp2px(100),y:vp2px(100)})
背景图片尺寸
.backgroundImageSize(ImageSize.Auto) // 默认,原始尺寸
.backgroundImageSize(ImageSize.Cover) // 等比例缩放背景图片,直至完全覆盖主键范围
.backgroundImageSize(ImageSize.Cover) // 等比例缩放背景图,当宽或高碰到组件时停止缩放,可能会出现留白
.backgroundImageSize({
width:100,
height:100
})
循环渲染ForEach(下面还有)
ForEach(Array.from({length:20}),(item,index)=>{
InfoItem(){ ... }
})
列表 List
List() {
ListItem() {}
}
主轴方向(垂直) | .listDirection(Axis.Horizontal) |
交叉轴布局 | .lanes(列数,间距) |
列对齐方式 | .alignListItem(ListItemAlign.Center) |
滚动条状态 | .scrollBar(BarState.Auto) |
分割线样式 | .divider({ strokeWidth:1 color:‘#f40’ startMargin:10 endMargin:10 }) |
容器组件 Tabs
当页面内容较多时,可以通过Tabs组件进行分类展示
Tabs(){
TabContent(){
Text('笔记')
}
.tabBar('笔记')
TabContent(){
Text('收藏')
}
.tabBar('收藏')
TabContent(){
Text('赞过')
}
.tabBar('赞过')
}
barPosition : 调整位置开头或结尾( 参数)
vertical : 调整导航水平或垂直
scrollable : 调整是否手势滑动切换
animationDuration : 点击滑动动画时间
名称 | 功能描述 |
---|---|
onChange(event:(index:number)=>void) | Tab页签切换后触发事件 index:当前显示的index索引,索引从0开始计算。 滑动切换、点击切换 均会触发 |
onTabBarClick(event:(index:number)=>void) | Tab页签点击后触发的事件 index:被点击的index索引,索引从0开始计算 |
Tabs(){
TabContent(){
Text('笔记')
}
.tabBar(this.myBuilder)
}
.onChange((index:number)=>{
console.log('激活的索引',index)
})
滚动容器Scroll
当子组件的布局尺寸超过Scroll的尺寸时,内容可以滚动
Scroll(){
// 可以传递参数
// Scroll只支持一个只组件
Column({space:10}){
ForEach(Array.from({length:10}),(item:string,index)=>{
Text('测试文本'+index)
})
}
}
.scrollable(ScrollDirection.Vertical) // 纵向滚动,这是默认的可以不写
名称 | 参数类型 | 描述 |
---|---|---|
scrollable | ScrollDirection | 设置滚动方向 |
scrollBar | BarState | 设置滚动条状态 |
scrollBarColor | string | number | color | 设置滚动条颜色 |
scrollBarWidth | string | number | 设置滚动条宽度 |
edgeEffect | value:EdgeEffect | 设置边缘滑动效果 |
.scrollable(ScrollDirection.Vertical) // 纵向滚动(默认)
.scrollable(ScrollDirection.Horizontal) // 横向滚动
.scrollBar(BarState.Auto) // 滚动条不滑动的时候不显示,滑动才会显示
.scrollBar(BarState.On) // 一直显示
.scrollBar(BarState.Off) // 隐藏滚动条,关闭
.scrollBarColor(Color.Yellow) // 滚动条颜色
.scrollBarWidth(20) // 滚动条宽度
.edgeEffect(EdgeEffect.None) // 无
.edgeEffect(EdgeEffect.Spring) // 弹簧
.edgeEffect(EdgeEffect.Fade) // 阴影
Scroll的控制器(回到顶部)
@Entry
@Component
struct demo4 {
myColumn: Scroller = new Scroller()
build() {
Column() {
Scroll(this.myColumn) {...}
Button('回到顶部')
.onClick(() => {
this.myColumn.scrollEdge(Edge.Top)
})
Button('获取滚动距离')
.onClick(() => {
const x = this.myColumn.currentOffset().xOffset
const y = this.myColumn.currentOffset().yOffset
AlertDialog.show({
message: `x:${x},y:${y}`
})
})
}
}
}
填充组件
Blank()
作用:填充空白区域(像弹簧)
弹性布局 Flex
Flex布局:伸缩布局,当子盒子的宽高总和溢出父盒子,默认进行压缩显示
线性布局,性能高于Flex
Column(){
Flex({
// 主轴方向
// direction:FlexDirection.Row // 元素横着排,从左到右,左上角为起点
// direction:FlexDirection.Column // 元素竖着排,从上到下,左上角为起点
// direction:FlexDirection.RowReverse // 元素横着排,从左到右,结束点在右上角
// direction:FlexDirection.ColumnReverse // 紧挨着左边,从上往下,结束点在左下角
// 主轴对齐方式
// justifyContent:FlexAlign.Start // 起始位置
// justifyContent:FlexAlign.Center // 居中
// justifyContent:FlexAlign.End // 末尾位置
// justifyContent:FlexAlign.SpaceBetween // 两头靠边,中间均分
// justifyContent:FlexAlign.SpaceAround // 0.5 1 1 1 0.5
// justifyContent:FlexAlign.SpaceEvenly // 全部均分
// 交叉轴对齐方式
// alignItems:ItemAlign.Stretch // 拉伸 (相当于把高度或宽度调成100%)
// ......
}){
Text('一').width(60).backgroundColor('#eaf9fe').textAlign(TextAlign.Center)
Text('二').width(60).backgroundColor('#d0eefe').textAlign(TextAlign.Center)
Text('三').width(60).backgroundColor('#aee4fd').textAlign(TextAlign.Center)
Text('四').width(60).backgroundColor('#7bd6fc').textAlign(TextAlign.Center)
Text('五').width(60).backgroundColor('#46bdfa').textAlign(TextAlign.Center)
}
}
Flex布局换行
FlexWrap.NoWrap 单行布局
FlexWrap.Wrap 多行布局
Flex({
wrap:FlexWrap.Wrap // 放不下自动换行
}){
Text('ArkUI').padding(10).margin(5).backgroundColor('#f1f1f1')
Text('ArkTS').padding(10).margin(5).backgroundColor('#f1f1f1')
......
}
决对定位position
作用:控制组件位置,实现层叠效果
参照父组件左上角进行偏移
组件不在占用原来的位置
.position({
x: 100,
y: 100
})
层级关系,后面的组件(代码在下面的)会盖住前面的组件
.zIndex(1)
定位offset
会占有之前的位置
offset({
y:100
x:100
})
层叠布局
组件层叠,特点是更简洁,编码效率更高(绝对定位是更灵活)
Stack({
alignContent:Alignment.Center
}){
Text().width(300).height(300).backgroundColor('#f0fcff')
Text().width(200).height(200).backgroundColor('#d0dfe6')
Text().width(100).height(100).backgroundColor('#8abcd1')
}
Badge角标组件
Column(){
Badge({
count:1, // 角标数值 小于1就不展示
position:BadgePosition.RightTop, // 角标位置,只能左、右和右上
style:{
fontSize:50, // 文字大小
badgeSize:16, // 图形大小
badgeColor:'#fa2a2d' // 图形底色
}
}){
Image($r('app.media.mntx')).width(200)
}
}
position:BadgePosition.RightTop // 右上
position:BadgePosition.Right // 右
position:BadgePosition.Left // 左
Grid网格布局容器
子组件GridItem
Column() {
Grid(){
ForEach((Array.from({length:9}),()=>{
GridItem(){
Column(){}.width('100%').height('100%').backgroundColor(Color.Green)
}
})
}
.columnsTemplate('1fr 1fr 2fr') // 1个1fr表示一列
.rowsTemplate('1fr 1fr 1fr') // 1个1fr表示一行
.columnsGap(5) // 列之间的间隙
.rowsGap(5) // 行之间的间
}
Swiper轮播组件
swiper是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示(文字,图 片,…)
Column(){
Swiper(){
Image($r('app.media.demo3_1'))
Image($r('app.media.demo3_2'))
Image($r('app.media.demo3_3'))
Image($r('app.media.demo3_4'))
}
.width('100%')
.height(400)
属性方法 | 传值 | 作用 | 默认值 |
---|---|---|---|
loop | boolean | 是否开启循环 | true |
autoPlay | boolean | 是否自动播放 | false |
interval | number | 自动播放的时间间隔(ms) | 3000 |
vertical | boolean | 纵向滑动轮播 | false |
… |
Swiper(){
Image('...')
......
}
.width('100%')
.aspectRatio(1) // 高度和宽一致
.autoPlay(true) // 自动播放
.interval(4000) // 间隔4秒
.vertical(true) // 纵向播放
// 小圆点的设置
.indicator(false) // 不显示小圆点
// 显示
.indicator( // 指示器
Indicator.dot() // 小圆点
.itemWidth(20) // 默认宽度
.itemHeight(20) // 默认高度
.color(Color.Black) // 默认颜色
.selectedItemWidth(30) // 选中宽度
.selectedItemHeight(30) // 选中高度
.selectedColor(Color.White) // 选中颜色
)
样式
IconFont字体图标使用
阿里巴巴矢量图标库:https://www.iconfont.cn/
- iconfont官网选图标 → 加入项目 → 下载
- 注册成自定义字体
- 设置字体使用
优势:任意放大缩小,不失真,可以修改颜色
import font from '@ohos.font'
@Entry
@Component
struct Index {
// 一加载Index入口页面,就会进行注册
// aboutToAppear → 会在组件一加载时,自动调用执行(生命周期函数)
aboutToAppear(): void {
font.registerFont({
familyName:'myfont',
familySrc:'/fonts/iconfont.ttf'
})
}
build() {
Column(){
Text('\ue639')
.fontFamily('myfont')
.fontSize(30)
}
}
}
线性布局 主轴对齐方式
线性布局(LinearLayout)通过线性容器Column和Row创建
Column 容器: 子元素垂直方向排列
Row 容器: 子元素水平方向排列
build() {
Column(){
Text('Iten1')
Text('Iten2')
Text('Iten3')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
FlexAlign的枚举值
.justifyContent(FlexAlign.Start) // 主轴起始位置对齐
.justifyContent(FlexAlign.Center) // 主轴居中对齐
.justifyContent(FlexAlign.End) // 主轴结束位置对齐
.justifyContent(FlexAlign.SpaceBetween)// 两头元素贴边,中间元素均匀分布
.justifyContent(FlexAlign.SpaceAround) // 间隙环绕 0.5 1 1 1 0.5 的间隙分布,靠边的只有一半的间隙
.justifyContent(FlexAlign.SpaceEvenly) // 所有间隙均匀分布
交叉轴对齐方式
属性: alignItems( ) 参数: 枚举类型
交叉轴在水平方向: HorizontalAlign
交叉轴在垂直方向: VerticalAlign
Column({space:5}) {
Text('账单')
Text('总资产')
Text('余额')
}
.alignItems(HorizontalAlign.Start) // 左
// .... HorizontalAlign.Center // 中
// .... HorizontalAlign.End // 右
Row({space:5}) {
Text('微信')
Text('通讯录')
Text('朋友圈')
}
.alignItems(VerticalAlign.Top) // 上
// .... VerticalAlign.Center 中
// .... VerticalAlign.Bottom 下
自适应伸缩
设置 layoutWeight 属性的子元素 与 兄弟元素,会按照权重进行分配 主轴的空间(剩余空间)
语法: .layoutWeight( 数字 )
Row(){
Text('左侧')
.layoutWeight(1)
.height(50)
.backgroundColor(Color.Pink)
Text('右侧')
.width(70)
.height(50)
.backgroundColor(Color.Orange)
}
填充组件
Blank()
作用:填充空白区域(像弹簧)
@Extend
名称 | 适合 | 参数 |
---|---|---|
@Extend | 抽取特定组件样式、事件 | 可以传递参数 |
@Styles | 抽取公共样式、事件 | 不可以传递参数 |
@Builder | 抽取结构、样式、事件 | 可以传递参数 |
扩展组件 扩展组件的样式、事件,实现复用效果
@Styles抽取通用属性、事件
不支持传递参数
// 全局定义
@Styles function commonStyles(){
.width('100%')
.height(200)
}
@Entry
@Component
struct demo4 {
@State color:ResourceColor=Color.Brown
// 在组件内定义
@Styles setBg(){
.backgroundColor(this.color)
}
build() {
Column() {
Row() {...}
.commonStyles()
.setBg()
Image($r(...))
.commonStyles()
.setBg()
Text(...)
.commonStyles()
.setBg()
}
}
}
@Builder自定义构建函数(结构、样式、事件)
@Builder
function navItem(icon:ResonrceStr,text:string){
Column({space:10}) {
Image(icon)
.width('100%')
Text(text)
}
.width('25%')
onClick(()=>{
AlerDialog.show({
message:'点了'+text
})
})
}
Row() {
navItem($r('app.media.demo3_1'),'首页')
navItem($r('app.media.demo3_1'),'我的')
}
@Builder 里面的数据要响应式的
@Builder
function navItem(dateInfo:DateInfo){
Column({space:10}) {
Image(dateInfo.icon)
.width('100%')
Text(text)
}
.width('25%')
onClick(()=>{
AlerDialog.show({
message:'点了'+dateInfo.text
})
})
}
Row() {
navItem({icon:$r('app.media.demo3_1'),text:'首页'})
}
interface DateInfo{
icon:ResonrceStr
text:string
}
@BuilderParam
BuilderParam表示我当前只是放了一个框,可以放一些默认值,真正要放的时候,可以传递过来覆盖
BuilderParam默认值只能是Builder
@Entry
@Component
struct DemoIndex {
build() {
Column() {
MyBuilderParmChild()
}
.height('100%')
.width('100%')
}
}
@Component
struct MyBuilderParmChild {
@Builder defaultParam() {Text('左边')}
@BuilderParam leftContent: () => void = this.defaultParam
@Builder defaultCenterParam() {Text('中间')}
@BuilderParam centerContent: () => void = this.defaultCenterParam
@Builder defaultRightParam() {Text('右边')}
@BuilderParam rightContent: () => void = this.defaultRightParam
build() {
Row() {
// 左
this.leftContent()
// 中
this.centerContent()
// 右
this.rightContent()
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Entry
@Component
struct DemoIndex {
@Builder
LeftBuilder(){
Image($r('sys.media.ohos_ic_compnent_titlebar_back_filled'))
.width(20)
}
@Builder
CenterBuilder(){
Text('我是新的中间')
}
@Builder
rightBuilder(){
Image($r('sys.media.ohos_ic_public_search_filled'))
.width(20)
}
build() {
Column() {
MyBuilderParmChild({
leftContent:this.LeftBuilder,
centerContent:this.CenterBuilder,
// 更加推荐下面这种写法
rightContent:()=>{
this.rightBuilder()
}
})
}
.height('100%')
.width('100%')
}
}
@Component
struct MyBuilderParmChild {
@Builder defaultParam() {Text('左边')}
@BuilderParam leftContent: () => void = this.defaultParam
@Builder defaultCenterParam() {Text('中间')}
@BuilderParam centerContent: () => void = this.defaultCenterParam
@Builder defaultRightParam() {Text('右边')}
@BuilderParam rightContent: () => void = this.defaultRightParam
build() {
Row() {
// 左
this.leftContent()
// 中
this.centerContent()
// 右
this.rightContent()
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
}
显示或隐藏效果控制
遮罩显隐控制
1.透明度 opacity:0=>1
2.层级 zIndex:-1=>99
图片动画
缩放 scale:0=>1
x 表示横向,y表示纵向,1就是默认大小,和当前一样,没有变化
0表示看不见,0.5 表示比之前小0.5倍,2就是原来的2倍大
0到1,就是从看不见,慢慢放大到默认大小
@Entry
@Component
struct demo3 {
@State maskOpacity:number=0 // 页面透明度
@State maskZIndex:number=-1 // 页面层级
@State maskScaleX:number=0
@State maskScaleY:number=0
build() {
Stack(){
Column(){
Button('立即抽卡')
.onClick(()=>{
this.maskOpacity = 1
this.maskZIndex = 1
this.maskScaleX = 1
this.maskScaleY = 1
})
}
Column(){
Image($r('app.media.sx2'))
// 控制元素的缩放
.scale({
x:this.maskScaleX,
y:this.maskScaleY
})
.animation({
duration:500
})
Button('开心收下')
.onClick(()=>{
this.maskOpacity =0
this.maskZIndex=-1
this.maskScaleX=0
this.maskScaleY=0
})
}
// 透明度 0全透明 0.5半透明 1完全显示
.opacity(this.maskOpacity)
.zIndex(this.maskZIndex)
// animation 动画 duration 动画时间,单位毫秒
.animation({
duration:300
})
}
}
}
数据传值
父子单向 @Prop
父组件改变,子组件同步更新,子组件更改,不会同步父组件,父组件更改,又会覆盖子组件
父子双向 @Link
不能右默认值,自己改,父组件也会同步
后代通信 提供 @Provide (起别名)
接收 @Consume(提供的名字)
接收的别名
@Observed与@ObjectLink
数据确保是通过 @Observed
修饰的类new
出来的
@Require修饰符
如果你想让父组件必须传递一个属性给你的Prop,作为强制性的约束条件,可以使用Require修饰符
@Require修饰符只能作用在两个修饰符前面@Prop @BuilderParam
@Track装饰器
Track的作用只更新对象中的某些字段, Track修饰符用来作用在class中的某些字段,只有被标记的字段才会更新,并且没有被Track标记的字段不能被使用
数据基础
字符串拼接
let name: string = '小明'
console.log('简介信息','名字是'+ name)
模板字符串
用反的单引号 `
拼接字符串和变量,更适合多个变量字符串的字符拼接
let name:string = '余强东'
let age:number = 25
console.log('字符串拼接',`姓名是${name},今年${age}岁了`)
类型转换(数字和字符串)
字符串转数字
Number( ):字符串 直接转数字,转换失败返回NaN(字符串中包含非数字)
parseInt( ):去掉小数部分 转数字,转换失败返回NaN
parseFloat( ):保留小数部分 转数字,转换失败返回NaN(如果最后面包含字母,会省略)
数字转字符串
toString( ):数字直接转字符串
toFixed( ):四舍五入转字符串,括号内填数字,表示保留几位小数,不填,就有取整的效果
let str1:string='1.1'
let str2:string='1.9'
let str3:string='1.1a'
console.log('Number',Number(str1)) // 1.1
console.log('Number',Number(str2)) // 1.9
console.log('Number',Number(str3)) // NaN
console.log('parseInt',parseInt(str1)) // 1
console.log('parseInt',parseInt(str2)) // 1
console.log('parseInt',parseInt(str3)) // 1
console.log('parseFloat',parseFloat(str1)) // 1.1
console.log('parseFloat',parseFloat(str2)) // 1.9
console.log('parseFloat',parseFloat(str3)) // 1.1
let num1:number=1.1
let num2:number=1.9
let num3:number=1.97532
console.log('num1',num1.toString()) // 1.1
console.log('num2',num2.toString()) // 1.9
console.log('num3',num3.toString()) // 1.97532
console.log('num1',num1.toFixed()) // 1
console.log('num2',num2.toFixed()) // 2
console.log('num3',num3.toFixed()) // 2
console.log('num3',num3.toFixed(1)) // 2.0
console.log('num3',num3.toFixed(2)) // 1.98
交互 - 点击事件
说明:组件被点击时触发的事件
作用:监听(感知)用户点击行为,进行对应操作
Column() {
Button('点我弹框')
.onClick(()=>{
console.log('消息','用户点击了')
AlertDialog.show({
message:'我是点击后展示的结果'
})
})
}
.onClick(()=>{ })
点击事件
AlertDialog.show({ message:'......'})
弹窗
状态管理
临时使用
普通变量:只能在初始化渲染,后续不再刷新
状态变量:变量前面添加@State注解,改变会引起UI刷新(必须设置类型和初始值)
let data1: string = '好好学习,天天向上'
@Entry
@Component
struct Index {
data2: string = 'Good good study day day up'
build() {
column() {
Text(data1)
Text(this.data2)
}
}
}
-------------------------------------------------------------------
@Entry
@Component
struct Index {
@State data3: string = '好好学习,天天向上'
build() {
column() {
Text(this.data3)
.onclick(() => {
this.data3 = 'Good good study day day up'
})
}
}
}
普通变量 使用let在外面定义的是全局变量,在struct里面定义的是局部变量,需要使用 this. 引用
状态变量的定义需要使用 @State
struct Index {
name:string = '周易'
@State name2:string = '刘萍'
build() {
Column(){
Text(this.name)
.fontSize(50)
.onClick(()=>{
this.name = '刘咪'
console.log('姓名',this.name)
})
Text(this.name2)
.fontSize(50)
.onClick(()=>{
this.name2 = '刘咪咪'
console.log('姓名',this.name2)
})
}
}
}
专业术语:数据驱动视图
计算案例
@Entry
@Component
struct Index {
@State num:number = 1
build() {
Column(){
Row({space:20}){
Button('-')
.onClick(()=>{
this.num = this.num -1
})
Text(this.num.toString())
Button('+')
.onClick(()=>{
this.num = this.num +1
})
}.padding(30)
}
}
}
算术运算符和赋值运算符
算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余(求模)等
+ — * / %
加 减 乘 除 取余
赋值运算符:对变量进行赋值的运算符
+= -= *= /= %=
加法赋值 减法赋值 乘法赋值 除法赋值 取余赋值
mum = mum +1 可以改为 num+=1
点赞案例
@Entry
@Component
struct test {
@State myColor:string = '#53575a'
@State num:number = 200
build() {
Column(){
Row({space:5}){
Image($r('app.media.ic_public_favor'))
.height(18)
.fillColor(this.myColor)
Text(this.num.toString())
.fontColor('#53575a')
}
.onClick(()=>{
this.myColor = '#ef3751'
this.num+=1
})
}.padding(30)
}
}
一元运算符
++ 和 - -
后置写法:先赋值再自增/自减 num++
前置写法:先自增/自减再赋值 ++num
let num:number = 10
let res1:number = num++
let res2:number = ++num
console.log('res1',res1) // 10
console.log('res2',res2) // 12
比较运算符
作用:用来判断比较两个数据的大小,返回一个布尔值(true / false)
比较运算符 | 作用 |
---|---|
> | 判断大于 |
>= | 判断大于等于 |
< | 判断小于 |
<= | 判断小于等于 |
== | 判断相等 |
!= | 判断不相等 |
let num:number = 10
let num1:number = 11
let num2:string = '10'
let num3:string = '11'
console.log('比较',num<=num1) // 比较 true
console.log('比较',num1.toString()==num3) // 比较 true
console.log('比较',num2!=num3) // 比较 true
逻辑运算符
作用:扩充判断条件
逻辑运算符 | 作用 |
---|---|
&& | 与,都真才真 |
|| | 或,一真则真 |
! | 非,取反 |
let num1:number = 9
let num2:number = 5
let num3:number = 3
console.log('结果1',num1 > num2 && num2 > num3) // true
console.log('结果2',num1 > num2 && num2 < num3) // false
console.log('结果3',num1 > num2 || num2 < num3) // true
console.log('结果4',!(num1 > num2) ) // false
console.log('结果5',!false ) // true
运算符的优先级
优先级 | 顺序 |
---|---|
1 小括号 | ( ) 小括号可以提高优先级 |
2 一元 | ++、–、! |
3 算术 | 先*、/、%后+、- |
4 比较 | >、>=、<、<= |
5 比较 | ==、!= |
6 逻辑运算符 | 先&&后|| |
7 赋值 | = |
数组的操作
主要针对数组中的数据进行 查找、修改、增加、删除
操作 | 语法 |
---|---|
查找 | 数组名[下标]、数组名.length |
修改 | 数组名[下标] = 新值 |
增加 | 数组名.unshift(数据1,数据2,…)、数组名.push(数据1,数据2,…) |
删除 | 数组名.shift( )、数组名.pop( ) |
任意位置增加或删除 | 数组名.splice(操作的起始位置,删除的个数,新增1,新增2,…) |
let names:string[]=['刘备','关羽','张飞','赵云','林黛玉','薛宝钗']
console.log('数组长度',names.unshift('岳云鹏')) // 7
console.log('姓名',names) // 岳云鹏,刘备,关羽,张飞,赵云,林黛玉,薛宝钗
console.log('数组长度',names.push('周瑜','吴邦国')) // 9
console.log('姓名',names) // 岳云鹏,刘备,关羽,张飞,赵云,林黛玉,薛宝钗,周瑜,吴邦国
console.log('删除元素',names.shift()) // 岳云鹏
console.log('姓名',names) // 刘备,关羽,张飞,赵云,林黛玉,薛宝钗,周瑜,吴邦国
console.log('删除元素',names.pop()) // 吴邦国
console.log('姓名',names) // 刘备,关羽,张飞,赵云,林黛玉,薛宝钗,周瑜
names.splice(0,0,'刘萍')
// 新增元素,从下标0开始的,删除0个元素,并且将删除的元素替换为刘萍
names.splice(1,2)
// 删除元素,从下标1开始,删除2个元素
If语句
if(逻辑条件){
条件成立执行的代码
}
if(逻辑条件){
条件成立执行的代码
}
else{
条件不成立执行的代码
}
if(条件1){
条件1成立执行的代码
}
else if (条件2){
条件2成立执行的代码
}
else if (条件3){
条件3成立执行的代码
}
else{
所有条件都不成立执行的代码
}
switch分支
switch(表达式){
case 值1:
与值1匹配,执行的代码
break
case 值2:
与值2匹配,执行的代码
break
default:
以上都未成功匹配,执行的代码
}
注意:如果没有break语句,则会执行switch中的下一个代码块(无论是否匹配成功)
三元条件表达式
语法:条件 ?条件成立执行的表达式 : 条件不成立执行的表达式
let num1:number=2
let num2:number=3
let res:boolean = num1 < num2 ? true : false
console.log('结果是',res)
条件渲染
条件渲染:使用if、else和else if,可基于不同状态渲染对应不同UI内容
@Entry
@Component
struct demo2 {
@State stock: number = 3
build() {
Column() {
if (this.stock < 1) {
Text('该商品暂时没有库存,看看相似商品吧')
}
Row(){
if (this.stock < 1) {
Button('查看类似商品')
}
else {
Button('加入购物车')
Button('立即购买')
}
}
}
}
}
while循环
while(条件){
条件成立重复执行的代码
}
while(true){
console.log('我是死循环')
}
let i:number = 1
while(i<5){
console.log('你好')
i++
}
循环三要素
1.初始值(变量)
2.循环条件
3.变化量(变量计数,自增或自减)
for循环
for(初始值;条件;变化量){
重复执行的代码
}
for(let i:number=0;i<5;i++){
console.log('你好')
}
退出循环
作用:满足指定条件,可以退出循环
break
:终止整个循环
continue
:退出当前循环,继续执行下一次循环
遍历数组
遍历:将数组里面的每个数据,按顺序访问一遍
let names:string[]=['刘备','关羽','张飞','赵云','诸葛亮','曹操']
for (let i:number=0;i<names.length;i++){
console.log('名字',names[i])
}
方法二
语法:for(let item of 数组名){ }
item:声明一个变量,用来在循环的时候接收每一个数组的元素(也可以是其他的变量)
对象数组
// 定义接口
interface Person {
stuId:number
name:string
gender:string
age:number
}
// 基于接口构建对象
let p1:Person = {
stuId:1,
name:'小红',
gender:'女',
age:12
}
// 基于接口构建对象数组
let pArr:Person[] = [
{stuId:1, name:'小红', gender:'女', age:12},
{stuId:2, name:'小明', gender:'男', age:13},
{stuId:3, name:'小王', gender:'男', age:14},
{stuId:4, name:'小美', gender:'女', age:15},
]
// 包括对象的复杂数据,如果想在日志中打印,需要调用一个方法,转换成字符串
// JSON.stringify(复杂类型) 对象/数组
for (let i of pArr){
console.log('元素',i) // 元素 [object Object]
console.log('元素',JSON.stringify(i)) // 元素 {"stuId":1,"name":"小红","gender":"女","age":12}
}
ForEach-渲染控制
ForEach可以基于数组的个数,渲染组件的个数
语法:ForEach ( arr , ( item : 数据类型 , index : 数据类型2 ) => { } )
@Entry
@Component
struct demo3 {
@State titles:string[]=['电子产品','精品服饰','母婴产品','影音娱乐','海外旅游']
build() {
Column(){
ForEach(this.titles,(i:string,index:number)=>{
Text(i)
.fontSize(20)
.fontColor(Color.Red)
})
}
}
}
快速生成长度为10的测试数组
Array.from({length:10})
ForEach的第三个参数
ForEach(this.titles,(item:string,index:number)=>{
......
},(item:string)=>JSON.stringify(item))
特殊情况
ForEach(this.list, (item: photoAccessHelper.PhotoAsset) => {
......
}, (item: photoAccessHelper.PhotoAssetg)=>JSON.stringify(item))
-----------------------------------------------------------------------------
JSON.stringify(item) 拿到的是一个空对象
改成
ForEach(this.list, (item: photoAccessHelper.PhotoAsset) => {
......
}, (item: photoAccessHelper.PhotoAssetg)=>JSON.stringify(item.uri))
----------------------------------------------------------------------------
JSON.stringify() 可以得到唯一的值,就不需要第三个参数
随机数
Math.random() 生成0-1的随机小数
导入导出
在components/index.ets统一导出
export * from ‘./HmCommentItem’
export * from ‘./HmNavBar’
自定义组件 - 成员函数变量
@Component
struct HelloComponent {
// 状态变量
@State msg: string = ''
// 成员变量-数据
info: string = ''
// 成员变量-函数
sayHello = () => {}
// 成员函数
sayHi() {}
build() {
// ...... 描述UI
}
}
@Entry
@Component
struct CustomComponentDemo {
build() {
Column() {
// 使用组件内部定义的初始值
HelloComponent()
// 使用传入的值,覆盖子组件的默认值
HelloComponent({ msg: 'ArkTS', info: '你好' })
// 函数也可以用传入
HelloComponent({sayHello() {console.log('传入的逻辑数据')}})
}
}
}
sayHello = () => {}
这种叫做成员变量,中间有一个等号,可以接收父组件传递过来的函数覆盖(可以外部传入覆盖)
sayHello(){}
这种叫成员函数(不可以f)
ArkTS语言基础
JavaScript >>> TypeScript >>> ArkTS
命名规则
常量名、枚举值 | 全大写,下划线分割 |
变量名、方法名、参数名 | 小驼峰 |
类名、枚举名 | 大驼峰 |
目录 | 小写 |
日志打印
console.log('说明','值')
数据存储(变量、常量)
string
字符串:描述信息
number
数字:计算
boolean
布尔:判断(真、假)
变量
变量:专门用来存储数据的容器
let 变量名:类型 = 值
let title:string = '苹果'
let price:number = 18
console.log('名称:',title,'价格:',price) //名称: 苹果 价格: 18
// 变量修改
title = '橘子'
console.log('名称:',title,'价格:',price) //名称: 橘子 价格: 18
常量
常量:用来存储不可变数据
const 常量名:类型 = 值
const PI:number = 3.1415926
const companyName:string = '华为科技有限公司'
变量命名规则
- 只能包含数字、字母、下划线、$ (不能以数字开头)
- 不能使用内置关键字
- 严格区分大小写 (推荐使用小驼峰)
数组
数组:是一个容器,可以存储多个数据
let 数组名:类型[] = [数据1,数据2,...]
let names:string[] = ['张三','李四','王五']
console.log('名字',names) // 名字 张三,李四,王五
console.log('名字',names[1]) // 名字 李四
数组索引(下标,编号),从0开始。(不支持负数表示)
快速生成长度为10的测试数组
Array.from({length:10})
数组的比较
[ ] === [ ] 两个都是空数组,对比的结果也不一样
数组属于对象
对象之间比较的是内存地址
所以可以把它转换为字符串再比较,(加 .toString())
if(this.list.toString() === input.toString()){
}
list.some(v=> v === ture)
查找里面的值,有没有为ture的,有一项满足,就为ture
函数
函数:可以被重复使用的代码块
// 定义函数
function 函数名(){
函数体
}
// 使用函数
函数名()
带参数的函数
// 定义函数
function 函数名(形参1:类型,形参2:类型,...){
编写代码对数据进行处理
return 处理后的结果
}
// 使用函数
let 变量名:类型 = 函数名(实参1,实参2,...)
箭头函数
箭头函数:是比普通函数更简洁的一种函数写法
let 函数名 = (形参1:类型,形参2:类型)=>{
函数体
return 计算的结果
}
函数名(实参1,实参2)
对比
function aa(d:number,c:number){
return d+c
}
let b:number = aa(1,3)
console.log('结果',b)
let aa = (d:number,c:number)=>{
return d+c
}
let b:number = aa(1,3)
console.log('结果',b)
对象 - 接口
作用:用来描述一个物体的特征和行为
对象:是一个可以存储多个数据的容器
数组只能存储同一类型的值,对象可以存储不同类型的值
let 对象名称:对象结构类型 = {属性名称:值}
interface 接口名 {
属性1:类型1
属性2:类型2
属性3:类型3
}
// 定义接口
interface Person {
name:string
age:number
weight:number
}
Person:人 / weight:体重
// 定义对象
let p:person = {
name:'刘基咪',
age:18,
weight:90,
}
注意:定义对象的时候需要逗号分隔,定义接口不需要
先定义接口,再定义对象,是基于接口定义对象
访问对象
对象名.属性名
// 获取对象的属性值 对象名.属性名
console.log('结果',p.name)
对象-方法
方法的作用:描述对象的具体行为
interface 接口名称 {
方法名:(参数:类型) => 返回值类型
}
interface Person{
name:string
dance:()=>void
sing:(song:string)=>void
}
// 调用
let yqd:Person = {
name:'余承东',
dance:()=>{
console.log(yqd.name,'我叫刘承东')
},
sing:(song:string)=>{
console.log('刘强东说','我叫余强东',song)
}
}
yqd.dance()
yqd.sing('我是家里的顶梁柱')
联合类型
联合类型是一种灵活的数据类型,它修饰的变量可以存储不同类型的数据
let 变量:类型1 | 类型2 | 类型3 = 值
| 可以理解成或的意思
let judge:number|string = 100
judge = 'A+'
judge = '优秀'
联合类型还可以将变量值,从给出的指定值里面选择(比如性别:男,女,保密)
let gender:'man'|'woman'|'secret' = 'secret'
枚举
枚举类型是一种特殊的数据类型,约定变量只能在一组数据范围内选择值
// 定义枚举类型(常量列表)
enum 枚举名 {
常量1 = 值,
常量2 = 值,
...
}
enum ThemeColor{
Red = '#ff0f29',
Orange = '#ff7100',
Green = '#30b30e'
}
// 使用枚举类型,约束变量
let color:ThemeColor = ThemeColor.Red
console.log('颜色',color)
枚举和联合类型的区别
枚举是一种键值对方式存储多个值,联合类型是一个值,可以有多种类型
弹层
import {MyDialog} from './MyDialog'
@Entry
@Component
struct DemoIndex {
// 注册弹层
myDialogController: CustomDialogController = new CustomDialogController({
// 自定义构建
builder: MyDialog(),
// 使用自定义样式
customStyle: true,
// 弹窗从底部开始显示
alignment:DialogAlignment.Bottom
})
build() {
Column() {
Button('打开')
.onClick(() => {
this.myDialogController.open()
})
}
}
}
@CustomDialog
struct MyDialog{
controller:CustomDialogController
build() {
Column(){
Text('我是弹窗')
}
}
}
export {MyDialog}
编辑器(快捷方式)
生成页面(方法一)
@Entry
@Component
struct demo {
build() {
}
}
resources > base > profile > main_pages.json
创建页面会在main-page.json5形成路由,有映射关系,如果删除页面,建议删除对应关系,否则报错
生成页面(方法二)
先新建一个普通文件 ArkTS File,然后再在页面输入entry
使用这种方法添加的页面,不会在main_pages.json
文件中添加路由
实时模板
变量名 变量名 变量名 可以随便取,这里表示的是,这里放一个变量(需要编辑)光标放在这里
variable 就是变量的意思
还可以在编辑变量里面设置变量的默认值
注解
/**
* 检测是否授权
* @param permissionName 权限名称
* @returns -1未授权(abilityAccessCtrl.GrantStatus.PERMISSION_DENIED),0授权了
*/
async checkAccessToken(permissionName:Permissions) {
调用这个方法,鼠标悬停的效果
params:参数的描述,需要先写对应的参数,在参数后面写描述
returns:返回值的描述