??一、ArkTS語言基本語法
??1.簡介
HarmonyOS的ArkTS語言是一種基于TypeScript開發(fā)的語言,它專為HarmonyOS系統(tǒng)開發(fā)而設(shè)計(jì)。ArkTS語言結(jié)合了JavaScript的靈活性和TypeScript的嚴(yán)謹(jǐn)性,使得開發(fā)者能夠快速、高效地開發(fā)出高質(zhì)量的HarmonyOS應(yīng)用程序。
ArkTS語言具有以下特點(diǎn):
靜態(tài)類型檢查:開發(fā)者在編寫代碼時(shí)可以使用類型注解來進(jìn)行類型檢查,從而減少因類型錯(cuò)誤而導(dǎo)致的bug。
異步/同步編程:ArkTS語言支持基于Promise和async/await的異步/同步編程方式,能夠更好地處理異步操作。
內(nèi)置模塊:ArkTS語言內(nèi)置了許多常用的模塊,如文件系統(tǒng)、網(wǎng)絡(luò)請(qǐng)求、圖形渲染等,使得開發(fā)者不必自己編寫這些模塊。
兼容性:ArkTS語言使用TypeScript語法,可以與JavaScript代碼無縫集成,并且可以編譯成JavaScript代碼來在其他平臺(tái)上運(yùn)行。
ArkTS語言基礎(chǔ)類庫是HarmonyOS系統(tǒng)上為應(yīng)用開發(fā)者提供的常用基礎(chǔ)能力,主要包含能力如下圖所示:
ArkTS是HarmonyOS優(yōu)選的主力應(yīng)用開發(fā)語言。ArkTS圍繞應(yīng)用開發(fā)在TypeScript(簡稱TS)生態(tài)基礎(chǔ)上做了進(jìn)一步擴(kuò)展,繼承了TS的所有特性,是TS的超集。
ArkTS和HTML的差別:
??2.TypeScript的基礎(chǔ)語法
TypeScript是一種由微軟開發(fā)的JavaScript超集語言,它支持JavaScript的所有語法,但添加了一些新的特性和語法,使開發(fā)更加可靠和高效。TypeScript最大的特點(diǎn)是引入了靜態(tài)類型,開發(fā)者可以在編譯時(shí)發(fā)現(xiàn)類型錯(cuò)誤,提高代碼的可維護(hù)性和可讀性。
TypeScript代碼可以在編譯時(shí)被轉(zhuǎn)換成JavaScript代碼,在瀏覽器和Node.js環(huán)境下都可以運(yùn)行。雖然TypeScript相對(duì)于JavaScript來說更加復(fù)雜,但是它可以幫助開發(fā)者更好地組織和管理復(fù)雜的項(xiàng)目,特別是在團(tuán)隊(duì)協(xié)作中提高代碼的質(zhì)量和可維護(hù)性。
TypeScript基礎(chǔ)知識(shí)包括基本類型、變量聲明、函數(shù)、類、接口、泛型等。另外,TypeScript還支持模塊化開發(fā),可以使用ES模塊規(guī)范或者CommonJS規(guī)范導(dǎo)入和導(dǎo)出模塊。在實(shí)際項(xiàng)目開發(fā)中,TypeScript還可以結(jié)合工具鏈如Webpack、Babel進(jìn)行編譯、打包等操作。
除了上面提到的變量聲明、函數(shù)定義、類定義、接口定義和枚舉類型外,TypeScript還有一些基礎(chǔ)語法需要掌握:
??2.1 類型注解
TypeScript的靜態(tài)類型檢查是通過類型注解實(shí)現(xiàn)的。在聲明變量或函數(shù)時(shí),可以使用冒號(hào)加上類型注解,指定變量或函數(shù)的類型。例如:
let name: string = "TypeScript";
function add(a: number, b: number): number {
return a + b;
}
??2.2 接口
TypeScript的接口是用來描述對(duì)象的形狀的??梢远x對(duì)象需要包含哪些屬性和方法,以及它們的類型。例如:
interface Person {
name: string;
age: number;
sayHello(): void;
}
let tom: Person = {
name: "Tom",
age: 18,
sayHello: function() {
console.log(`Hello, my name is ${this.name}!`);
}
};
??2.3 泛型
TypeScript的泛型可以幫助我們編寫更加靈活、可重用的代碼。它允許在編寫函數(shù)、類或接口時(shí)使用參數(shù)化類型,從而提高代碼的通用性和可讀性。例如:
function identity<T>(arg: T): T {
<details>
<summary>點(diǎn)擊查看代碼</summary>
function identity(arg: T): T {return arg;}
let output = identity("TypeScript");console.log(output); // 輸出 TypeScript
</details>
return arg;
}
let output = identity<string>("TypeScript");
console.log(output); // 輸出 TypeScript
??2.4 類的繼承
TypeScript的類可以繼承其他類,從而實(shí)現(xiàn)代碼的重用和擴(kuò)展。通過關(guān)鍵字extends可以讓一個(gè)類繼承另一個(gè)類,并繼承其屬性和方法。例如:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0) {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Dog extends Animal {
bark() {
console.log("Woof! Woof!");
}
}
let dog = new Dog("Bobby");
dog.move(10); // 輸出 "Bobby moved 10m."
dog.bark(); // 輸出 "Woof! Woof!"
??2.5 類的訪問修飾符
TypeScript的類可以通過訪問修飾符來控制類的屬性和方法的訪問權(quán)限。有三個(gè)訪問修飾符可以使用:public、private和protected。默認(rèn)情況下,都是public。
public:公共的,任何外部或內(nèi)部都可以訪問。
private:私有的,只有類的內(nèi)部可以訪問,外部無法訪問。
protected:受保護(hù)的,只有類的內(nèi)部和其子類可以訪問,外部無法訪問。
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
protected sayHello() {
console.log(`Hello, I'm ${this.name}.`);
}
}
class Student extends Person {
constructor(name: string) {
super(name);
}
public sayHelloToTeacher(teacher: Person) {
console.log(`Hello, ${teacher.name}, I'm ${this.name}.`);
}
}
let tom = new Student("Tom");
let bob = new Person("Bob");
tom.sayHelloToTeacher(bob); // 輸出 "Hello, Bob, I'm Tom."
bob.sayHello(); // 報(bào)錯(cuò):屬性 'sayHello' 受保護(hù),只能在類 'Person' 及其子類中訪問。
以上只是舉例一些TS的基礎(chǔ)語法,TS內(nèi)容遠(yuǎn)不止這些不懂的可以去學(xué)學(xué)TS。
??3.ArkTS的基本組成
裝飾器:用于裝飾類、結(jié)構(gòu)、方法以及變量,并賦予其特殊的含義。如上述示例中@Entry、@Component和@State都是裝飾器,@Component表示自定義組件,@Entry表示該自定義組件為入口組件,@State表示組件中的狀態(tài)變量,狀態(tài)變量變化會(huì)觸發(fā)UI刷新。
UI描述:以聲明式的方式來描述UI的結(jié)構(gòu),例如build()方法中的代碼塊。
自定義組件:可復(fù)用的UI單元,可組合其他組件,如上述被@Component裝飾的struct Hello。
系統(tǒng)組件:ArkUI框架中默認(rèn)內(nèi)置的基礎(chǔ)和容器組件,可直接被開發(fā)者調(diào)用,比如示例中的Column、Text、Divider、Button。
屬性方法:組件可以通過鏈?zhǔn)秸{(diào)用配置多項(xiàng)屬性,如fontSize()、width()、height()、backgroundColor()等。
事件方法:組件可以通過鏈?zhǔn)秸{(diào)用設(shè)置多個(gè)事件的響應(yīng)邏輯,如跟隨在Button后面的onClick()。系統(tǒng)組件、屬性方法、事件方法具體使用可參考基于ArkTS的聲明式開發(fā)范式。
除此之外,ArkTS擴(kuò)展了多種語法范式來使開發(fā)更加便捷:
@Builder/@BuilderParam:特殊的封裝UI描述的方法,細(xì)粒度的封裝和復(fù)用UI描述。
@Extend/@Style:擴(kuò)展內(nèi)置組件和封裝屬性樣式,更靈活地組合內(nèi)置組件。stateStyles:多態(tài)樣式,可以依據(jù)組件的內(nèi)部狀態(tài)的不同,設(shè)置不同樣式。
??4.自定義組件
@Component
struct HelloComponent {
@State message: string = 'Hello, World!';
build() {
// HelloComponent自定義組件組合系統(tǒng)組件Row和Text
Row() {
Text(this.message)
.onClick(() => {
// 狀態(tài)變量message的改變驅(qū)動(dòng)UI刷新,UI從'Hello, World!'刷新為'Hello, ArkUI!'
this.message = 'Hello, ArkUI!';
})
}
}
}
@Entry
@Component
struct ParentComponent {
build() {
Column() {
Text('ArkUI message')
HelloComponent({ message: 'Hello, World!' });
Divider()
HelloComponent({ message: '你好!' });
}
}
}
struct:自定義組件基于struct實(shí)現(xiàn),struct + 自定義組件名 +{…}的組合構(gòu)成自定義組件,不能有繼承關(guān)系。對(duì)于struct的實(shí)例化,可以省略new。
build()函數(shù):build()函數(shù)用于定義自定義組件的聲明式UI描述,自定義組件必須定義build()函數(shù)。
@Entry:@Entry裝飾的自定義組件將作為UI頁面的入口。在單個(gè)UI頁面中,最多可以使用@Entry裝飾一個(gè)自定義組件。@Entry可以接受一個(gè)可選的LocalStorage的參數(shù)。
??4.1 build()函數(shù)規(guī)范1、根節(jié)點(diǎn)唯一
@Entry
@Component
struct MyComponent {
build() {
// 根節(jié)點(diǎn)唯一且必要,必須為容器組件
Row() {
ChildComponent()
}
}
}
@Component
struct ChildComponent {
build() {
// 根節(jié)點(diǎn)唯一且必要,可為非容器組件
Image('test.jpg')
}
}
2、不允許聲明本地變量、打印、作用域
build() {
// 反例:不允許聲明本地變量
let a: number = 1;
// 反例:不允許console.info
console.info('print debug log');
// 反例:不允許本地作用域
{
...
}
}
3、不允許調(diào)用沒有用@Builder裝飾的方法,允許系統(tǒng)組件的參數(shù)是TS方法的返回值。
@Component
struct ParentComponent {
doSomeCalculations() {
}
calcTextValue(): string {
return 'Hello World';
}
@Builder doSomeRender() {
Text(`Hello World`)
}
build() {
Column() {
// 反例:不能調(diào)用沒有用@Builder裝飾的方法
this.doSomeCalculations();
// 正例:可以調(diào)用
this.doSomeRender();
// 正例:參數(shù)可以為調(diào)用TS方法的返回值
Text(this.calcTextValue())
}
}
}
4、不允許switch和表達(dá)式
build() {
Column() {
// 反例:不允許使用switch語法
switch (expression) {
case 1:
Text('...')
break;
case 2:
Image('...')
break;
default:
Text('...')
break;
}
// 反例:不允許使用表達(dá)式
(this.aVar > 10) ? Text('...') : Image('...')
}
}
??5.頁面和自定義組件生命周期
頁面生命周期,即被@Entry裝飾的組件生命周期,提供以下生命周期接口:
-
onPageShow:頁面每次顯示時(shí)觸發(fā)。
-
onPageHide:頁面每次隱藏時(shí)觸發(fā)一次。
-
onBackPress:當(dāng)用戶點(diǎn)擊返回按鈕時(shí)觸發(fā)。
組件生命周期,即一般用@Component裝飾的自定義組件的生命周期,提供以下生命周期接口:
-
aboutToAppear:組件即將出現(xiàn)時(shí)回調(diào)該接口,具體時(shí)機(jī)為在創(chuàng)建自定義組件的新實(shí)例后,在執(zhí)行其build()函數(shù)之前執(zhí)行。
-
aboutToDisappear:在自定義組件即將析構(gòu)銷毀時(shí)執(zhí)行。
// Index.ets
import router from '@ohos.router';
@Entry
@Component
struct MyComponent {
@State showChild: boolean = true;
// 只有被@Entry裝飾的組件才可以調(diào)用頁面的生命周期
onPageShow() {
console.info('Index onPageShow');
}
// 只有被@Entry裝飾的組件才可以調(diào)用頁面的生命周期
onPageHide() {
console.info('Index onPageHide');
}
// 只有被@Entry裝飾的組件才可以調(diào)用頁面的生命周期
onBackPress() {
console.info('Index onBackPress');
}
// 組件生命周期
aboutToAppear() {
console.info('MyComponent aboutToAppear');
}
// 組件生命周期
aboutToDisappear() {
console.info('MyComponent aboutToDisappear');
}
build() {
Column() {
// this.showChild為true,創(chuàng)建Child子組件,執(zhí)行Child aboutToAppear
if (this.showChild) {
Child()
}
// this.showChild為false,刪除Child子組件,執(zhí)行Child aboutToDisappear
Button('create or delete Child').onClick(() => {
this.showChild = false;
})
// push到Page2頁面,執(zhí)行onPageHide
Button('push to next page')
.onClick(() => {
router.pushUrl({ url: 'pages/Page2' });
})
}
}
}
@Component
struct Child {
@State title: string = 'Hello World';
// 組件生命周期
aboutToDisappear() {
console.info('[lifeCycle] Child aboutToDisappear')
}
// 組件生命周期
aboutToAppear() {
console.info('[lifeCycle] Child aboutToAppear')
}
build() {
Text(this.title).fontSize(50).onClick(() => {
this.title = 'Hello ArkUI';
})
}
}
??6.裝飾函數(shù)
??6.1 @Builder裝飾器
@Builder主要是定義頁面UI
??6.1.1 裝飾指向
1、自定義組件內(nèi)自定義構(gòu)建函數(shù)
@Builder MyBuilderFunction(){ ... }
#使用
this.MyBuilderFunction(){ ... }
2、MyGlobalBuilderFunction()
@Builder function MyGlobalBuilderFunction(){ ... }
#使用
MyGlobalBuilderFunction()
??6.1.2 參數(shù)傳遞
1、按引用傳遞參數(shù)
@Builder function ABuilder($$: { paramA1: string }) {
Row() {
Text(`UseStateVarByReference: ${$$.paramA1} `)
}
}
@Entry
@Component
struct Parent {
@State label: string = 'Hello';
build() {
Column() {
// 在Parent組件中調(diào)用ABuilder的時(shí)候,將this.label引用傳遞給ABuilder
ABuilder({ paramA1: this.label })
Button('Click me').onClick(() => {
// 點(diǎn)擊“Click me”后,UI從“Hello”刷新為“ArkUI”
this.label = 'ArkUI';
})
}
}
}
2、按值傳遞參數(shù)
@Builder function ABuilder(paramA1: string) {
Row() {
Text(`UseStateVarByValue: ${paramA1} `)
}
}
@Entry
@Component
struct Parent {
label: string = 'Hello';
build() {
Column() {
ABuilder(this.label)
}
}
}
??6.2 @BuilderParam裝飾器
@BuilderParam用來裝飾指向@Builder方法的變量,開發(fā)者可在初始化自定義組件時(shí)對(duì)此屬性進(jìn)行賦值,為自定義組件增加特定的功能。
??6.2.1 裝飾指向
1、本地初始化@BuilderParam
@Builder function GlobalBuilder0() {}
@Component
struct Child {
@Builder doNothingBuilder() {};
@BuilderParam aBuilder0: () => void = this.doNothingBuilder;
@BuilderParam aBuilder1: () => void = GlobalBuilder0;
build(){}
}
2、初始化子組件@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 })
}
}
}
this都是器其本身,不會(huì)存在傳遞。
??6.2.2 使用場景
1、參數(shù)化傳遞
@Builder function GlobalBuilder1($$ : {label: string }) {
Text($$.label)
.width(400)
.height(50)
.backgroundColor(Color.Blue)
}
@Component
struct Child {
label: string = 'Child'
// 無參數(shù)類,指向的componentBuilder也是無參數(shù)類型
@BuilderParam aBuilder0: () => void;
// 有參數(shù)類型,指向的GlobalBuilder1也是有參數(shù)類型的方法
@BuilderParam aBuilder1: ($$ : { label : string}) => void;
build() {
Column() {
this.aBuilder0()
this.aBuilder1({label: 'global Builder label' } )
}
}
}
@Entry
@Component
struct Parent {
label: string = 'Parent'
@Builder componentBuilder() {
Text(`${this.label}`)
}
build() {
Column() {
this.componentBuilder()
Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })
}
}
}
2、尾隨閉包
// xxx.ets
@Component
struct CustomContainer {
@Prop header: string;
@BuilderParam closer: () => void
build() {
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() {
// 創(chuàng)建CustomContainer,在創(chuàng)建CustomContainer時(shí),通過其后緊跟一個(gè)大括號(hào)“{}”形成尾隨閉包
// 作為傳遞給子組件CustomContainer @BuilderParam closer: () => void的參數(shù)
CustomContainer({ header: this.text }) {
Column() {
specificParam('testA', 'testB')
}.backgroundColor(Color.Yellow)
.onClick(() => {
this.text = 'changeHeader';
})
}
}
}
}
??6.3 @Styles裝飾器
@Styles裝飾器主要是定義公共樣式
??6.3.1 裝飾指向
1、全局
// 全局
@Styles function functionName() { ... }
// 在組件內(nèi)
@Component
struct FancyUse {
@Styles fancy() {
.height(100)
}
}
2、組件內(nèi)
@Component
struct FancyUse {
@State heightValue: number = 100
@Styles fancy() {
.height(this.heightValue)
.backgroundColor(Color.Yellow)
.onClick(() => {
this.heightValue = 200
})
}
}
??6.3.2 使用場景
// 定義在全局的@Styles封裝的樣式
@Styles function globalFancy () {
.width(150)
.height(100)
.backgroundColor(Color.Pink)
}
@Entry
@Component
struct FancyUse {
@State heightValue: number = 100
// 定義在組件內(nèi)的@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)
// 使用組件內(nèi)的@Styles封裝的樣式
Text('FancyB')
.fancy()
.fontSize(30)
}
}
}
??6.4 @Extend裝飾器
@Extend用于擴(kuò)展原生組件樣式,作用和@Styles差不多。
??6.4.1 裝飾指向@Extend僅支持定義在全局,不支持在組件內(nèi)部定義
1、@Extend支持封裝指定的組件的私有屬性和私有事件
// @Extend(Text)可以支持Text的私有屬性fontColor
@Extend(Text) function fancy () {
.fontColor(Color.Red)
}
// superFancyText可以調(diào)用預(yù)定義的fancy
@Extend(Text) function superFancyText(size:number) {
.fontSize(size)
.fancy()
}
2、@Extend裝飾的方法支持參數(shù)
// xxx.ets
@Extend(Text) function fancy (fontSize: number) {
.fontColor(Color.Red)
.fontSize(fontSize)
}
@Entry
@Component
struct FancyUse {
build() {
Row({ space: 10 }) {
Text('Fancy')
.fancy(16)
Text('Fancy')
.fancy(24)
}
}
}
3、@Extend裝飾的方法的參數(shù)可以為function
@Extend(Text) function makeMeClick(onClick: () => void) {
.backgroundColor(Color.Blue)
.onClick(onClick)
}
@Entry
@Component
struct FancyUse {
@State label: string = 'Hello World';
onClickHandler() {
this.label = 'Hello ArkUI';
}
build() {
Row({ space: 10 }) {
Text(`${this.label}`)
.makeMeClick(this.onClickHandler.bind(this))
}
}
}
4、@Extend的參數(shù)可以為狀態(tài)變量
@Extend(Text) function fancy (fontSize: number) {
.fontColor(Color.Red)
.fontSize(fontSize)
}
@Entry
@Component
struct FancyUse {
@State fontSizeValue: number = 20
build() {
Row({ space: 10 }) {
Text('Fancy')
.fancy(this.fontSizeValue)
.onClick(() => {
this.fontSizeValue = 30
})
}
}
}
??6.4.2 使用場景
@Extend(Text) function fancyText(weightValue: number, color: Color) {
.fontStyle(FontStyle.Italic)
.fontWeight(weightValue)
.backgroundColor(color)
}
@Entry
@Component
struct FancyUse {
@State label: string = 'Hello World'
build() {
Row({ space: 10 }) {
Text(`${this.label}`)
.fancyText(100, Color.Blue)
Text(`${this.label}`)
.fancyText(200, Color.Pink)
Text(`${this.label}`)
.fancyText(300, Color.Orange)
}.margin('20%')
}
}
??7.多態(tài)樣式
stateStyles是屬性方法,可以根據(jù)UI內(nèi)部狀態(tài)來設(shè)置樣式,類似于css偽類,但語法不同。ArkUI提供以下四種狀態(tài):
-
focused:獲焦態(tài)
-
normal:正常態(tài)
-
pressed:按壓態(tài)
-
disabled:不可用態(tài)
??7.1 基本使用
@Entry
@Component
struct CompWithInlineStateStyles {
@State focusedColor: Color = Color.Red;
normalColor: Color = Color.Green
build() {
Column() {
Button('clickMe').height(100).width(100)
.stateStyles({
normal: {
.backgroundColor(this.normalColor)
},
focused: {
.backgroundColor(this.focusedColor)
}
})
.onClick(() => {
this.focusedColor = Color.Pink
})
.margin('30%')
}
}
}
??7.2 @Styles和stateStyles聯(lián)合使用
@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,
})
}
}
}
??7.3 stateStyles里使用常規(guī)變量和狀態(tài)變量
@Entry
@Component
struct CompWithInlineStateStyles {
@State focusedColor: Color = Color.Red;
normalColor: Color = Color.Green
build() {
Button('clickMe').height(100).width(100)
.stateStyles({
normal: {
.backgroundColor(this.normalColor)
},
focused: {
.backgroundColor(this.focusedColor)
}
})
.onClick(() => {
this.focusedColor = Color.Pink
})
.margin('30%')
}
}
文章轉(zhuǎn)載自:蜀道山QAQ
原文鏈接:https://www.cnblogs.com/shudaoshan/p/17968508文章來源:http://www.zghlxwxcb.cn/news/detail-802283.html
體驗(yàn)地址:引邁 - JNPF快速開發(fā)平臺(tái)_低代碼開發(fā)平臺(tái)_零代碼開發(fā)平臺(tái)_流程設(shè)計(jì)器_表單引擎_工作流引擎_軟件架構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-802283.html
到了這里,關(guān)于鴻蒙HarmonyOS實(shí)戰(zhàn)-ArkTS語言(基本語法)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!