鸿蒙开发
编辑器
目录结构

布局组件
ts
@Entry // 应用入口的标识
@Component // 组件标识
struct Index {
@State message: string = 'hello harmonyOS';
build() {
Column(){
Text(this.message)
.fontColor(Color.Red)
.fontSize(40)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
js
// 横向布局容器
Row()
.width() // 宽度
.height() // 高度
.margin({left: 10, right: 10, top: 10, bottom: 10}) // margin
.padding({left: 10, right: 10, top: 10, bottom: 10}) // padding
.border({ // 边框
width: 1,
color: Color.Black
})
.backgroundColor('#000000') // 背景颜色
.backgroundImage($r('app.media.startIcon')) // 背景图片
.backgroundImageSize(ImageSize.Auto) // 背景图片尺寸
// Auto
// Cover 占满容器,剪裁
// Contain 占满容器,不剪裁,保证完整显示
.justifyContent(FlexAlign.Center) // 横向对齐方式(FlexAlign 枚举)
// Start
// Center
// End
// SpaceBetween
// SpaceAround
// SpaceEvenly
.alignItems(HorizontalAlign.Center) // 纵向对齐方式(HorizontalAlign 枚举)
// Start
// Center
// End
// 纵向布局容器
Column()
基本组件
js
// 文本,相当于\<span>
Text()
.fontColor(Color.Blue) // 字体颜色(Color 枚举)
// '#ff7400'
// 'rgb(0,0,0)'
// White
// Black
// Blue
// Brown
// Gray
// Green
// Grey
// Orange
// Pink
// Red
// Yellow
// Transparent
.fontSize(24) // 字体大小
.fontWeight(600) // 字重
.textAlign(TextAlign.Center) // 水平方向对齐方式
// Start
// Center
// End
Button('按钮')
TextInput({placeholder: '输入框'})
Radio({value: '1', group: 'sex'}) // 单选框
// value 绑定值
// group 单选框组
.radioStyle({})
// uncheckedBorderColor 未选中时的颜色
// checkedBackgroundColor 选中时的颜色
.onChange((isChecked) => {}) // 是否选中
// 分割线
Line()
方法组件
ts
// 日历选择弹窗
CalendarPickerDialog.show({
selected: new Date(),
onChange: (date) => {
console.log(JSON.stringify(date))
}
})
// selected 当前日期默认选中
// backgroundColor 弹窗背景颜色
// acceptButtonStyle 确认按钮样式
// cancelButtonStyle 取消按钮样式
// onChange 选中回调
// onAccept 确认回调
// onCancel 取消回调
// onDidAppear 弹窗弹出回调
// onDidDisappear 弹窗消失回调
// onWillAppear 弹窗动效前回调
// onWillDisappear 弹窗退出动效前回调
ts
// 时间选择器
this.getUIContext().showTimePickerDialog() // 官方推荐使用方式
TimePickerDialog.show({
useMilitaryTime: true,
})
// useMilitaryTime 是否为24小时制(默认为12小时制)
// disappearTextStyle 设置所有选项中最上和最下两个选项的样式
// textStyle 设置所有选项中除了最上、最下及选中项以外的选项样式
// selectedTextStyle 设置选中项的样式
// acceptButtonStyle 确认按钮样式
// cancelButtonStyle 取消按钮样式
// alignment 弹窗在竖直方向上的对齐方式
// offset 相对alignment的偏移量
// backgroundColor 弹窗背景颜色
// onChange 选中回调
// onAccept 确认回调
// onCancel 取消回调
// onDidAppear 弹窗弹出回调
// onDidDisappear 弹窗消失回调
// onWillAppear 弹窗动效前回调
// onWillDisappear 弹窗退出动效前回调
ts
// 警告弹窗
this.getUIContext().showAlertDialog() // 官方推荐使用方式
AlertDialog.show({
title: '警告弹窗',
message: 'warning',
})
// title 标题
// subtitle 副标题
// message 内容
// autoCancel 遮罩层是否可关闭弹窗(默认true)
// cancel 遮罩层关闭回调
// alignment 弹窗在竖直方向上的对齐方式
// offset 相对alignment所在位置的偏移量
// gridCount 宽度所占用栅格数(默认4)
滚动组件 Scroll()
ts
@Entry
@Component
struct Index {
scroller: Scroller = new Scroller()
arr: number[] = [0,1,2,3,4,5,6,7,8,9]
build() {
Scroll(this.scroller){
// Scroll 里只能有一个子元素
Column({space: 10}){
ForEach(this.arr, (item: number) => {
Text((item + 1).toString())
.width('100%')
.height(100)
.backgroundColor('#fff')
}, (item: string) => item)
}
}
.backgroundColor('#fff5f5f5')
.scrollable(ScrollDirection.Vertical) // 滚动方向
.scrollBar(BarState.On) // 是否显示滚动条
.scrollBarColor(Color.Gray) // 滚动条颜色
.scrollBarWidth(6) // 滚动条宽度
.edgeEffect(EdgeEffect.Spring) // 滚定到边界的交互效果
// 滚动前事件
.onWillScroll((xOffset: number, yOffset: number) => {
// console.log(`xOffset: ${xOffset} yOffset: ${yOffset}`)
})
// 滚动后事件
.onDidScroll((xOffset: number, yOffset: number) => {
console.log(`xOffset: ${xOffset} yOffset: ${yOffset}`)
})
// 滚动到边缘事件
.onScrollEdge((side: Edge) => {
console.log(`side: ${side}`)
})
// 滚动停止事件
.onScrollStop(() => {
console.log('滚动停止')
})
}
}
ts
// 实例化一个控制器对象
scroller: Scroller = new Scroller()
Scroll(this.scroller)
.scrollable(ScrollDirection.Vertical) // 滚动方向
// Vertical 纵向
// Horizontal 横向
// None
.scrollBar(BarState.On) // 是否显示滚动条
// On
// Off
// Auto
.scrollBarColor(Color.Gray) // 滚动条颜色
.scrollBarWidth(6) // 滚动条宽度
.friction(0.6) // 摩擦系数(有默认值)
.edgeEffect(EdgeEffect.Spring) // 滚定到边界的交互效果
// None
// Fade 圆弧形阴影
// Spring 一段空白区域
.onWillScroll((xOffset, yOffset) => {}) // 滚动前事件
// xOffset yOffset 预估值
.onDidScroll((xOffset, yOffset, scrollState) => {}) // 滚动后事件
// xOffset yOffset 滚动完成后相对于滚动前的偏移量
.onScrollEdge((side) => {}) // 滚动到边缘事件
.onScrollStop() // 滚动停止事件
// 定位到往下100的位置(没有动画)
this.scroller.scrollBy(0, 100)
// 滚动指定距离(可以设置动画,需要在当前位置上加上滚动距离)
const yOffset:number = this.scroller.currentOffset().yOffset
this.scroller.scrollTo({
xOffset: 0,
yOffset: yOffset + 100,
animation: {duration: 500}
})
层叠组件 Stack()
可以实现定位效果,子元素通过
zIndex
实现层级
ts
@Entry
@Component
struct Index {
@State count:number = 1
build() {
Stack({alignContent: Alignment.BottomEnd}){
// 容器
Column(){
Text(`count: ${this.count}`)
}
.zIndex(1)
.width('100%')
.height('100%')
.backgroundColor('#fafafa')
// 定位元素
Button('+')
.zIndex(2)
.height(40)
.fontSize(20)
.margin({right: 40, bottom: 60})
.onClick(() => {
this.count = this.count + 1
})
}
.width('100%')
.height('100%')
}
}
ts
Stack({alignContent: Alignment.BottomEnd}) // alignContent 对齐方式(Alignment 枚举)
// TopStart
// Top
// TopEnd
// Start
// Center
// End
// BottomStart
// Bottom
// BottomEnd
相对布局组件 RelativeContainer()

相对定位,需要一个参照元素,默认
__container__ (父元素)
,可以给其他元素添加.id()
定位元素的哪条边 和 参照元素的哪条边 重叠
ts
@Extend(Column) function columnStyle(color: Color[], index:number) {
.width(100)
.height(100)
.backgroundColor(color[index])
}
@Entry
@Component
struct Index {
color:Color[] = [Color.Yellow, Color.Brown, Color.Pink, Color.Green, Color.Orange, Color.Grey]
build() {
RelativeContainer(){
// 第一个元素
Column(){ Text(`1`) }
.id('column1')
.columnStyle(this.color, 0)
.alignRules({
top: {anchor: '__container__', align: VerticalAlign.Top},
left: {anchor: '__container__', align: HorizontalAlign.Start}
})
// 第二个元素
Column(){ Text(`2`) }
.columnStyle(this.color, 1)
.alignRules({
top: {anchor: '__container__', align: VerticalAlign.Top},
right: {anchor: '__container__', align: HorizontalAlign.End}
})
// 第三个元素
Column(){ Text(`3`) }
.columnStyle(this.color, 2)
.alignRules({
middle: {anchor: '__container__', align: HorizontalAlign.Center},
center: {anchor: '__container__', align: VerticalAlign.Center}
})
// 第四个元素
Column(){ Text(`4`) }
.columnStyle(this.color, 3)
.alignRules({
bottom: {anchor: '__container__', align: VerticalAlign.Bottom},
left: {anchor: '__container__', align: HorizontalAlign.Start}
})
// 第五个元素
Column(){ Text(`5`) }
.columnStyle(this.color, 4)
.alignRules({
bottom: {anchor: '__container__', align: VerticalAlign.Bottom},
right: {anchor: '__container__', align: HorizontalAlign.End}
})
// 第六个元素
Column(){ Text(`6`) }
.columnStyle(this.color, 5)
.alignRules({
top: {anchor: 'column1', align: VerticalAlign.Center},
left: {anchor: 'column1', align: HorizontalAlign.Center}
})
}
.width(300)
.height(300)
.border({
width: 1,
color: Color.Black
})
}
}
ts
RelativeContainer() // 相对定位组件
.alignRules({top, bottom, left, right})
// anchor 参照元素(__container__: 父元素)
// align 对接线
装饰器
定义组件重用样式 @Styles
ts
@Styles function style1() {
.width(100)
.height(100)
.backgroundColor('#fafafa')
.padding(20)
.margin({bottom: 10})
}
Text(`1`).style1()
定义扩展组件样式 @Extend
ts
@Extend(Text) function style2(color: Color[], index:number) {
.width(100)
.height(100)
.backgroundColor(color[index])
.padding(20)
.margin({bottom: 10})
}
Text(`1`).style2([], 0)
组件内部状态 @State
- 可以双向绑定
- 只能内部使用
- 必须初始化
- 嵌套对象数据,只能绑定第一层
ts
@Entry
@Component
struct Index {
@State current:number = 0
build() {
Row({space: 20}){
ForEach([1,2,3,4], (item:number) => {
Text(`num${item}`)
.width(60)
.height(30)
.textAlign(TextAlign.Center)
.border({
width: this.current === item ? 2 : 1,
color: this.current === item ? Color.Blue : Color.Black
})
.onClick(() => {
this.current = item;
})
})
}
}
}
父子通信,单向数据绑定 @Prop
- 单向数据绑定
- 只能在
@Component
使用 - 父组件更新,子组件改变
ts
// 父组件
import { Child } from '../view/child'
@Entry
@Component
struct Index {
@State title:string = 'hello world'
build() {
Column({space: 20}){
Button('修改子组件')
.onClick(() => {
this.title = '你好 鸿蒙'
})
Child({title: this.title})
}
}
}
ts
// 子组件
@Component
export struct Child {
@Prop title:string // 接收数据
build() {
Column({space: 10}){
Text("子组件")
Text(this.title)
}
}
}
父子通信,双向数据绑定 @Link
- 和
@Prop
用法一样 - 双向数据绑定
- 只能在
@Component
使用 - 父子组件更新,另一方响应
数据双向绑定 (v-model)
使用
$$
绑定
ts
@Entry
@Component
struct Index {
@State msg:string = '123'
build() {
Column({space: 20}){
TextInput({text: $$this.msg}) // 输入框绑定变量
Text(this.msg)
}
}
}
循环渲染
ts
interface User {
id: number
name: string
}
@Entry
@Component
struct Index {
@State users:User[] = [
{id: 1, name: 'javascript'},
{id: 2, name: 'typescript'}
]
build() {
Column({space: 20}){
ForEach(this.users, (item:User) => {
Text(item.name)
}, (item: User) => `${item.id}`)
}
}
}
ForEach(
[], // 循环数据
(item, index) => {}, // 渲染
(item, index) => {} // 键值,和vue的 :key 的一样
)
路由跳转 router
ts
import { router } from '@kit.ArkUI' // 引入
@Entry
@Component
struct Index {
build() {
Column({space: 20}){
Button('跳转页面')
.onClick(() => {
router.pushUrl({url: 'pages/Add'}, router.RouterMode.Single)
// router.replaceUrl({url: 'pages/Add'})
})
}
}
}
router.pushUrl({url: 'pages/Add', params: { text: '123' }})
router.replaceUrl({url: 'pages/Add'})
router.RouterMode.Standard // 路由模式
// Standard 多实例模式(默认)
// Single 单实例模式
// 接收路由参数
const route = router.getParams()
console.log(`${JSON.stringify(route)}`)
生命周期
ts
aboutToAppear(): void {} // 创建组件实例,执行 build() 之前
onDidBuild(): void {} // 执行 build() 之后(推荐在这个阶段实现数据埋点等不影响ui的操作)
aboutToDisappear(): void {} // 销毁时执行
onPageShow(): void {} // 每次进入(仅@Entry装饰的组件生效)
onPageHide(): void {} // 每次退出(仅@Entry装饰的组件生效)
onBackPress(): void {} // 点击返回按钮时(仅@Entry装饰的组件生效)
aboutToReuse(): void {} // 当一个可复用的自定义组件从复用缓存中重新加入到节点树时
aboutToRecycle(): void {} // 在可复用组件从组件树上被加入到复用缓存之前调用