做网站要多少钱怎么样,网站后台不能编辑,兼职网站项目建设报告,网络强国建设的未来目录
1 - 基本UI描述
1.1 - 基本概念
1.2 - UI描述规范
1.2.1 - 无参数构造配置
1.2.2 - 必选参数构造配置
1.2.3 - 属性配置
1.2.4 - 事件配置
1.2.5 - 子组件配置
2 - 状态管理
2.1 - 基本概念
2.2 - 页面级变量的状…目录
1 - 基本UI描述
1.1 - 基本概念
1.2 - UI描述规范
1.2.1 - 无参数构造配置
1.2.2 - 必选参数构造配置
1.2.3 - 属性配置
1.2.4 - 事件配置
1.2.5 - 子组件配置
2 - 状态管理
2.1 - 基本概念
2.2 - 页面级变量的状态管理
2.2.1 - State
2.2.2 - Prop
2.2.3 - Link
2.2.4 - Observed和ObjectLink数据管理
2.2.5 - Consume和Provide
2.2.6 - Watch
2.3 - 应用级变量的状态管理
2.3.1 - AppStorage
2.3.2 - PersistentStorage
2.3.3 - Environment 1 - 基本UI描述
ArkTS通过装饰器Component和Entry装饰struct关键字声明的数据结构构成一个自定义组件。
1.1 - 基本概念 struct自定义组件可以基于struct实现不能有继承关系对于struct的实例化可以省略new。 装饰器装饰器给被装饰的对象赋予某一种能力其不仅可以装饰类或结构体还可以装饰类的属性。多个装饰器可以叠加到目标元素上定义在同一行中或者分开多行推荐分开多行定义。
Entry
Component
struct MyComponent {
}
build函数自定义组件必须定义build函数并且禁止自定义构造函数。build函数满足Builder构造器接口定义用于定义组件的声明式UI描述。
interface Builder {build: () void
}
Component装饰struct结构体在装饰后具有基于组件的能力需要实现build方法来创建UI。Entry装饰struct组件被装饰后作为页面的入口页面加载时被渲染显示。Preview装饰struct用Preview装饰的自定义组件可以在DevEco Studio的预览器上进行实时预览加载页面时将创建并显示Preview装饰的自定义组件。
说明
在单个源文件中最多可以使用10个Preview装饰自定义组件。
链式调用以“.”链式调用的方法配置UI组件的属性方法、事件方法等。
1.2 - UI描述规范
1.2.1 - 无参数构造配置
如果组件的接口定义中不包括必选构造参数组件后面的“()”中不需要配置任何内容。例如Divider组件不包含构造参数。
Column() {Text(item 1)Divider()Text(item 2)
}
1.2.2 - 必选参数构造配置
如果组件的接口定义中包含必须按构参数则在组件后面的“()”中必须配置相应参数参数可以使用常量进行赋值。
例如
Image组件的必选参数src
Image(https://xyz/test.jpg)
Text组件的必选参数content
Text(test)
变量或表达式也可以用于参数赋值其中表达式返回的结果类型必须满足参数类型要求。
例如设置变量或表达式来构造Image和Text组件的参数
Image(this.imagePath)
Image(https:// this.imageUrl)
Text(count: ${this.count})
1.2.3 - 属性配置
使用属性方法配置组件的属性属性方法紧随组件并用“.”运算符连接。
配置Text组件的字体大小属性
Text(test).fontSize(12)
使用“.”运算符进行链式调用并同时配置组件的多个属性如下所示
Image(test.jpg).alt(error.jpg) .width(100) .height(100)
除了直接传递常量参数外还可以传递变量或表达式如下所示
Text(hello).fontSize(this.size)
Image(test.jpg).width(this.count % 2 0 ? 100 : 200) .height(this.offset 100)
对于系统内置组件框架还为其属性预定义了一些枚举类型供开发人员调用枚举类型可以作为参数传递且必须满足参数类型要求。
例如可以按以下方式配置Text组件的颜色和字体属性
Text(this.message).id(One Piece).fontColor(Color.Blue).fontSize(50).fontWeight(FontWeight.Bold)
1.2.4 - 事件配置
通过事件方法可以配置组件支持的事件事件方法紧随组件并用“.”运算符连接。
使用lambda表达式配置组件的事件方法
Button(add counter).onClick(() {this.counter 2})
使用匿名函数表达式配置组件的事件方法要求使用bind以确保函数体中的this引用包含的组件
Button(add counter).onClick(function () {this.counter 2}.bind(this))
使用组件的成员函数配置组件的事件方法
myClickHandler(): void {this.counter 2
}...Button(add counter).onClick(this.myClickHandler)
1.2.5 - 子组件配置
对于支持子组件配置的组件例如容器组件在“{……}”里为组件添加子组件的UI描述。Column、Row、Stack、Grid、List等组件都是容器组件。
以下是简单的Column示例
Column() {Text(Hello).fontSize(100)Divider()Text(this.myText).fontSize(100).fontColor(Color.Red)
}
容器组件之间也可以互相嵌套实现相对复杂的多级嵌套效果
Column() {Row() {Image(test1.jpg).width(100).height(100)Button(click 1).onClick(() {console.info(1 clicked!)})}Divider()Row() {Image(test2.jpg).width(100).height(100)Button(click 2).onClick(() {console.info(2 clicked!)})}Divider()Row() {Image(test3.jpg).width(100).height(100)Button(click 3).onClick(() {console.info(3 clicked!)})}
}
2 - 状态管理
2.1 - 基本概念
ArkTS提供了多维度的状态管理机制在UI开发框架中和UI相关联的数据不仅可以在组件内使用还可以在不同组件层级间传递比如父子组件之间、爷孙组件之间也可以是全局范围内的传递。另外从数据的传递形式来看可分为只读的单向传递和可变更的双向传递。可以灵活的利用这些能力来实现数据和UI的联动。 2.2 - 页面级变量的状态管理
State、Prop、Link、Provide、Consume、ObjectLink、Observed和Watch用于管理页面级变量的状态。
装饰器装饰内容说明State基本数据类型、类、数组修饰的状态数据被修改时会触发组件的build方法进行UI界面更新。Prop基本数据类型修改后的状态数据用于在父组件和子组件之间建立单向数据依赖关系。修改父组件关联数据时更新当前组件的UI。Link基本数据类型、类、数组父子组件之间的双向数据绑定父组件的内部状态数据作为数据源任何一方所做的修改都会反映给另一方。Observed类Observed应用于类表示该类中的数据变更被UI页面管理。ObjectLink被Observed所装饰类的对象装饰的状态数据被修改时在父组件或者其他兄弟组件内与它关联的状态数据所在的组件都会更新UI。Consume基本数据类型、类、数组Consume装饰的变量在感知到Provide装饰的变量更新后会触发当前自定义组件的重新渲染。Provide基本数据类型、类、数组Provide作为数据的提供方可以更新其子孙节点的数据并触发页面渲染。
2.2.1 - State
State装饰的变量是组件内部的状态数据当这些状态数据被修改时将会调用所在组件的build方法进行UI刷新。
State状态数据具有以下特征
支持多种类型数据支持class、number、boolean、string强类型数据的值类型和引用类型以及这些强类型构成的数组即Arrayclass、Arraystring、Arrayboolean、Arraynumber。不支持object和any。支持多实例组件不同实例的内部状态数据独立。内部私有标记为State的属性是私有变量只能在组件内访问。需要本地初始化必须为所有State变量分配初始值变量未初始化可能导致未定义的框架异常行为。创建自定义组件时支持通过状态变量名设置初始值在创建组件实例时可以通过变量名显式指定State状态变量的初始值。
示例
在下面的示例中 用户定义的组件MyComponent定义了State状态变量count和title。如果count或title的值发生变化则执行MyComponent的build方法来重新渲染组件 EntryComponent中有多个MyComponent组件实例第一个MyComponent内部状态的更改不会影响第二个MyComponent 创建MyComponent实例时通过变量名给组件内的变量进行初始化如 MyComponent({ title: { value: Hello World 2 }, count: 7 })
// Test_State.ets
class Model {value: stringconstructor(value: string) {this.value value}
}Entry
Component
struct EntryComponent {build() {Column() {MyComponent({ count: 1, increaseBy: 2 }) // 第1个MyComponent实例MyComponent({ title: { value: Hello World 2 }, count: 7 }) // 第2个MyComponent实例}}
}Component
struct MyComponent {State title: Model { value: Hello World }State count: number 0private toggle: string Hello Worldprivate increaseBy: number 1build() {Column() {Text(${this.title.value}).fontSize(30)Button(Click to change title).margin(20).onClick(() {// 修改内部状态变量titlethis.title.value (this.toggle this.title.value) ? Hello World : Hello ArkUI})Button(Click to increase count${this.count}).margin(20).onClick(() {// 修改内部状态变量countthis.count this.increaseBy})}}
}
2.2.2 - Prop
Prop与State有相同的语义但初始化方式不同。Prop装饰的变量必须使用其父组件提供的State变量进行初始化允许组件内部修改Prop变量但变量的更改不会通知给父组件父组件变量的更改会同步到prop装饰的变量即Prop属于单向数据绑定。
Prop状态数据具有以下特征
支持简单类型仅支持number、string、boolean等简单数据类型私有仅支持组件内访问支持多个实例一个组件中可以定义多个标有Prop的属性创建自定义组件时将值传递给Prop变量进行初始化在创建组件的新实例时必须初始化所有Prop变量不支持在组件内部进行初始化。
示例
在下面的示例中当按“1”或“-1”按钮时父组件状态发生变化重新执行build方法此时将创建一个新的CountDownComponent组件实例。父组件的countDownStartValue状态变量被用于初始化子组件的Prop变量当按下子组件的“count - costOfOneAttempt”按钮时其Prop变量count将被更改CountDownComponent重新渲染但是count值的更改不会影响父组件的countDownStartValue值。 // Test_Prop.ets
Entry
Component
struct ParentComponent {State countDownStartValue: number 10 // 初始化countDownStartValuebuild() {Column() {Text(Grant ${this.countDownStartValue} nuggets to play.).fontSize(18)Button(1 - Nuggets in New Game).margin(15).onClick(() {this.countDownStartValue 1})Button(-1 - Nuggets in New Game).margin(15).onClick(() {this.countDownStartValue - 1})// 创建子组件时必须在构造函数参数中提供其Prop变量count的初始值同时初始化常规变量costOfOneAttempt非Prop变量CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })}}
}Component
struct CountDownComponent {Prop count: numberprivate costOfOneAttempt: numberbuild() {Column() {if (this.count 0) {Text(You have ${this.count} Nuggets left).fontSize(18)} else {Text(Game over!).fontSize(18)}Button(count - costOfOneAttempt).margin(15).onClick(() {this.count - this.costOfOneAttempt})}}
}
2.2.3 - Link
Link装饰的变量可以和父组件的State变量建立双向数据绑定
支持多种类型Link支持的数据类型与State相同即class、number、string、boolean或这些类型的数组私有仅支持组件内访问单个数据源父组件中用于初始化子组件Link变量的必须是State变量双向通信子组件对Link变量的更改将同步修改父组件中的State变量创建自定义组件时需要将变量的引用传递给Link变量在创建组件的新实例时必须使用命名参数初始化所有Link变量。Link变量可以使用State变量或Link变量的引用进行初始化State变量可以通过$操作符创建引用。
说明
Link变量不能在组件内部进行初始化。
简单类型示例
Link语义是从$操作符引出即$isPlaying是this.isPlaying内部状态的双向数据绑定。当单击子组件PlayButton中的按钮时Link变量更改PlayButton与父组件中的Text和Button将同时进行刷新同样地当点击父组件中的Button修改this.isPlaying时子组件PlayButton与父组件中的Text和Button也将同时刷新。
// Test_Link.ets
Entry
Component
struct Player {State isPlaying: boolean falsebuild() {Column() {PlayButton({ buttonPlaying: $isPlaying })Text(Player is ${this.isPlaying ? : not} playing).fontSize(18)Button(Parent: this.isPlaying).margin(15).onClick(() {this.isPlaying !this.isPlaying})}}
}Component
struct PlayButton {Link buttonPlaying: booleanbuild() {Column() {Button(this.buttonPlaying ? pause : play).margin(20).onClick(() {this.buttonPlaying !this.buttonPlaying})}}
}
复杂类型示例
// Test_Link.ets
Entry
Component
struct Parent {State arr: number[] [1, 2, 3]build() {Column() {Child({ items: $arr })Button(Parent Button: splice).margin(10).onClick(() {this.arr.splice(0, 1, 60)})ForEach(this.arr, item {Text(item.toString()).fontSize(18).margin(10)}, item item.toString())}}
}Component
struct Child {Link items: number[]build() {Column() {Button(Child Button1: push).margin(15).onClick(() {this.items.push(100)})Button(Child Button2: replace whole item).margin(15).onClick(() {this.items [100, 200, 300]})}}
}
Link、State和Prop结合使用示例
下面示例中ParentView包含ChildA和ChildB两个子组件ParentView的状态变量counter分别用于初始化ChildA的Prop变量和ChildB的Link变量。
ChildB使用Link建立双向数据绑定当ChildB修改counterRef状态变量值时该更改将同步到ParentView和ChildA共享ChildA使用Prop建立从ParentView到自身的单向数据绑定当ChildA修改counterVal状态变量值时ChildA将重新渲染但该更改不会传达给ParentView和ChildB。
// Test_Combine.ets
Entry
Component
struct ParentView {State counter: number 0build() {Column() {ChildA({ counterVal: this.counter })ChildB({ counterRef: $counter })}}
}Component
struct ChildA {Prop counterVal: numberbuild() {Button(ChildA: (${this.counterVal}) 1).margin(15).onClick(() {this.counterVal 1})}
}Component
struct ChildB {Link counterRef: numberbuild() {Button(ChildB: (${this.counterRef}) 1).margin(15).onClick(() {this.counterRef 1})}
}
2.2.4 - Observed和ObjectLink数据管理
当开发者需要在子组件中针对父组件的一个变量(parent_a)设置双向同步时开发者可以在父组件中使用State装饰变量(parent_a)并在子组件中使用Link装饰对应的变量(child_a)。这样不仅可以实现父组件与单个子组件之间的数据同步也可以实现父组件与多个子组件之间的数据同步。如下图所示可以看到父子组件针对ClassA类型的变量设置了双向同步那么当子组件1中变量对应的属性c的值变化时会通知父组件同步变化而当父组件中属性c的值变化时会通知所有子组件同步变化。 然而上述例子是针对某个数据对象进行的整体同步而当开发者只想针对父组件中某个数据对象的部分信息进行同步时使用Link就不能满足要求。如果这些部分信息是一个类对象就可以使用ObjectLink配合Observed来实现如下图所示。 设置要求 Observed用于类ObjectLink用于变量。 ObjectLink装饰的变量类型必须为类(class type)。 类要被Observed装饰器所装饰。不支持简单类型参数可以使用Prop进行单向同步。 ObjectLink装饰的变量是不可变的。 属性的改动是被允许的当改动发生时如果同一个对象被多个ObjectLink变量所引用那么所有拥有这些变量的自定义组件都会被通知进行重新渲染。 ObjectLink装饰的变量不可设置默认值。 必须让父组件中有一个由State、Link、StorageLink、Provide或Consume装饰的变量所参与的TS表达式进行初始化。 ObjectLink装饰的变量是私有变量只能在组件内访问。
示例
// Test_ObjectLink.ets
// 父组件ViewB中的类对象ClassA与子组件ViewA保持数据同步时可以使用ObjectLink和Observed绑定该数据对象的父组件和其他子组件同步更新
var nextID: number 0Observed
class ClassA {public name: stringpublic c: numberpublic id: numberconstructor(c: number, name: string OK) {this.name namethis.c cthis.id nextID}
}Component
struct ViewA {label: string ViewA1ObjectLink a: ClassAbuild() {Row() {Button(ViewA [${this.label}] this.a.c ${this.a.c} 1).onClick(() {this.a.c 1})}.margin({ top: 10 })}
}Entry
Component
struct ViewB {State arrA: ClassA[] [new ClassA(0), new ClassA(0)]build() {Column() {ForEach(this.arrA, (item) {ViewA({ label: #${item.id}, a: item })}, (item) item.id.toString())ViewA({ label: this.arrA[first], a: this.arrA[0] })ViewA({ label: this.arrA[last], a: this.arrA[this.arrA.length - 1] })Button(ViewB: reset array).margin({ top: 10 }).onClick(() {this.arrA [new ClassA(0), new ClassA(0)]})Button(ViewB: push).margin({ top: 10 }).onClick(() {this.arrA.push(new ClassA(0))})Button(ViewB: shift).margin({ top: 10 }).onClick(() {this.arrA.shift()})}.width(100%)}
}
2.2.5 - Consume和Provide
Provide作为数据的提供方可以更新其子孙节点的数据并触发页面渲染。Consume在感知到Provide数据的更新后会触发当前自定义组件的重新渲染。
说明
使用Provide和Consume时应避免循环引用导致死循环。 Provide 名称说明装饰器参数是一个string类型的常量用于给装饰的变量起别名。如果规定别名则提供对应别名的数据更新。如果没有则使用变量名作为别名。推荐使用Provide(alias)这种形式。同步机制Provide的变量类似State可以修改对应变量进行页面重新渲染。也可以修改Consume装饰的变量反向修改State变量。初始值必须设置初始值。页面重渲染场景 触发页面渲染的修改 - 基础类型(booleanstringnumber)变量的改变 - Observed class类型变量及其属性的修改 - 添加删除更新数组中的元素。 Consume 类型说明初始值不可设置默认初始值
示例
// Test_consume.ets
Entry
Component
struct CompA {Provide(reviewVote) reviewVotes: number 0;build() {Column() {CompB()Button(CompA: ${this.reviewVotes}).margin(10).onClick(() {this.reviewVotes 1;})}}
}Component
struct CompB {build() {Column() {CompC()}}
}Component
struct CompC {Consume(reviewVote) reviewVotes: numberbuild() {Column() {Button(CompC: ${this.reviewVotes}).margin(10).onClick(() {this.reviewVotes 1})}.width(100%)}
}
2.2.6 - Watch
Watch用于监听状态变量的变化语法结构为
State Watch(onChanged) count : number 0
如上所示给状态变量增加一个Watch装饰器通过Watch注册一个回调方法onChanged 当状态变量count被改变时 触发onChanged回调。
装饰器State、Prop、Link、ObjectLink、Provide、Consume、StorageProp以及StorageLink所装饰的变量均可以通过Watch监听其变化。
// Test_Watch.ets
Entry
Component
struct CompA {State Watch(onBasketUpdated) shopBasket: Arraynumber [7, 12, 47, 3]State totalPurchase: number 0State addPurchase: number 0aboutToAppear() {this.updateTotal()}updateTotal(): number {let sum 0;this.shopBasket.forEach((i) {sum i})// 计算新的购物篮总价值如果超过100则适用折扣this.totalPurchase (sum 100) ? sum : 0.9 * sumreturn this.totalPurchase}// shopBasket更改时触发该方法onBasketUpdated(propName: string): void {this.updateTotal()}build() {Column() {Button(add to basket this.addPurchase).margin(15).onClick(() {this.addPurchase Math.round(100 * Math.random())this.shopBasket.push(this.addPurchase)})Text(${this.totalPurchase}).fontSize(30)}}
}
2.3 - 应用级变量的状态管理
2.3.1 - AppStorage
AppStorage是应用程序中的单例对象由UI框架在应用程序启动时创建在应用程序退出时销毁为应用程序范围内的可变状态属性提供中央存储。
AppStorage包含整个应用程序中需要访问的所有状态属性只要应用程序保持运行AppStorage就会保存所有属性及属性值属性值可以通过唯一的键值进行访问。
组件可以通过装饰器将应用程序状态数据与AppStorage进行同步应用业务逻辑的实现也可以通过接口访问AppStorage。
AppStorage的选择状态属性可以与不同的数据源或数据接收器同步这些数据源和接收器可以是设备上的本地或远程并具有不同的功能如数据持久性。这样的数据源和接收器可以独立于UI在业务逻辑中实现。
默认情况下AppStorage中的属性是可变的AppStorage还可使用不可变(只读)属性。
StorageLink装饰器
组件通过使用StorageLink(key)装饰的状态变量与AppStorage建立双向数据绑定key为AppStorage中的属性键值。当创建包含StorageLink的状态变量的组件时该状态变量的值将使用AppStorage中的值进行初始化。在UI组件中对StorageLink的状态变量所做的更改将同步到AppStorage并从AppStorage同步到任何其他绑定实例中如PersistentStorage或其他绑定的UI组件。
StorageProp装饰器
组件通过使用StorageProp(key)装饰的状态变量将与AppStorage建立单向数据绑定key标识AppStorage中的属性键值。当创建包含StoageProp的状态变量的组件时该状态变量的值将使用AppStorage中的值进行初始化。AppStorage中的属性值的更改会导致绑定的UI组件进行状态更新。
示例
每次用户单击Count按钮时this.varA变量值都会增加此变量与AppStorage中的varA同步。每次用户单击当前语言按钮时修改AppStorage中的languageCode此修改会同步给this.lang变量。
// Test_AppStorage.etsEntry
Component
struct ComponentA {StorageLink(varA) varA: number 2StorageProp(languageCode) lang: string enprivate label: string countaboutToAppear() {this.label (this.lang zh) ? 数 : Count}build() {Column(){Row({ space: 20 }) {Button(${this.label}: ${this.varA}).onClick(() {AppStorage.Setnumber(varA, AppStorage.Getnumber(varA) 1)})Button(lang: ${this.lang}).onClick(() {if (this.lang zh) {AppStorage.Setstring(languageCode, en)} else {AppStorage.Setstring(languageCode, zh)}this.label (this.lang zh) ? 数 : Count})}.margin({ bottom: 50 })Row(){Button(更改StorageLink修饰的变量${this.varA}).fontSize(10).onClick(() {this.varA})}.margin({ bottom: 50 })Row(){Button(更改StorageProp修饰的变量${this.lang}).fontSize(10).onClick(() {this.lang test})}}}
} 2.3.2 - PersistentStorage
PersistentStorage类提供了一些静态方法用来管理应用持久化数据可以将特定标记的持久化数据链接到AppStorage中并由AppStorage接口访问对应持久化数据或者通过StorageLink装饰器来访问对应key的变量。
说明
PersistProp接口使用时需要保证输入对应的key应当在AppStorage存在。DeleteProp接口使用时只能对本次启动已经link过的数据生效。
// Test_PersistentStorage.ets
PersistentStorage.PersistProp(highScore, 0);Entry
Component
struct PersistentComponent {StorageLink(highScore) highScore: string 0State currentScore: number 0build() {Column() {if (this.currentScore Number(this.highScore)) {Text(new highScore : ${this.highScore})}Button() {Text(goal!, currentScore : ${this.currentScore}).fontSize(10)}.onClick(() {this.currentScoreif (this.currentScore Number(this.highScore)) {this.highScore this.currentScore.toString()}})}}
}
2.3.3 - Environment
Environment是框架在应用程序启动时创建的单例对象它为AppStorage提供了一系列应用程序需要的环境状态属性这些属性描述了应用程序运行的设备环境。Environment及其属性是不可变的所有属性值类型均为简单类型。如下示例展示了从Environment获取语音环境
Environment.EnvProp(accessibilityEnabled, default);
var enable AppStorage.Get(accessibilityEnabled);
accessibilityEnabled是Environment提供默认系统变量识别符。首先需要将对应系统属性绑定到AppStorage中再通过AppStorage中的方法或者装饰器访问对应系统的属性数据。 感谢各位大佬支持
互三啦