鸿蒙开发笔记

鸿蒙开发

编辑器

DevEco Studio 官方下载页面

目录结构

布局组件

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)
    }
  }
}
  • @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 {} // 在可复用组件从组件树上被加入到复用缓存之前调用
相关推荐
&白帝&17 分钟前
CSS Background 相关属性详解 文字镂空效果
前端·css
我的心巴26 分钟前
Vue2 ElementUI Tree 拖动目标节点能否被放置及获取放置位置
前端·vue.js·elementui
ze_juejin39 分钟前
Subject、BehaviorSubject、ReplaySubject、AsyncSubject、VoidSubject比较
前端·angular.js
每天吃饭的羊43 分钟前
面试-TypeScript 场景类面试题
前端
CRMEB定制开发1 小时前
CRMEB 注释规范:多端适配下的代码可读性提升之道
前端
中雨20251 小时前
HarmonyOS Next快速入门:TextInput组件
前端
白晓明1 小时前
HarmonyOS NEXT端云一体化云侧云函数介绍和开发
前端·harmonyos
白晓明1 小时前
HarmonyOS NEXT端侧工程调用云函数能力实现业务功能
前端·harmonyos
锋利的绵羊1 小时前
【小程序】迁移非主包组件以减少主包体积
前端·微信小程序·uni-app