鸿蒙ArkTS基础知识-自定义组件生命周期函数onBackPress的调用。

623 篇文章 5 订阅
621 篇文章 3 订阅

介绍

本课程使用声明式语法和组件化基础知识,搭建一个可刷新的排行榜页面。在排行榜页面中,使用循环渲染控制语法来实现列表数据渲染,使用@Builder创建排行列表布局内容,使用装饰器@State、@Prop、@Link来管理组件状态。最后我们点击系统返回按键,来学习自定义组件生命周期函数。效果如图所示:

相关概念

1.渲染控制语法:

  • 条件渲染:使用if/else进行条件渲染。语法如下:
Column() {
   if (this.count > 0) {
       Text('count is positive')
   }
}
  • 循环渲染:开发框架提供循环渲染(ForEach组件)来迭代数组,并为每个数组项创建相应的组件。ForEach定义如下:
ForEach(
  arr: any[], // 用于迭代的数组
  itemGenerator: (item: any, index?: number) => void, // 生成子组件的lambda函数
  keyGenerator?: (item: any, index?: number) => string // 用于给定数组项生成唯一且稳定的键值
)

2.组件状态管理装饰器和@Builder装饰器:

组件状态管理装饰器用来管理组件中的状态,它们分别是:@State、@Prop、@Link。

  • @State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新。
  • @Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但更改不会通知给父组件,即@Prop属于单向数据绑定。
  • @Link装饰的变量可以和父组件的@State变量建立双向数据绑定,需要注意的是:@Link变量不能在组件内部进行初始化。
  • @Builder装饰的方法用于定义组件的声明式UI描述,在一个自定义组件内快速生成多个布局内容。

@State、@Prop、@Link三者关系如图所示:

3.组件生命周期函数:

自定义组件的生命周期函数用于通知用户该自定义组件的生命周期,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用这些回调函数。 右图是自定义组件生命周期的简化图示:

说明: 需要注意的是,部分生命周期回调函数仅对**@Entry**修饰的自定义组件生效,它们分别是:onPageShow、onPageHide、onBackPress。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  1. 完成DevEco Device Tool的安装
  2. 完成RK3568开发板的烧录

3.搭建开发环境。

  1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets               // 代码区    
│  ├──common                        // 公共文件目录
│  │  └──constants                  
│  │     └──Constants.ets           // 常量
│  ├──entryability
│  │  └──EntryAbility.ts            // 应用的入口
│  ├──model                         
│  │  └──DataModel.ets              // 模拟数据
│  ├──pages
│  │  └──RankPage.ets               // 入口页面
│  ├──view                          // 自定义组件目录
│  │  ├──ListHeaderComponent.ets
│  │  ├──ListItemComponent.ets
│  │  └──TitleComponent.ets
│  └──viewmodel         
│     ├──RankData.ets               // 实体类            
│     └──RankViewModel.ets          // 视图业务逻辑类
└──entry/src/main/resources         // 资源文件目录

使用@Link封装标题组件

在TitleComponent文件中,首先使用struct对象创建自定义组件,然后使用@Link修饰器管理TitleComponent组件内的状态变量isRefreshData,状态变量isRefreshData值发生改变后,通过@Link装饰器通知页面刷新List中的数据。代码如下:

// TitleComponent.ets
...
@Component
export struct TitleComponent {
  @Link isRefreshData: boolean; // 判断是否刷新数据
  @State title: Resource = $r('app.string.title_default');

  build() {
    Row() {
      ...
      Row() {
        Image($r('app.media.loading'))
          .height(TitleBarStyle.IMAGE_LOADING_SIZE)
          .width(TitleBarStyle.IMAGE_LOADING_SIZE)
          .onClick(() => {
            this.isRefreshData = !this.isRefreshData;
          })
      }
      .width(TitleBarStyle.WEIGHT)
      .height(WEIGHT)
      .justifyContent(FlexAlign.End)
    }
   ...
  }
}

效果如图所示:

封装列表头部样式组件

在ListHeaderComponent文件中,我们使用常规成员变量来设置自定义组件ListHeaderComponent的widthValue和paddingValue,代码如下:

// ListHeaderComponent.ets
...
@Component
export struct ListHeaderComponent {
  paddingValue: Padding | Length = 0;
  widthValue: Length = 0;

  build() {
    Row() {
      Text($r('app.string.page_number'))
        .fontSize(FontSize.SMALL)
        .width(ListHeaderStyle.LAYOUT_WEIGHT_LEFT)
        .fontWeight(ListHeaderStyle.FONT_WEIGHT)
        .fontColor($r('app.color.font_description'))
      Text($r('app.string.page_type'))
        .fontSize(FontSize.SMALL)
        .width(ListHeaderStyle.LAYOUT_WEIGHT_CENTER)
        .fontWeight(ListHeaderStyle.FONT_WEIGHT)
        .fontColor($r('app.color.font_description'))
      Text($r('app.string.page_vote'))
        .fontSize(FontSize.SMALL)
        .width(ListHeaderStyle.LAYOUT_WEIGHT_RIGHT)
        .fontWeight(ListHeaderStyle.FONT_WEIGHT)
        .fontColor($r('app.color.font_description'))
    }
    .width(this.widthValue)
    .padding(this.paddingValue)
  }
}

效果如图所示:

创建ListItemComponent

为了体现@Prop单向绑定功能,我们在ListItemComponent组件中添加了一个@Prop修饰的字段isSwitchDataSource,当通过点击改变ListItemComponent组件中isSwitchDataSource状态时,ListItemComponent作为List的子组件,并不会通知其父组件List刷新状态。

在代码中,我们使用@State管理ListItemComponent中的 isChange 状态,当用户点击ListItemComponent时,ListItemComponent组件中的文本颜色发生变化。我们使用条件渲染控制语句,创建的圆型文本组件。

// ListItemComponent.ets
...
@Component
export struct ListItemComponent {
  index?: number;
  private name?: Resource;
  @Prop vote: string = '';
  @Prop isSwitchDataSource: boolean = false;
  // 判断是否改变ListItemComponent字体颜色
  @State isChange: boolean = false;

  build() {
    Row() {
      Column() {
        if (this.isRenderCircleText()) {
          if (this.index !== undefined) {
            this.CircleText(this.index);
          }
        } else {
          Text(this.index?.toString())
            .lineHeight(ItemStyle.TEXT_LAYOUT_SIZE)
            .textAlign(TextAlign.Center)
            .width(ItemStyle.TEXT_LAYOUT_SIZE)
            .fontWeight(FontWeight.BOLD)
            .fontSize(FontSize.SMALL)
        }
      }
      .width(ItemStyle.LAYOUT_WEIGHT_LEFT)
      .alignItems(HorizontalAlign.Start)

      Text(this.name)
        .width(ItemStyle.LAYOUT_WEIGHT_CENTER)
        .fontWeight(FontWeight.BOLDER)
        .fontSize(FontSize.MIDDLE)
        .fontColor(this.isChange ? ItemStyle.COLOR_BLUE : ItemStyle.COLOR_BLACK)
      Text(this.vote)
        .width(ItemStyle.LAYOUT_WEIGHT_RIGHT)
        .fontWeight(FontWeight.BOLD)
        .fontSize(FontSize.SMALL)
        .fontColor(this.isChange ? ItemStyle.COLOR_BLUE : ItemStyle.COLOR_BLACK)
    }
    .height(ItemStyle.BAR_HEIGHT)
    .width(WEIGHT)
    .onClick(() => {
      this.isSwitchDataSource = !this.isSwitchDataSource;
      this.isChange = !this.isChange;
    })
  }
  ...
}

效果如图所示:

创建RankList

为了简化代码,提高代码的可读性,我们使用@Builder描述排行列表布局内容,使用循环渲染组件ForEach创建ListItem。代码如下:

// RankPage.ets
...
  build() {
    Column() {
      // 顶部标题组件
      TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })
      // 列表头部样式
      ListHeaderComponent({
        paddingValue: {
          left: Style.RANK_PADDING,
          right: Style.RANK_PADDING
        },
        widthValue: Style.CONTENT_WIDTH
      })
      .margin({
        top: Style.HEADER_MARGIN_TOP,
        bottom: Style.HEADER_MARGIN_BOTTOM
      })
      // 列表区域
      this.RankList(Style.CONTENT_WIDTH)
    }
    .backgroundColor($r('app.color.background'))
    .height(WEIGHT)
    .width(WEIGHT)
  }

  @Builder RankList(widthValue: Length) {
    Column() {
      List() {
        ForEach(this.isSwitchDataSource ? this.dataSource1 : this.dataSource2,
          (item: RankData, index?: number) => {
            ListItem() {
              ListItemComponent({ index: (Number(index) + 1), name: item.name, vote: item.vote,
                isSwitchDataSource: this.isSwitchDataSource
              })
            }
          }, (item: RankData) => JSON.stringify(item))
      }
      .width(WEIGHT)
      .height(Style.LIST_HEIGHT)
      .divider({ strokeWidth: Style.STROKE_WIDTH })
    }
    .padding({
      left: Style.RANK_PADDING,
      right: Style.RANK_PADDING
    })
    .borderRadius(Style.BORDER_RADIUS)
    .width(widthValue)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(Color.White)
  }
...

效果如图所示:

使用自定义组件生命周期函数

我们通过点击系统导航返回按钮来演示onBackPress回调方法的使用,在指定的时间段内,如果满足退出条件,onBackPress将返回false,系统默认关闭当前页面。否则,提示用户需要再点击一次才能退出,同时onBackPress返回true,表示用户自己处理导航返回事件。代码如下:

// RankPage.ets
... 
@Entry
@Component
struct RankPage {
  ...
  onBackPress() {
    if (this.isShowToast()) {
      prompt.showToast({
        message: $r('app.string.prompt_text'),
        duration: TIME
      });
      this.clickBackTimeRecord = new Date().getTime();
      return true;
    }
    return false;
  }
  ...
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 条件渲染、循环渲染语法的使用。
  2. @State、@Prop、@Link修饰器的使用。
  3. @Builder修饰器的使用。
  4. 自定义组件生命周期函数onBackPress的调用。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书请点击→《鸿蒙生态应用开发白皮书V2.0PDF

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. ……

二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全
  5. ........

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

更多了解更多鸿蒙开发的相关知识可以参考:鸿蒙 (Harmony OS)开发学习手册

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Vue 组件中,有如下的生命周期钩子函数(按调用顺序): 1. beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 2. created:实例创建完成后被立即调用。在这一步,实例已经完成了数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 3. beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。 4. mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 5. beforeUpdate:在数据更新之前调用,发生在虚拟 DOM 重新渲染和打补丁之前。这里无法访问到更新后的 DOM。 6. updated:在由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用调用时,组件 DOM 已经更新,所以可以执行依赖于 DOM 的操作。 7. activated:keep-alive 组件激活时调用。 8. deactivated:keep-alive 组件停用时调用。 9. beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。 10. destroyed:实例销毁之后调用。该钩子被调用后,Vue 实例指示的所有东西都会解绑定,所有事物都会被销毁,所有事件监听器都会被移除。 需要注意的是,在组件中使用 keep-alive 时,组件的生命周期还会多出两个钩子函数:activated 和 deactivated。这两个钩子函数会在组件被缓存时调用,用于控制缓存期间组件的行为。当组件被激活时,activated 钩子函数会被调用;当组件被停用时,deactivated 钩子函数会被调用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值