
基于ArkUI(方舟开发框架)的页面开发
ArkUI(方舟开发框架)是一套 构建 鸿蒙应用 界面 的框架。
构建页面的最小单位就是 "组件"。
组件分类:
① 基础组件:界面呈现的基础元素。
如:文字Text()、图片、按钮等。
② 容器组件:控制布局排布。
如:Row行、Column列等。
调整组件之间的距离给外层容器组件加 { space: 数字 }
Column({ space: 20}){...}
布局思路
先排版,再放内容。
注意:build有且只能有一个根元素,且是容器组件
排版 → 内容 → 美化
组件
组件的属性方法
需求:美化组件外观效果 → 组件的属性方法
组件() {}
.属性方法1(参数)
.属性方法2(参数)
.属性方法3(参数)
……
Text('小说简介')
.height(40)
.fontSize(20)
……
字体颜色
语法:.fontColor(颜色值)
① 枚举颜色 Color.颜色名
Color.Red、Color.Pink
② #开头的16进制
'#8fbce7' 【设计图会标注】
文字溢出省略号、行高
1. 文字溢出省略 (设置文本超长时的显示方式)
语法:.textOverflow({
overflow: TextOverflow.XXX
})
注意:需要配合 .maxLines(行数) 使用
2. 行高
语法:.lineHeight(数字)
Text('方舟...')
.textOverflow({
overflow: TextOverflow.Ellipsis
})
.maxLines(2)
.lineHeight(30)
Image 图片组件
作用:界面中展示图片
语法:Image(图片数据源) 支持 网络图片资源 和 本地图片资源
Image('url')
Image( $r('app.media.文件名') )
输入框 与 按钮
TextInput(参数)
.属性方法()
1.参数:placeholder提示文本
TextInput({
placeholder: '占位符文本'
})
2. 属性:type(InputType.xxx) 设置输入框 type 类型
① Normal 基本输入模式,无特殊限制
② Password 密码输入模式
TextInput({placeholder: '占位符文本'})
.type(InputType.Password)
Button('按钮文本')
设计资源-svg图标
需求:界面中展示图标 → 可以使用 svg 图标(任意放大缩小不失真、可以改颜色)
使用方式:
1. 设计师提供:基于项目设计的图标,拷贝到项目目录使用
2. 图标库中选取:找合适的图标资源 → 下载(svg) → 拷贝使用
Image($r('app.media.ic_dianpu'))
.width(40)//修改大小
.fillColor('#b0473d')//修改颜色
布局元素的组成
内边距 padding
作用:在 组件内 添加 间距,拉开内容与组件边缘之间的距离
Text('内边距padding')
.padding(20) // 四个方向内边距均为20
Text('内边距padding')
.padding({
top: 10,
right: 20,
bottom: 40,
left: 80
}) // 四个方向内边距分别设置
外边距 margin
作用:在 组件外 添加 间距,拉开两个组件之间的距离
Text('外边距margin')
.margin(20) // 四个方向外边距均为20
Text('外边距margin')
.margin({
top: 10,
right: 20,
bottom: 40,
left: 80
}) // 四个方向内边距分别设置
边框 border
作用:给组件添加边界,进行装饰美化。
Text('边框语法')
.border({
width: 1, // 宽度
color: '#3274f6', // 颜色
style: BorderStyle.Solid // 样式
}) // 四个方向相同
Text('边框语法')
.border({
width: { left: 1 },
color: { left: 'red' },
style: { left: BorderStyle.Dashed }
}) // top、right、bottom、left
设置组件圆角
属性:.borderRadius(参数)
参数:数值 或 对象 (四个角单独设置)
topLeft:左上角
topRight:右上角
bottomLeft:左下角
bottomRight:右下角
Text('圆角语法')
.borderRadius(5) // 四个圆角相同
.borderRadius({
topLeft: 5,
topRight: 10,
bottomRight: 15,
bottomLeft: 20
}) // 四个方向圆角,单独设置
特殊形状的圆角设置
1. 正圆
Text('正圆')
.width(100) // 宽度高度一样
.height(100)
.borderRadius(50) // 圆角是宽或高的一半
2. 胶囊按钮(左右半圆)
Text('胶囊按钮')
.width(150) // 宽度大,高度小
.height(50)
.borderRadius(25) // 圆角是高的一半
背景属性
背景图 - backgroundImage
属性:.backgroundImage(背景图地址)
Text()
.backgroundImage($r('app.media.flower'))
背景图平铺方式-枚举ImageRepeat
背景图平铺方式:(可省略)
NoRepeat:不平铺,默认值
X:水平平铺
Y:垂直平铺
XY:水平垂直均平铺
Text('我是文本')
.backgroundImage($r('app.media.flower'),ImageRepeat.XY)
背景图位置 - backgroundImagePosition
作用:调整背景图在组件内的显示位置,默认显示位置为组件左上角
属性:.backgroundImagePosition(坐标对象 或 枚举)
参数:
位置坐标: { x: 位置坐标, y: 位置坐标 } (单位下一节详细说)
枚举 Alignment
Text()
.backgroundImage($r('app.media.flower'))
.backgroundImagePosition({ x: 100, y:100 })
.backgroundImagePosition(Alignment.Center)
背景图尺寸 - backgroundImageSize
作用:背景图缩放
属性:.backgroundImageSize(宽高对象 或 枚举)
参数:
背景图宽高:{ width: 尺寸, height: 尺寸 }
枚举 ImageSize:
Contain:等比例缩放背景图,当宽或高与组件尺寸相同停止缩放
Cover:等比例缩放背景图至图片完全覆盖组件范围
Auto:默认,原图尺寸
Text()
.backgroundImage($r('app.media.flower'))
.backgroundImageSize({ width: 250, height: 100 })
.backgroundImageSize(ImageSize.Cover)
单位问题
背景定位默认单位 → px:实际的物理像素点,设备出厂,就定好了【分辨率单位】
宽高默认单位 → vp:虚拟像素,相对于不同的设备会自动转换,保证不同设备视觉一致 (推荐)
函数:vp2px(数值) 将vp进行转换,得到px的数值
Badge 角标组件
Badge({
count: 1, // 角标数值
position: BadgePosition.RightTop, // 角标位置
style: {
fontSize: 12, // 文字大小
badgeSize: 16, // 圆形大小
badgeColor: '#FA2A2D' // 圆形底色
}
}) {
Image($r('app.media.bg_01'))
.width(80)
}
类似于消息产生的小红点
Swiper 轮播组件
Swiper是一个 容器组件,当设置了多个子组件后,可以对这些 子组件 进行轮播显示。(文字、图片...)
Swiper 的基本用法
语法结构:
Swiper() {
// 1. 轮播内容
Text('1')
Text('2')
Text('3')
}
// 2. 设置尺寸(内容会自动拉伸)
.width('100%')
.height(100)
Swiper() {
// 1. 轮播内容
Image($r('...'))
Image($r('...'))
Image($r('...'))
}
// 2. 设置尺寸(内容会自动拉伸)
.width('100%')
.height(100)
Swiper 的常见属性
Swiper 样式自定义
Swiper() {
...
}
.indicator(
Indicator.dot() // 小圆点
.itemWidth(20) // 默认的宽
.itemHeight(20) // 默认的高
.color(Color.Black) // 默认的颜色
.selectedItemWidth(30) // 选中的宽
.selectedItemHeight(30) // 选中的高
.selectedColor(Color.White) // 选中的颜色
)
样式&结构重用
@Extend:扩展组件(样式、事件)
@Styles: 抽取通用属性、事件
@Builder:自定义构建函数(结构、样式、事件)
@Extend:扩展组件(样式、事件)
可以将
Swiper() {
Text('1')
.textAlign(TextAlign.Center)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.fontSize(30)
.onClick(() => {
AlertDialog.show({
message: '轮播图 1'
})
})
Text('2')
.textAlign(TextAlign.Center)
.backgroundColor(Color.Orange)
.fontColor(Color.White)
.fontSize(30)
.onClick(() => {
AlertDialog.show({
message: '轮播图 2'
})
}) ...
}
优化为
@Extend(Text)
function textExtend(color: ResourceColor, txt: string) {
.textAlign(TextAlign.Center)
.backgroundColor(color)
.fontColor(Color.White)
.fontSize(30)
.onClick(() => {
AlertDialog.show({
message: txt
})
})
}
Swiper() {
Text('1')
.textExtend(Color.Red, '轮播图1')
Text('2')
.textExtend(Color.Orange, '轮播图2')
Text('3')
.textExtend(Color.Grey, '轮播图3')
}
@Styles: 抽取通用属性、事件
可以将
Text(this.message)
.width(100)
.height(100)
.backgroundColor(this.bgColor)
.onClick(() => {
this.bgColor = Color.Orange
})
Button('按钮')
.width(100)
.height(100)
.backgroundColor(this.bgColor)
.onClick(() => {
this.bgColor = Color.Orange
})
Column() {}
.width(100)
.height(100)
.backgroundColor(this.bgColor)
.onClick(() => {
this.bgColor = Color.Orange
})
优化为
// 1. 全局定义
@Styles function commonStyles() {
.width(100)
.height(100)
.onClick(()=>{
// ...
})
}
@Component
struct FancyDemo {
// 2. 在组件内定义
@Styles setBg() {
.backgroundColor(Color.Red)
}
builder(){
Text()
.commonStyles()
.setBg()
}
}
@Builder:自定义构建函数(结构、样式、事件)
可以将
Row() {
Column({ space: 10 }) {
Image($r('app.media.ic_reuse_01')).width('80%')
Text('阿里拍卖')
}
.width('25%')
.onClick(() => {
AlertDialog.show({
message: '点了 阿里拍卖'
})
})
Column({ space: 10 }) {
Image($r('app.media.ic_reuse_02')).width('80%')
Text('菜鸟')
}
.width('25%')
.onClick(() => {
AlertDialog.show({
message: '点了 菜鸟'
})
})
}
优化为
// 全局 Builder
@Builder
function navItem(icon: ResourceStr, text: string) {
Column({ space: 10 }) {
Image(icon)
.width('80%');
Text(text);
}
.width('25%')
.onClick(() => {
AlertDialog.show({
message: '点了' + text
})
})
}
Row() {
navItem($r('app.media.ic_reuse_01'),'阿里拍卖')
navItem($r('app.media.ic_reuse_02'),'菜鸟')
}
局部 builder 类似,只是定义在组件内,this.xxx()
滚动容器 Scroll
滚动容器 Scroll
当子组件的布局尺寸 超过Scroll的尺寸 时,内容可以滚动
滚动容器 Scroll – 核心用法
用法说明:
1. Scroll 设置尺寸
2. 设置溢出的子组件(只支持一个子组件)
3. 滚动方向(支持横向和纵向,默认纵向)
Scroll(){
// 只支持一个子组件
Column(){
// 内容放在内部
// 尺寸超过 Scroll 即可滚动
}
}
.width('100%')
.height(200)
.scrollable(ScrollDirection.xxx)
滚动容器 Scroll – 常见属性
滚动容器 Scroll – 控制器
核心步骤:
1. 实例化 Scroller 的 控制器
2. 绑定给 Scroll 组件
3. 控制器的方法 控制滚动,控制器属性 获取滚动距离
struct ScrollDemo {
scroller: Scroller = new Scroller()
build() {
Column() {
Scroll(this.scroller) { ... }
Row() {
Button('返回顶部')
.onClick(() => {
this.scroller.scrollEdge(Edge.Top)
})
Button('获取滚动距离')
.onClick(() => {
const x = this.scroller.currentOffset().xOffset
const y = this.scroller.currentOffset().yOffset
AlertDialog.show({
message:`x:${x},y:${y}`
})
})
}
}
}
}
滚动容器 Scroll – Scroll 事件
Scroll 组件提供了一些事件,让开发者可以在适当的时候添加逻辑
Scroll(){
// 内容略
}
.onScroll((x,y)=>{
// 滚动时 一直触发
// 可以结合 scroller的currentOffset方法 获取滚动距离
})
容器组件 Tabs
容器组件 Tabs
当页面内容较多时,可以通过Tabs组件进行 分类展示
容器组件 Tabs – 基本用法
struct TabbarDemo {
build() {
// 外层顶级容器
Tabs() {
TabContent() {
// 内容区域:只能有一个子组件
Text('首页内容')
}
.tabBar('首页') // 导航栏
TabContent() {
Text('推荐内容')
}
.tabBar('推荐')
...
}
}
}
容器组件 Tabs – 常用属性
barPosition :调整位置 开头 或 结尾 (参数)
vertical :调整导航 水平 或 垂直
scrollable :调整是否 手势滑动 切换
animationDuration :点击滑动动画时间
// BarPosition.Start 起始
// BarPosition.End 结尾
Tabs({ barPosition: BarPosition.End }) {
// 内容略
}
.vertical(true)// 垂直导航 true / 水平false
.scrollable(true) // 允许滑动 true / 不允许 false
.animationDuration(0) // 切换动画的时间,毫秒
容器组件 Tabs – 滚动导航栏、
如果导航栏的内容较多,屏幕无法容纳时,可以将他设置为滚动
可以通过 Tabs 组件的 barMode 属性即可调整 固定导航栏 或 滚动导航栏
Tabs(){
// 内容略
}
.barMode(BarMode.Scrollable)// 滚动
// .barMode(BarMode.Fixed)// 默认值
容器组件 Tabs – 自定义TabBar – 基础结构
TabBar 在底部,一般会显示 图形 和 文字,甚至有 特殊的图标
Tabs() {
TabContent() {
// 内容略
}
.tabBar(this.tabBarBuilder())
}
@Builder
tabBarBuilder() {
// 自定义的Tabbar结构
}
容器组件 Tabs – 自定义TabBar – 高亮切换
核心思路:
1. 监听切换事件 → 得到索引值,记录高亮的索引
2. 给每个 tabBar起个标记,0,1,2
3. 在 tabBar 内部比较 标记 == 记录的索引 ? 高亮 : 不高亮
自定义组件 - 基础
自定义组件 - 基本使用
概念:由框架直接提供的称为 系统组件,由开发者定义的称为 自定义组件
@Entry
@Component
struct Index {
build() {
Column() {
Text('系统组件')
// 自定义组件
HelloComponent()
HelloComponent()
}
}
}
// 定义
@Component
struct HelloComponent {
// 状态变量
@State message:string =''
build(){
// .... 描述 UI
}
}
自定义组件 - 通用样式事件
自定义组件可以通过点语法,设置 通用样式, 通用事件
如果想要单独预览组件,可以使用 @Preview 进行装饰
@Entry
@Component
struct Index {
build() {
Column() {
HelloComponent()
.width(200)
.height(100)
.backgroundColor(Color.Orange)
.onClick(() => {
console.log('外部添加的点击事件')
})
}
}
}
@Preview
@Component
export struct HelloComponent {
@State info: string = '默认info'
build() {
Row() {
Text(this.info)
Button('修改数据')
}
}
}
自定义组件 – 成员函数变量
除了必须要实现 build() 函数外,还可以定义其他的成员函数,以及成员变量。
成员变量的值 → 外部可传参覆盖
@Component
struct HelloComponent {
// 状态变量
@State msg:string = ''
// 成员变量-数据
info:string = ''
// 成员变量-函数
sayHello = () => {}
// 成员函数
sayHi(){}
build(){
// .... 描述 UI
}
}
@Entry
@Component
struct CustomComponentDemo {
build() {
Column() {
// 使用组件内部定义的初始值
HelloComponent()
// 使用传入的值,覆盖子组件的默认值
HelloComponent({ info: '你好', msg: 'ArkTS' })
// 函数也可以传入
HelloComponent({ sayHello(){ console.log('传入的逻辑') } })
}
}
}
@BuilderParam 传递UI
利用 @BuilderParam 构建函数,可以让自定义组件 允许外部传递 UI。
@Entry
@Component
struct Index {
build() {
Column({ space: 15 }) {
SonCom() {
// 直接传递进来(尾随闭包)
Button('待付款')
}
}
}
}
@Component
struct SonCom {
// 1.定义 BuilderParam 接受外部传入的 ui, 并设置默认值
@BuilderParam ContentBuilder: () => void = this.defaultBuilder
// 默认 的 Builder
@Builder
defaultBuilder() {
Text('默认的内容')
}
build() {
Column() {
// 2. 使用 @BuilderParam 装饰的成员变量
this.ContentBuilder()
}
}
}
多个 @BuilderParam 参数
子组件有多个BuilderParam,必须通过参数的方式来传入
@Component
struct SonCom {
// 由外部传入 UI
@BuilderParam tBuilder: () => void = this.tDefaultBuilder
@BuilderParam cBuilder: () => void = this.cDefaultBuilder
// 设置默认 Builder
@Builder
tDefaultBuilder() { ... }
@Builder
cDefaultBuilder() { ... }
build() {
Column() {
this.tBuilder()
this.cBuilder()
}
}
}
@Entry
@Component
struct Index {
@Builder
fTBuilder() { ... }
@Builder
fCBuilder() { ... }
build() {
Column({ space: 15 }) {
SonCom({
tBuilder: this.fTBuilder,
cBuilder: this.fCBuilder
})
}
}
}
布局
线性布局
线性布局(LinearLayout)通过线性容器 Column 和 Row 创建。
Column 容器:子元素 垂直方向 排列
Row 容器:子元素 水平方向 排列
排布主方向上的对齐方式 (主轴)
属性:.justifyContent(枚举FlexAlign) (Row 组件的 justifyContent 属性效果相似)
交叉轴对齐方式
属性:alignItems()
参数:枚举类型
交叉轴在水平方向:HorizontalAlign
交叉轴在垂直方向:VerticalAlign
交叉轴对齐方式:
alignItems()
自适应伸缩
设置 layoutWeight 属性的 子元素 与 兄弟元素,会 按照权重 进行分配 主轴 的 空间 (剩余空间)
语法:.layoutWeight(数字)
Row() {
Text('左侧')
.layoutWeight(1)
.height(50)
.backgroundColor(Color.Pink)
Text('右侧')
.width(70)
.height(50)
.backgroundColor(Color.Orange)
}
弹性布局(Flex)
参数对象:
1. 主轴方向:direction
2. 主轴对齐方式:justifyContent
3. 交叉轴对齐方式:alignItems
4. 布局换行:wrap
单行或者单列: 优先使用线性布局(基于Flex设计,做了性能优化)
wrap 属性:换行
1. FlexWrap.NoWrap 单行布局
2. FlexWrap.Wrap 多行布局
Flex({
wrap: FlexWrap.Wrap
})
绝对定位
作用:控制组件位置,可以实现层叠效果
特点:
1. 参照 父组件左上角 进行偏移
2. 绝对定位后的组件 不再占用自身原有位置
语法:.position(位置对象)
参数:{ x: 水平偏移量, y: 垂直偏移量 }
Text('文字内容')
.position({
x: 0,
y: 0
})
zIndex 层级
作用:调整组件层级
语法:.zIndex(数字)
参数:取值为整数数字,取值越大,显示层级越高
层叠布局
层叠布局
层叠布局具有较强的组件层叠能力。场景:卡片层叠效果等
特点:层叠操作更简洁,编码效率高。(绝对定位的优势是更灵活)
Stack 容器内的⼦元素的顺序为 Item1 -> Item2 -> Item3
Stack() {
Item1()
Item2()
Item3()
}
特点:层叠操作更简洁,编码效率高。(绝对定位的优势是更灵活)
Grid 布局
GridItem() {
Badge({
count: 1,
position: BadgePosition.RightTop,
style: {
fontSize: 14,
badgeSize: 20,
badgeColor: '#fa2a2d'
}
}) {
Image($r('app.media.bg_01'))
.width(80)
}
}
交互
点击事件
交互 – 点击事件
说明:组件 被点击时 触发的事件
作用:监听(感知)用户 点击行为,进行对应操作
语法:onClick( (参数) => {} )
Button('点我, 显示弹框')
.onClick(() => {
AlertDialog.show({
message: '你好-这是个弹框'
})
})
状态管理
之前构建的页面多为静态界面。
但如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念
点击交互 触发了 文本状态变更,状态变更 引起了 UI渲染
普通变量:只能在初始化时渲染,后续将不会再刷新。
let msg1: string = 程序员'
@Entry
@Component
struct Index {
msg2: string = '学鸿蒙'
build() {
Column() {
Text(msg1)
Text(this.msg2)
}
}
}
状态变量:需要装饰器装饰,改变会引起 UI 的渲染刷新 (必须设置 类型 和 初始值)
@Entry
@Component
struct Index {
@State msg3: string = 'Hello World'
build() {
Column() {
Text(this.msg3).onClick(() => {
this.msg3 = '你好, 世界'
})
}
}
}
注意:定义在 组件内 普通变量 或 状态变量,都需要 通过 this 访问
@State 自己的状态
注意:不是状态变量的所有更改都会引起刷新。只有可以被框架观察到的修改才会引起UI刷新。
1. boolean、string、number类型时,可以观察到数值的变化
2. class或者Object时,可观察 自身的赋值 的变化, 第一层属性赋值的变化,即Object.keys(observedObject) 返回的属性。
// 状态变量
@State message: string = 'Hello, World!';
@State person: Person = {
name: 'jack',
dog: {
name: '柯基'
}
}
Button('修改title外层属性')
.onClick(() => {
this.person.name = '666'
})
Button('修改title嵌套属性')
.onClick(() => {
// 无法触发更新
// this.person.dog.name = '内部的 666'
this.person.dog = {
name: '阿拉斯加'
}
})
@Prop - 父子单向
@Prop 装饰的变量可以和父组件建立单向的同步关系。
@Prop 装饰的变量是可变的,但是变化不会同步回其父组件
@Entry
@Component
struct FatherCom {
@State info: string = '么么哒'
build() {
Column() {
Text(this.info)
SonCom({
info: this.info,
changeInfo: (newInfo: string) => {
this.info = newInfo
}
})
}
}
}
@Component
struct SonCom {
@Prop info: string
changeInfo = (newInfo: string) => {
}
build() {
Button('info:' + this.info)
.onClick(() => {
this.changeInfo('改啦')
})
}
}
@Link 双向同步
使用 @Link 可以实现父组件和子组件的 双向同步:
使用步骤:
1. 将父组件的状态属性传递给子组件
2. 子组件通过@Link修饰即可
3. 分别测试基础,和复杂类型
@Provide、@Consume后代组件
将数据传递给后代,和后代的数据进行双向同步
使用步骤:
1. 将父组件的状态属性使用 @Provide 修饰
2. 子组件通过 @Consume 修饰
3. 分别测试 基础 和 复杂 类型
@Observed & @ObjectLink 嵌套对象数组 属性变化
说明:装饰器仅能观察到 第一层 的变化。对于多层嵌套的情况,比如 对象数组 等。
他们的第二层的属性变化是无法观察到的。这就引出了@Observed/@ObjectLink装饰器。
作用:用于在 涉及嵌套对象 或 数组 的场景中进行 双向数据同步
注意:ObjectLink修饰符不能用在 Entry 修饰的组件中
路由
页面路由指的是在应用程序中实现 不同页面之间的跳转,以及数据传递。
路由 – 1. 创建页面
① 直接右键新建Page
② 新建普通ets文件,配置成页面
新建普通页面 pages/DetailPage.ets
文件位置 → main_pages.json
路由 – 2. 页面跳转 和 后退
// 导入
import router from '@ohos.router';
// 1.调用方法 - 普通跳转(可以返回)
router.pushUrl({
url:'页面地址'
})
// 2.调用方法 - 替换跳转(无法返回)
router.replaceUrl({
url:'页面地址'
})
// 3.调用方法 - 返回()
router.back()
路由 – 3. 页面栈
页面栈是用来存储程序运行时页面的一种 数据结构,遵循 先进后出 的原则
页面栈的最大容量为 32 个页面
// 获取页面栈长度
router.getLength()
// 清空页面栈
router.clear()
路由 – 4. 路由模式
路由提供了两种不同的跳转模式
1. Standard:无论之前是否添加过,一直添加到页面栈【默认常用】
2. Single:如果目标页面已存在,会将已有的最近同url页面移到栈顶【看情况使用】
// 在第二个参数设置 【路由模式】
router.pushUrl(options, mode)
路由 – 5. 路由传参
日常开发中有这样的场景:点击不同的电影,商品,标题等,需要跳转到与之对应的详情页面
router.pushUrl({
url:'地址',
params:{
// 以对象的形式传递参数
}
})
// -------------页面 B接收并解析参数------------
aboutToAppear(): void {
// 1.确认内容
console.log(JSON.stringify(router.getParams()))
// 2.通过 as 类型断言 转为具体的类型
const params = router.getParams() as 类型
// 3. 通过点语法即可取值
params.xxx
}
ForEach-渲染控制
ForEach 可以基于数组的个数,渲染组件的个数。(简化代码)
语法: ForEach(arr, (item, index) => {})
@State titles:string[] = ['电子产品', '精品服饰', '母婴产品',
'影音娱乐', '海外旅游']
build() {
Column() {
ForEach(this.titles, (item: string, index) => {
Text(item)
.fontSize('24')
.fontWeight(700)
.fontColor(Color.Orange)
.width('100%')
.padding(15)
})
}
}
生命周期
组件 和 页面 在创建、显示、销毁的这一整个过程中,会自动执行 一系列的【生命周期钩子】
其实就是一系列的【函数】,让开发者有机会在特定的阶段运行自己的代码
区分 页面 和 组件:@Entry
aboutToAppear:创建组件实例后执行,可以修改状态变量
aboutToDisappear:组件实例销毁前执行,不允许修改状态变量
onPageShow:页面每次显示触发(路由过程、应用进入前后台)
onPageHide:页面每次隐藏触发(路由过程、应用进入前后台)
onBackPress:点击返回触发(return true 阻止返回键默认返回效果)
仅@Entry修饰的页面组件生效
Stage模型
应用模型 是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制
简而言之:应用模型就是 应用的施工图纸, 他规范化了: 程序运行流程、项目结构、文件功能等...
了解应用模型之后,就可以知道:
1. 实现某个功能需要在哪个文件编码
2. 如何感知应用的 状态变化(启动、关闭、切后台)
3. 如何调整项目配置
...
随着系统的演进发展,先后提供了两种应用模型:
1. FA 模型:从API 7开始支持的模型,已经 不再主推
2. Stage 模型:从API 9开始新增的模型,是目前 主推且会长期演进的模型
ArkTS 中每个 ets 文件,都可以看做是一个模块
AppScope > app.json5:应用的全局配置信息。
• entry:HarmonyOS工程模块,编译构建生成一个HAP包。
• src > main > ets:用于存放ArkTS源码。
• src > main > ets > entryability:应用/服务的入口。
• src > main > ets > pages:应用/服务包含的页面。
• src > main > resources:用于存放应用/服务所用到的资源文件。
• src > ain > module.json5:模块应用配置文件。
• build-profile.json5:当前的模块信息 、编译信息配置项,包括buildOption、targets配置等。
• hvigorfile.ts:模块级编译构建任务脚本,开发者可以自定义相关任务和代码实现。
• obfuscation-rules.txt:混淆规则文件。。
• oh_modules:用于存放三方库依赖信息。
• build-profile.json5:应用级配置信息,包括签名signingConfigs、产品配置products等。。
• hvigorfile.ts:应用级编译构建任务脚本。
Stage模型 – app.json5 应用配置
应用配置在工程的 AppScope 目录下的 app.json5 配置文件中
{
"app": {
"bundleName": "包名 不可省略",
"vendor": "应用开发厂商描述 不可省略",
"versionCode": 版本号,数值越大版本越高,
"versionName": "给用户看的版本号",
"icon": "应用图标",
"label": "应用名"
}
}
Stage模型 – module.json5 模块配置
module.json5 配置文件,配置 ability 入口图标 和 标签配置
{
"module": {
...
"abilities": [
{
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
}
...
]
}
}
Stage模型 - UIAbility 组件
每一个UIAbility实例,都对应于一个最近任务列表中的任务。
UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。
一个应用可以有一个 UIAbility 也可以有多个 UIAbility
单 UIAbility:任务列表只有一个任务。
多 UIAbility:在任务列表中会有多个任务。
相关知识点:
UIAbilitiy 配置启动页面
UIAbilitiy 生命周期
UIAbilitiy 组件间交互
Stage模型 - UIAbility 组件的生命周期
当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。
onCreate: Ability创建时回调,执行初始化业务逻辑操作。
onDestory: Ability销毁时回调,执行资源清理等操作。
onForeground: 当应用从后台转到前台时触发。
onBackground: 当应用从前台转到后台时触发
模块化语法
模块化基本认知
模块化:把一个大的程序,【拆分】成若干的小的模块,通过【特定的语法】,可以进行任意组合
默认导出和导入
默认导出:指一个模块,只能默认导出的 一个值 或 对象。使用时,可以 自定义 导入名称。
使用步骤:
1. 当前模块中 导出模块
2. 需要使用的地方 导入模块
// 默认导出
export default 需要导出的内容
// 默认导入
import xxx from '模块路径'
按需导出和导入
按需导出:指一个模块,可以按照需要,导出多个特性。
// 逐个导出单个特性
export let name1 = …, name2 = …, …, nameN;
export function FunctionName(){...}
export class ClassName {...}
// 一次性导出
export { name1, name2, …, nameN };
// --------------------------------
// 导入
import { name1, name2, name3 as 别名 } from "module-name";
全部导入
将所有的按需导入,全部导入进来 → 导出部分不需要调整,调整导入的语法即可
import * as Utils from './utils'
// 通过 Utils 即可获取 utils模块中导出的所有内容