当前位置: 首页 > news >正文

鸿蒙面试题库收集(一):ArkTSArkUI-基础理论

收集官网faq:https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-arkui-kit-0000001769732210

一. ArkTS&ArkUI

1. 基础理论

1. 鸿蒙相关的生命周期都有哪些?

(1)UIAbility生命周期: onCreate、onWindowStageCreate、onForeground、onBackground、onWindowStageDestroy、onDestroy。

  • onCreate:Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行页面初始化操作,例如变量定义资源加载等,用于后续的UI展示。

  • onWindowStageCreate():UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI加载、设置WindowStage的事件订阅。[事件订阅代码]

  • onForegound():在UIAbility的UI可见之前,如UIAbility切换至前台时触发。可以在onForeground()回调中申请系统需要的资源,或者重新申请在onBackground()中释放的资源。

  • onWindowStageDestory():在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI资源。

  • onBackground():在UIAbility的UI完全不可见之后,如UIAbility切换至后台时候触发。可以在onBackground()回调中释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。

  • onWindowStageDestory():在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI资源。

  • onDestroy():Destroy状态在UIAbility实例销毁时触发。可以在onDestroy()回调中进行系统资源的释放、数据的保存等操作。

(2)页面生命周期:onPageShow、onPageHide、onBackPress。 页面生命周期,说白了就是@Entry修饰的组件,才称之为页面。

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry装饰的自定义组件生效。
  • onBackPress:当用户点击返回按钮时触发,仅@Entry装饰的自定义组件生效。

(3)组件生命周期:aboutToAppear(发起网络请求)、aboutToDisappear。

  • aboutToAppear:在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build()函数中生效。
  • aboutToDisappear:函数在自定义组件销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

按返回键页面执行生命周期方法:

  • 打开第一个页面:
    • Index:aboutToAppear
    • Index:onPageShow
  • 跳转第二个页面:
    • Index:onPageHide
    • Second:aboutToAppear
    • Second:onPageShow
  • 点击back:如果是在第二个页面跳转到第一个页面:
    • Second:onBackPress Second:onPageHide
    • Second:onPageHide Index:aboutToAppear
    • Index:onPageShow Index:onPageShow
    • Second:aboutToDisappear

返回页面不走aboutToAppear:

  • aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • 返回页面时==不需要走重新创建==,不会执行aboutToAppear,只会执行onPageShow。

问:aboutToAppear和onAppear的区别?

  • aboutToAppear:是组件的生命周期方法,当组件实例创建后,执行build函数之前执行aboutToAppear

  • onAppear:是组件的属性方法,在该组件显示时触发此回调

    Text()
    .onAppear(()=>{}
2. ArkUI的两大开发范式是什么,区别是什么
  • ArkUI推荐使用声明式开发范式 , 其他的框架有参考类Web开发范式
  • 类Web开发范式:采用经典的HML、CSS、JavaScript三段式开发方式,即使用HML标签文件搭建布局、使用CSS文件描述样式、使用JavaScript文件处理逻辑。该范式更符合于Web前端开发者的使用习惯,便于快速将已有的Web应用改造成方舟UI框架应用。

  • 声明式开发范式:采用基于TypeScript声明式UI语法扩展而来的ArkTS语言,从组件、动画和状态管理三个维度提供UI绘制能力。

  • ==延伸问题==:有听过命令式编程么,命令式编程与声明式编程的区别是什么?

    • 其实这里的命令式编程,就相当于是类Web开发范式
  • 我们来对比一下命令式和声明式

  • 声明式开发范式 : 只需要描述/声明 , 你要做什么 (通过封装好的组件以及相关熟悉方法 , 快速实现目的)

  • 命令式开发范式 : 不仅需要知道做什么 , 更需要知道如何做 (需要通过最原始的方式 , 一步一步实现)

  • 左侧是纯前端实现的按钮点击 , 也就是命令式

    • 命令式需要自己一点一点实现 , 如何做必须清楚
  • 右侧是ArkTs实现的按钮点击 , 也就是声明式

    • 声明式只需要知道做什么 , 调用对应api即可 , 不需要知道内部如何实现
3. 项目使用的是harmoneyos还是openharmoney,区别是啥 ?

HarmonyOS:OpenHarmony+闭源应用和华为移动服务HMS(比如应用市场,视频,音乐等app)
Andoird:aosp(android open source project) + GMS(Google Mobile Service)

4. arkts中哪些类不能被继承, 面试官关注点是组件是否可以继承?(组件是否可以被继承)

组件不能被继承,被@compent修饰的自定义组件不能被继承,只能引用,或者对外暴露方法。

官网解释:

  • struct:自定义组件基于struct实现,struct + 自定义组件名 + {...}的组合构成自定义组件,==不能有继承关系==。对于struct的实例化,可以省略new。

  • @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。==struct被@Component装饰后具备组件化的能力==,需要实现build方法描述UI,一个struct只能被一个@Component装饰。@Component可以接受一个可选的bool类型参数。

    @Component
    struct MyComponent {
    }
5.介绍Stage模型和FA模型
  1. Stage模型 : HarmonyOS 3.1推出 也就是API9 , 是目前==主推==且会长期演进的模型
    • 由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型
    • stage: 舞台 /steɪdʒ/
  2. FA模型: FA(Feature Ability)模型:HarmonyOS早期版本开始支持的模型,已经不再主推
    • feature: 特点 /ˈfiːtʃə(r)/
  3. 区别: Stage模型与FA模型最大的区别在于
    1. Stage模型中,多个应用组件共享同一个ArkTS引擎实例;
    2. 而FA模型中,每个应用组件独享一个ArkTS引擎实例。
    3. 因此在Stage模型中,应用组件之间可以方便的共享对象和状态,同时减少复杂应用运行对内存的占用。
    4. Stage模型作为主推的应用模型,开发者通过它能够更加便利地开发出分布式场景下的复杂应用。

2. 装饰器

1. 你使用过哪些装饰器,分别阐述一下他们得作用
  • @State装饰器,使得变量变为状态变量,影响UI(数据变化,UI变化)

  • @Prop装饰的变量和父组件建立单向的同步关系:

    • 父组件的@State数据变化,会同步到子组件@Prop

    • 具体用法

      //父组件:Parent
      @State num:number = 0
      build(){Son({num:this.num})
      }
      //子组件:Son
      @Prop num:number
    • @Prop修饰的变量,api9不能初始化,api11能初始化

  • @Link装饰的变量与其父组件中的数据源共享相同的值。

    • 父组件的@State数据变化,会同步到子组件@Link数据

    • 子组件@link数据变化,会同步到父组件@State数据

    • 具体用法

      //父组件:Parent
      @State num:number = 0
      build(){Son({num:$num})//api9必须使用$,api11开始也可以使用this了
      }
      //子组件:Son
      @Link num:number
    • @Link修饰的变量,api9不能初始化,api11不能初始化

2. 有用过@Styles,@Extend,@Builder装饰器么?
  • @Styles装饰器:定义组件重用样式 (多个组件通用的样式)

    @Styles装饰器,用于封装重复的通用样式代码。

    如果多个不同类型的组件,有着相同的样式,例如宽高,背景色,字体大小。那么就可以将这下相同的样式代码抽取到一个@Styles装饰器修饰的方法中,供大家复用。

    支持全局和局部定义:

    // 全局
    @Styles function functionName() { ... } //styles方法不能调用另一个styles方法***// 在组件内
    @Component
    struct FancyUse {@Styles fancy() {.height(100)}
    }
  • @Extend装饰器:定义扩展组件样式 (某一种组件自己的样式,私有属性)

    @Extend,用于扩展原生组件样式。

    如果同一类型的组件,有着很多相同的样式,例如按钮的类型,点击事件等。那么就可以将这些重复代码,抽过去到一个@Extend装饰器修饰的方法中,供此组件使用。

    ==仅支持全局定义==:(因为它相当于是给所有的此类组件使用)

    // @Extend(Text)可以支持Text的私有属性fontColor
    @Extend(Text) function fancy () {.fontColor(Color.Red)
    }
    // superFancyText可以调用预定义的fancy
    @Extend(Text) function superFancyText(size:number) { //Extend方法可以调用另一个Extend方法.fontSize(size).fancy()
    }
  • @Builder装饰器:自定义构建函数

    @Builder装饰器,用于封装重复的,复杂UI结构代码,例如List中的ListItem的布局结构,一般比较复杂就可以抽取到@Builder装饰的函数中

    @Builder所装饰的函数遵循build()函数语法规则,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。

    支持全局定义和局部定义:

    //既然调用是通过this调用,那么说明是在组件内部定义
    //组件内部定义不需要关键字function
    @Builder MyBuilderFunction() { ... }//全局定义
    MyGlobalBuilderFunction()
  • @BuilderParam装饰器:引用@Builder函数

    当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。

    为解决此问题,ArkUI引入了@BuilderParam装饰器,该装饰器用于声明任意UI描述的一个元素,==类似slot占位符==。

    • 使得自定义组件更加灵活

    代码:

    @Component
    struct Child {@Builder customBuilder() {}// 使用父组件@Builder装饰的方法初始化子组件@BuilderParam@BuilderParam customBuilderParam: () => void = this.customBuilder;build() {Column() {this.customBuilderParam()}}
    }@Entry
    @Component
    struct Parent {@Builder componentBuilder() {Text(`Parent builder `)}build() {Column() {Child({ customBuilderParam: this.componentBuilder })}}
    }
3. 还用过其他装饰器么?
1. Provide和Consume
  1. @Provide和@Consume,用于祖先与后代组件的双向数据同步,实现跨层级传递

    • ==理解==:@Provide装饰器的变量是在祖先组件中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费”数据
  2. 语法特点:

    • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定

      // 通过相同的变量名绑定
      @Provide a: number = 0; //祖先组件中定义
      @Consume a: number;  //子孙组件中定义// 通过相同的变量别名绑定
      @Provide('a') b: number = 0;//参数即为别名
      @Consume('a') c: number;
2. ObjectLink和Observed
  • @ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

    • 被@Observed装饰的类,可以被观察到属性的变化;
    • 子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中的属性,这个属性同样也需要被@Observed装饰。
    • 单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。
  • 详情参考: 3.状态管理.md --> 2.5章节

3. Watch

概述

  1. @Watch应用于==对状态变量的监听==。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。
  2. @Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用

代码:

@Component
struct TotalView {@Prop @Watch('onCountUpdated') count: number = 0;@State total: number = 0;// 该函数是自定义组件的成员函数// @Watch 回调// propName是被watch的属性名// 多个状态绑定同一个@Watch回调时,通过propName区分到底是哪个状态改变了onCountUpdated(propName: string): void {this.total += this.count;}build() {Text(`Total: ${this.total}`)}
}@Entry
@Component
struct CountModifier {@State count: number = 0;build() {Column() {Button('add to basket').onClick(() => {this.count++})TotalView({ count: this.count })}}
}

相关文章:

  • 支付宝远程收款api之小荷包跳转码
  • 【算法——KMP】
  • Spring Boot 整合 Keycloak
  • K8s flink-operator 例子
  • 多无人机通信(多机通信)+配置ssh服务
  • opengauss使用遇到的问题,随时更新
  • react是一种语言?
  • 高效编程的利器 Jupyter Notebook
  • (undone) MIT6.824 Lecture1 笔记
  • 数据结构:树(并查集)
  • minio 快速入门+单机部署+集群+调优
  • 前端使用xlsx-js-style导出Excel,带样式,并处理合并单元格边框显示不全和动态插入表头解决
  • 分治思想--python
  • Nest.js实现一个简单的聊天室
  • 24.9.27学习笔记
  • [译]如何构建服务器端web组件,为何要构建?
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 【前端学习】-粗谈选择器
  • angular2 简述
  • Angularjs之国际化
  • github从入门到放弃(1)
  • HTML5新特性总结
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java超时控制的实现
  • laravel with 查询列表限制条数
  • MySQL-事务管理(基础)
  • PAT A1092
  • python_bomb----数据类型总结
  • XML已死 ?
  • 设计模式(12)迭代器模式(讲解+应用)
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 携程小程序初体验
  • 正则学习笔记
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • # include “ “ 和 # include < >两者的区别
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $.ajax()参数及用法
  • ()、[]、{}、(())、[[]]命令替换
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (vue)el-tabs选中最后一项后更新数据后无法展开
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (三) diretfbrc详解
  • (十二)Flink Table API
  • (四)事件系统
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (循环依赖问题)学习spring的第九天
  • (译)计算距离、方位和更多经纬度之间的点
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)h264中avc和flv数据的解析