公司网站一般去哪里做,重庆建设工程造价信息网官网查询,网络设计属于什么专业,深圳设计产业园文章目录 ArkTSArkTS声明式开发范式的基本组成基本语法声明式UI创建组件配置属性配置事件配置子组件 自定义组件基本结构成员函数/变量build()函数自定义组件通用样式自定义组件的创建和渲染流程自定义组件重新渲染自定义组件的删除 Builder装饰器全局自定义构建函数组件内部的… 文章目录 ArkTSArkTS声明式开发范式的基本组成基本语法声明式UI创建组件配置属性配置事件配置子组件 自定义组件基本结构成员函数/变量build()函数自定义组件通用样式自定义组件的创建和渲染流程自定义组件重新渲染自定义组件的删除 Builder装饰器全局自定义构建函数组件内部的私有构建函数参数传递规则--按值传递参数传递规则--按引用传递 BuilderParam装饰器初始化BuilderParam使用场景 Styles装饰器Extend装饰器多态样式stateStyles TS是JS的超集ArkTS则是TS的超集。 ArkTS
ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS是在TS基础上做了拓展。
当前ArkTS在TS的基础上主要扩展了如下能力
基本语法ArkTS定义了声明式UI描述、自定义组件和动态扩展UI元素的能力再配合ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。状态管理ArkTS提供了多维度的状态管理机制。在UI开发框架中与UI相关联的数据可以在组件内使用也可以在不同组件层级间传递比如父子组件之间、爷孙组件之间还可以在应用全局范围内传递或跨设备传递。另外从数据的传递形式来看可分为只读的单向传递和可变更的双向传递。开发者可以灵活地利用这些能力来实现数据和UI的联动。渲染控制ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据并在每次迭代过程中创建相应的组件。
未来ArkTS会结合应用开发/运行的需求持续演进逐步提供并行和并发能力增强、系统类型增强、分布式开发范式等更多特性。
ArkTS声明式开发范式的基本组成 装饰器 用来装饰类、结构体、方法以及变量赋予其特殊的含义如上述示例中 Entry 、 Component 、 State 都是装饰器。具体而言 Component 表示这是个自定义组件 Entry 则表示这是个入口组件 State 表示组件中的状态变量此状态变化会引起 UI 变更。 自定义组件 可复用的 UI 单元可组合其它组件被 Component 装饰的 struct。 UI 描述 声明式的方式来描述 UI 的结构 build() 方法内部的代码块。 内置组件 框架中默认内置的基础和布局组件可直接被开发者调用比如 Column、Text、Divider、Button。 事件方法 用于添加组件对事件的响应逻辑统一通过事件方法进行设置Button的onClick()。 属性方法 用于组件属性的配置统一通过属性方法进行设置如fontSize()、width()、height()、color() 等可通过链式调用的方式设置多项属性。
除此之外ArkTS扩展了多种语法范式来使开发更加便捷
Builder/BuilderParam特殊的封装UI描述的方法细粒度的封装和复用UI描述。 Extend/Styles扩展内置组件和封装属性样式更灵活地组合内置组件。 stateStyles多态样式可以依据组件的内部状态的不同设置不同样式。 基本语法
声明式UI
创建组件 Column() {// 有参数形式// string类型的参数Text(test)// $r形式引入应用资源可应用于多语言场景Text($r(app.string.title_value))// 无参数形式Text()Divider()
}配置属性
Image(test.jpg).alt(error.jpg) .width(100) .height(100)Text(test).fontSize(12)配置事件
// 使用箭头函数
Button(Click me).onClick(() {this.myText ArkUI;})// 使用匿名函数要使用bind以确保函数体中的this指向当前组件。
Button(add counter).onClick(function(){this.counter 2;}.bind(this))// 使用组件的成员函数配置组件
myClickHandler(): void {this.counter 2;
}Button(add counter).onClick(this.myClickHandler.bind(this))// 使用声明的箭头函数可以直接调用不需要bind this
fn () {console.info(counter: ${this.counter})this.counter
}Button(add counter).onClick(this.fn)配置子组件
需要在{…}中为组件添加子组件
Column() {Row() {Image(test1.jpg).width(100).height(100)Button(click 1).onClick(() {console.info(1 clicked!);})}
}自定义组件
基本结构
Entry
Component
struct MyComponent {build() {}
}EntryEntry装饰的自定义组件将作为UI页面的入口。在单个UI页面中最多可以使用Entry装饰一个自定义组件。Entry可以接受一个可选的LocalStorage的参数。
ComponentComponent装饰器仅能装饰struct关键字声明的数据结构。struct被Component装饰后具备组件化的能力需要实现build方法描述UI一个struct只能被一个Component装饰。
struct自定义组件基于struct实现struct 自定义组件名 {…}的组合构成自定义组件不能有继承关系。对于struct的实例化可以省略new。
build()函数build()函数用于定义自定义组件的声明式UI描述自定义组件必须定义build()函数。
成员函数/变量
自定义组件除了必须要实现build()函数外还可以实现其他成员函数成员函数具有以下约束
不支持静态函数。成员函数的访问是私有的。
自定义组件可以包含成员变量成员变量具有以下约束
不支持静态成员变量。所有成员变量都是私有的变量的访问规则与成员函数的访问规则相同。自定义组件的成员变量本地初始化有些是可选的有些是必选的。具体是否需要本地初始化是否需要从父组件通过参数传递初始化子组件的成员变量参考状态管理。
build()函数
所有声明在build()函数的语言我们统称为UI描述UI描述需要遵循以下规则
Entry装饰的自定义组件其build()函数下的根节点唯一且必要且必须为容器组件其中ForEach禁止作为根节点。 Component装饰的自定义组件其build()函数下的根节点唯一且必要可以为非容器组件其中ForEach禁止作为根节点。
Entry
Component
struct MyComponent {build() {// 根节点唯一且必要必须为容器组件Row() {ChildComponent() }}
}Component
struct ChildComponent {build() {// 根节点唯一且必要可为非容器组件Image(test.jpg)}
}不允许声明本地变量
build() {// 反例不允许声明本地变量let a: number 1;
}不允许在UI描述里直接使用console.info但允许在方法或者函数里使用
build() {// 反例不允许console.infoconsole.info(print debug log);
}不允许创建本地的作用域
build() {// 反例不允许本地作用域{...}
}不允许调用没有用Builder装饰的方法允许系统组件的参数是TS方法的返回值。
Component
struct ParentComponent {doSomeCalculations() {}calcTextValue(): string {return Hello World;}Builder doSomeRender() {Text(Hello World)}build() {Column() {// 反例不能调用没有用Builder装饰的方法this.doSomeCalculations();// 正例可以调用this.doSomeRender();// 正例参数可以为调用TS方法的返回值Text(this.calcTextValue())}}
}不允许switch语法如果需要使用条件判断请使用if。
build() {Column() {// 反例不允许使用switch语法switch (expression) {case 1:Text(...)break;case 2:Image(...)break;default:Text(...)break;}}
}不允许使用表达式
build() {Column() {// 反例不允许使用表达式(this.aVar 10) ? Text(...) : Image(...)}
}自定义组件通用样式
Component
struct MyComponent2 {build() {Button(Hello World)}
}Entry
Component
struct MyComponent {build() {Row() {MyComponent2().width(200).height(300).backgroundColor(Color.Red)}}
}自定义组件的创建和渲染流程
自定义组件的创建自定义组件的实例由ArkUI框架创建。初始化自定义组件的成员变量通过本地默认值或者构造方法传递参数来初始化自定义组件的成员变量初始化顺序为成员变量的定义顺序。如果开发者定义了aboutToAppear则执行aboutToAppear方法。在首次渲染的时候执行build方法渲染系统组件如果子组件为自定义组件则创建自定义组件的实例。在执行build()函数的过程中框架会观察每个状态变量的读取状态将保存两个map 状态变量 - UI组件包括ForEach和if。UI组件 - 此组件的更新函数即一个lambda方法作为build()函数的子集创建对应的UI组件并执行其属性方法示意如下。 build() {...this.observeComponentCreation(() {Button.create();})this.observeComponentCreation(() {Text.create();})...}当应用在后台启动时此时应用进程并没有销毁所以仅需要执行onPageShow。
自定义组件重新渲染
当事件句柄被触发比如设置了点击事件即触发点击事件改变了状态变量时或者LocalStorage / AppStorage中的属性更改并导致绑定的状态变量更改其值时
框架观察到了变化将启动重新渲染。根据框架持有的两个map自定义组件的创建和渲染流程中第4步框架可以知道该状态变量管理了哪些UI组件以及这些UI组件对应的更新函数。执行这些UI组件的更新函数实现最小化更新。
自定义组件的删除
如果if组件的分支改变或者ForEach循环渲染中数组的个数改变组件将被删除
在删除组件之前将调用其aboutToDisappear生命周期函数标记着该节点将要被销毁。ArkUI的节点删除机制是后端节点直接从组件树上摘下后端节点被销毁对前端节点解引用前端节点已经没有引用时将被JS虚拟机垃圾回收。自定义组件和它的变量将被删除如果其有同步的变量比如Link、Prop、StorageLink将从同步源上取消注册。
不建议在生命周期aboutToDisappear内使用async await如果在生命周期的aboutToDisappear使用异步操作Promise或者回调方法自定义组件将被保留在Promise的闭包中直到回调方法被执行完这个行为阻止了自定义组件的垃圾回收。
Builder装饰器 Builder装饰器是个特殊的工具以模块化和可复用的方式构建用户界面 Builder所装饰的函数遵循build()函数语法规则将重复使用的UI元素抽象成一个方法在build方法里调用。 举个简单的例子
全局自定义构建函数 应用内可以直接调用 如果不涉及组件状态变化建议使用全局的自定义构建方法。 知道是啥了那就整点别的
组件内部的私有构建函数 需要用 this 调用 参数传递规则–按值传递 传递的参数为状态变量时状态变量的改变不会引起Builder方法内的UI刷新。所以当使用状态变量的时候推荐使用按引用传递。 参数传递规则–按引用传递 使用$$传递的参数可以是状态变量且状态变量的改变会引起Builder方法内的UI刷新。 在按值传递的基础上修改一下就好了额 UI会刷新了
BuilderParam装饰器 BuilderParam 装饰器允许你将一个函数作为参数传递给一个自定义构建函数Builder 装饰的函数 初始化BuilderParam
使用所属自定义组件的自定义构建函数或者全局的自定义构建函数在本地初始化BuilderParam
Builder function GlobalBuilder0() {}Component
struct Child {Builder doNothingBuilder() {};BuilderParam aBuilder0: () void this.doNothingBuilder;BuilderParam aBuilder1: () void GlobalBuilder0;build(){}
}用父组件自定义构建函数初始化子组件BuilderParam装饰的方法。
Component
struct Child {BuilderParam aBuilder0: () void;build() {Column() {this.aBuilder0()}}
}Entry
Component
struct Parent {Builder componentBuilder() {Text(Parent builder )}build() {Column() {Child({ aBuilder0: this.componentBuilder })}}
}使用场景
参数初始化组件 BuilderParam装饰的方法可以是有参数和无参数的两种形式需与指向的Builder方法类型匹配。BuilderParam装饰的方法类型需要和Builder方法类型一致 Builder function GlobalBuilder1($$ : {label: string }) {Text($$.label).width(400).height(50).backgroundColor(Color.Green)
}Component
struct Child {label: string Child// 无参数类指向的componentBuilder也是无参数类型BuilderParam aBuilder0: () void;// 有参数类型指向的GlobalBuilder1也是有参数类型的方法BuilderParam aBuilder1: ($$ : { label : string}) void;build() {Column() {this.aBuilder0()this.aBuilder1({label: global Builder label } )}}
}Entry
Component
struct Parent {label: string ParentBuilder componentBuilder() {Text(${this.label})}build() {Column() {this.componentBuilder()Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })}}
}尾随闭包初始化组件
// xxx.ets
Component
struct CustomContainer {Prop header: string;BuilderParam closer: () voidbuild() {Column() {Text(this.header).fontSize(30)this.closer()}}
}Builder function specificParam(label1: string, label2: string) {Column() {Text(label1).fontSize(30)Text(label2).fontSize(30)}
}Entry
Component
struct CustomContainerUser {State text: string header;build() {Column() {// 创建CustomContainer在创建CustomContainer时通过其后紧跟一个大括号“{}”形成尾随闭包// 作为传递给子组件CustomContainer BuilderParam closer: () void的参数CustomContainer({ header: this.text }) {Column() {specificParam(testA, testB)}.backgroundColor(Color.Yellow).onClick(() {this.text changeHeader;})}}}
}Styles装饰器 简单说就是公共样式封装 当前Styles仅支持通用属性比如width、height等等和通用事件比如onClick、onTouch等等。Styles方法不支持参数Styles可以定义在组件内或全局在全局定义时需在方法名前面添加function关键字组件内定义时则不需要添加function关键字。定义在组件内的Styles可以通过this访问组件的常量和状态变量并可以在Styles里通过事件来改变状态变量的值组件内Styles的优先级高于全局Styles。优先找当前组件内的Styles如果找不到则会全局查找。
// 定义在全局的Styles封装的样式
Styles function globalFancy() {.width(150).height(100).backgroundColor(Color.Pink)
}Entry
Component
struct FancyUse {State heightValue: number 100// 定义在组件内的Styles封装的样式Styles fancy() {.width(200).height(this.heightValue).backgroundColor(Color.Yellow).onClick(() {this.heightValue 200})}build() {Column({ space: 10 }) {// 使用全局的Styles封装的样式Text(FancyA).globalFancy().fontSize(30)// 使用组件内的Styles封装的样式Text(FancyB).fancy().fontSize(30)}}
}Extend装饰器 在Styles的基础上我们提供了Extend用于扩展原生组件样式。 语法 Extend(UIComponentName) function functionName { … } Extend仅支持定义在全局不支持在组件内部定义。Extend装饰的方法支持参数Extend支持封装指定的组件的私有属性和私有事件和预定义相同组件的Extend的方法。Extend的参数可以为状态变量当状态变量改变时UI可以正常的被刷新渲染Extend装饰的方法的参数可以为function作为Event事件的句柄。
先玩一下样式继承。
再玩一下事件。
使用场景 以下示例声明了3个Text组件每个Text组件均设置了fontStyle、fontWeight和backgroundColor样式。
Entry
Component
struct FancyUse {State label: string Hello Worldbuild() {Row({ space: 10 }) {Text(${this.label}).fontStyle(FontStyle.Italic).fontWeight(100).backgroundColor(Color.Blue)Text(${this.label}).fontStyle(FontStyle.Italic).fontWeight(200).backgroundColor(Color.Pink)Text(${this.label}).fontStyle(FontStyle.Italic).fontWeight(300).backgroundColor(Color.Orange)}.margin(20%)}
}多态样式stateStyles Styles和Extend仅仅应用于静态页面的样式复用stateStyles可以依据组件的内部状态的不同快速设置不同样式。 stateStyles是属性方法可以根据UI内部状态来设置样式类似于css伪类但语法不同。ArkUI提供以下四种状态
focused获焦态。normal正常态。pressed按压态。disabled不可用态。 可以与Styles联合使用
Entry
Component
struct MyComponent {Styles normalStyle() {.backgroundColor(Color.Gray)}Styles pressedStyle() {.backgroundColor(Color.Red)}build() {Column() {Text(Text1).fontSize(50).fontColor(Color.White).stateStyles({normal: this.normalStyle,pressed: this.pressedStyle,})}}
}stateStyles可以通过this绑定组件内的常规变量和状态变量
Entry
Component
struct CompWithInlineStateStyles {State focusedColor: Color Color.Red;normalColor: Color Color.Greenbuild() {Column() {Button(clickMe).height(100).width(100).stateStyles({normal: {.backgroundColor(this.normalColor)},focused: {.backgroundColor(this.focusedColor)}}).onClick(() {this.focusedColor Color.Pink}).margin(30%)}}
}