一、編程語言介紹
ArkTS是HarmonyOS主力應(yīng)用開發(fā)語言。它在TypeScript(簡稱TS)的基礎(chǔ)上,匹配ArkUI框架,擴(kuò)展了聲明式UI、狀態(tài)管理等相應(yīng)的能力,讓開發(fā)者以更簡潔、更自然的方式開發(fā)跨端應(yīng)用。
- JavaScript是一種屬于網(wǎng)絡(luò)的高級腳本語言,已經(jīng)被廣泛應(yīng)用開發(fā),常用來為網(wǎng)頁添加各式各樣的動態(tài)功能,為用戶提供更流暢美觀的瀏覽效果。
- TypeScript是JavaScript的一個超集,它擴(kuò)展了JavaScript的語法,通過在JavaScript的基礎(chǔ)上添加靜態(tài)類型定義構(gòu)建而成,是一個開源的編程語言。
- ArkTS基于TypeScript語言,擴(kuò)展了聲明式UI、狀態(tài)管理、并發(fā)任務(wù)等能力。
二、TypeScript基礎(chǔ)類型
1. 布爾值
let isDone: boolean = false;
2. 數(shù)字
TypeScript里的所有數(shù)字都是浮點數(shù),這些浮點數(shù)的類型是number。除了支持十進(jìn)制,還支持二進(jìn)制、八進(jìn)制、十六進(jìn)制
let decLiteral: number = 2023;
let binaryLiteral: number = 0b11111100111;
let octalLiteral: number = 0o3747;
let hexLiteral: number = 0x7e7;
console.log('decLiteral is' + decLiteral)
// 結(jié)果都是2023
3. 字符串
let name: string = "Jacky";
4. 數(shù)組
TypeSscript支持兩種方式聲明數(shù)組:
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
5. 元組
let x: [string, number];
x = ['hello', 10]
6. 枚舉
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
7. unknown
有時候,我們會想要為那些在編程階段還不清楚類型的變量指定一個類型。那么我們可以使用 unknown 類型來標(biāo)記這些類型
let notSure: unknown = 4;
notSure = 'maybe a string instead';
notSure = false;
8. void
當(dāng)一個函數(shù)沒有返回值時,通常會見到其返回值類型是void。
function test() void {
console.log('This is function is void');
}
9. null 和 undefined
TypeScript里,undefined 和 null 兩者各自有自己的類型分別叫做 undefined 和 unll。
let u: undefined = undefined;
let n: null = null;
10. 聯(lián)合類型
聯(lián)合類型(Union Types)表示取值可以為多種類型中的一種。
let myFavoriteNumber: string | number;;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
三、TypeScript基礎(chǔ)知識
條件語句
if語句
let num: number = 5;
if (num > 0) {
console.log('數(shù)字是正數(shù)');
}
let num: number = 12;
if (num % 2 == 0) {
console.log('數(shù)字是偶數(shù)');
} else {
console.log('數(shù)字是奇數(shù)');
}
let num: number = 5;
if (num > 0) {
console.log(num + '是正數(shù)');
} else if (num < 0) {
console.log(num + '是負(fù)數(shù)');
} else {
console.log(num + '是0');
}
switch語句
var grade: string = 'A';
switch(grade) {
case 'A': {
console.log('優(yōu)');
break;
}
case 'B': {
console.log('良');
break;
}
case 'C': {
console.log('及格');
break;
}
case 'D': {
console.log('不及格');
break;
}
default: {
console.log('非法輸入');
break;
}
}
函數(shù)定義
有名函數(shù)和匿名函數(shù)
// 有名函數(shù):給變量設(shè)置為number類型
function add(x: number, y: number): number {
return x + y;
}
// 匿名函數(shù):給變量設(shè)置為number類型
let myAdd = function (x: number, y: number): number {
return x + y;
};
可選參數(shù)
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + ' ' + lastName;
else
return firstName;
}
let result1 = buildName('Bob');
let result2 = buildName('Bob', 'Adams');
剩余參數(shù)
剩余參數(shù)會被當(dāng)做個數(shù)不限的可選參數(shù)。 可以一個都沒有,同樣也可以有任意個。 可以使用省略號( …)進(jìn)行定義:
function getEmployeeName(firstName: string, ...restOfName: string[]) {
return firstName + ' ' + restOfName.join(' ');
}
let employeeName = getEmployeeName('Joseph', 'Samuel', 'Lucas', 'MacKinzie');
箭頭函數(shù)
ES6版本的TypeScript提供了一個箭頭函數(shù),它是定義匿名函數(shù)的簡寫語法,用于函數(shù)表達(dá)式,它省略了function關(guān)鍵字。箭頭函數(shù)的定義如下,其函數(shù)是一個語句塊:
( [param1, parma2,…param n] )=> {
// 代碼塊
}
其中,括號內(nèi)是函數(shù)的入?yún)ⅲ梢杂?到多個參數(shù),箭頭后是函數(shù)的代碼塊。我們可以將這個箭頭函數(shù)賦值給一個變量,如下所示:
let arrowFun = ( [param1, parma2,…param n] )=> {
// 代碼塊
}
如果要主動調(diào)用這個箭頭函數(shù),可以按如下方法去調(diào)用:
arrowFun(param1, parma2,…param n)
類
1. 類的定義
TypeScript支持基于類的面向?qū)ο蟮木幊谭绞?,定義類的關(guān)鍵字為class,后面緊跟類名。類描述了所創(chuàng)
建的對象共同的屬性和方法。
聲明一個Person類,這個類有3個成員:一個是屬性(包含name和age),一個是構(gòu)造函數(shù),一個是getPersonInfo方法,其定義如下所示。
class Person {
private name: string
private age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getPersonInfo(): string {
return `My name is ${this.name} and age is ${this.age}`;
}
}
let person1 = new Person('Jacky', 18);
person1.getPersonInfo();
2. 繼承
繼承就是子類繼承父類的特征和行為,使得子類具有父類相同的行為。TypeScript中允許使用繼承來擴(kuò)展現(xiàn)有的類,對應(yīng)的關(guān)鍵字為extends。
class Employee extends Person {
private department: string
constructor(name: string, age: number, department: string) {
super(name, age);
this.department = department;
}
public getEmployeeInfo(): string {
return this.getPersonInfo() + ` and work in ${this.department}`;
}
}
let person2 = new Employee('Tom', 28, 'HuaWei');
person2.getPersonInfo();
person2.getEmployeeInfo();
模塊
隨著應(yīng)用越來越大,通常要將代碼拆分成多個文件,即所謂的模塊(module)。模塊可以相互加載,并可以使用特殊的指令 export 和 import 來交換功能,從另一個模塊調(diào)用一個模塊的函數(shù)。
兩個模塊之間的關(guān)系是通過在文件級別上使用 import 和 export 建立的。模塊里面的變量、函數(shù)和類等在模塊外部是不可見的,除非明確地使用 export 導(dǎo)出它們。類似地,我們必須通過 import 導(dǎo)入其他模塊導(dǎo)出的變量、函數(shù)、類等。
- 導(dǎo)出
export class NewsData {
title: string;
content: string;
imagesUrl: Array<NewsFile>;
source: string;
constructor(title: string, content: string, imagesUrl: Array<NewsFile>, source: string) {
this.title = title;
this.content = content;
this.imagesUrl = imagesUrl;
this.source = source;
}
}
- 導(dǎo)入
import { NewsData } from '../common/bean/NewsData';
迭代器
當(dāng)一個對象實現(xiàn)了Symbol.iterator屬性時,我們認(rèn)為它是可迭代的。一些內(nèi)置的類型如Array,Map,Set,String,Int32Array,Uint32Array等都具有可迭代性。
for…of 語句
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
for…in 語句
let list = [4, 5, 6];
for (let i in list) {
console.log(i); // "0", "1", "2",
}
for (let i of list) {
console.log(i); // "4", "5", "6"
}
四、ArkTS基礎(chǔ)知識
UI規(guī)范描述
ArkUI開發(fā)框架
ArkTS聲明式開發(fā)范式
基本組成說明如下:
-
裝飾器
用來裝飾類、結(jié)構(gòu)體、方法以及變量,賦予其特殊的含義,如上述示例中 @Entry 、 @Component 、 @State 都是裝飾器。具體而言, @Component 表示這是個自定義組件; @Entry 則表示這是個入口組件; @State 表示組件中的狀態(tài)變量,此狀態(tài)變化會引起 UI 變更。 -
自定義組件
可復(fù)用的 UI 單元,可組合其它組件,如上述被 @Component 裝飾的 struct Hello。 -
UI 描述
聲明式的方式來描述 UI 的結(jié)構(gòu),如上述 build() 方法內(nèi)部的代碼塊。 -
內(nèi)置組件
框架中默認(rèn)內(nèi)置的基礎(chǔ)和布局組件,可直接被開發(fā)者調(diào)用,比如示例中的 Column、Text、Divider、Button。 -
事件方法
用于添加組件對事件的響應(yīng)邏輯,統(tǒng)一通過事件方法進(jìn)行設(shè)置,如跟隨在Button后面的onClick()。 -
屬性方法
用于組件屬性的配置,統(tǒng)一通過屬性方法進(jìn)行設(shè)置,如fontSize()、width()、height()、color() 等,可通過鏈?zhǔn)秸{(diào)用的方式設(shè)置多項屬性。
從UI框架的需求角度,ArkTS在TS的類型系統(tǒng)的基礎(chǔ)上,做了進(jìn)一步的擴(kuò)展:定義了各種裝飾器、自定義組件和UI描述機(jī)制,再配合UI開發(fā)框架中的UI內(nèi)置組件、事件方法、屬性方法等共同構(gòu)成了應(yīng)用開發(fā)的主體。
在應(yīng)用開發(fā)中,除了UI的結(jié)構(gòu)化描述之外,還有一個重要的方面:狀態(tài)管理。如上述示例中,用 @State 裝飾過的變量 myText ,包含了一個基礎(chǔ)的狀態(tài)管理機(jī)制,即 myText 的值的變化會自動觸發(fā)相應(yīng)的 UI 變更 (Text組件)。ArkUI 中進(jìn)一步提供了多維度的狀態(tài)管理機(jī)制。和 UI 相關(guān)聯(lián)的數(shù)據(jù),不僅可以在組件內(nèi)使用,還可以在不同組件層級間傳遞,比如父子組件之間,爺孫組件之間,也可以是全局范圍內(nèi)的傳遞,還可以是跨設(shè)備傳遞。另外,從數(shù)據(jù)的傳遞形式來看,可分為只讀的單向傳遞和可變更的雙向傳遞。開發(fā)者可以靈活的利用這些能力來實現(xiàn)數(shù)據(jù)和 UI 的聯(lián)動。
總體而言,ArkUI開發(fā)框架通過擴(kuò)展成熟語言、結(jié)合語法糖或者語言原生的元編程能力、以及UI組件、狀態(tài)管理等方面設(shè)計了統(tǒng)一的UI開發(fā)范式,結(jié)合原生語言能力共同完成應(yīng)用開發(fā)。這些構(gòu)成了當(dāng)前ArkTS基于TS的主要擴(kuò)展。
渲染控制
- 條件渲染:使用if/else進(jìn)行條件渲染。
- 循環(huán)渲染:開發(fā)框架提供循環(huán)渲染(ForEach組件)來迭代數(shù)組,并為每個數(shù)組項創(chuàng)建相應(yīng)的組件。
狀態(tài)管理
組件狀態(tài)管理裝飾器用來管理組件中的狀態(tài),它們分別是:@State、@Prop、@Link。
- @State裝飾的變量是組件內(nèi)部的狀態(tài)數(shù)據(jù),當(dāng)這些狀態(tài)數(shù)據(jù)被修改時,將會調(diào)用所在組件的build方法進(jìn)行UI刷新。
- @Prop與@State有相同的語義,但初始化方式不同。@Prop裝飾的變量必須使用其父組件提供的@State變量進(jìn)行初始化,允許組件內(nèi)部修改@Prop變量,但更改不會通知給父組件,即@Prop屬于單向數(shù)據(jù)綁定。
- @Link裝飾的變量可以和父組件的@State變量建立雙向數(shù)據(jù)綁定,需要注意的是:@Link變量不能在組件內(nèi)部進(jìn)行初始化。
- @Builder裝飾的方法用于定義組件的聲明式UI描述,在一個自定義組件內(nèi)快速生成多個布局內(nèi)容。
@State、@Prop、@Link三者關(guān)系如圖所示:
組件生命周期函數(shù):
自定義組件的生命周期函數(shù)用于通知用戶該自定義組件的生命周期,這些回調(diào)函數(shù)是私有的,在運行時由開發(fā)框架在特定的時間進(jìn)行調(diào)用,不能從應(yīng)用程序中手動調(diào)用這些回調(diào)函數(shù)。
自定義組件生命周期的簡化圖示:
五、ArkTS實踐
1. 聲明式UI基本概念
應(yīng)用界面是由一個個頁面組成,ArkTS是由ArkUI框架提供,用于以聲明式開發(fā)范式開發(fā)界面的語言。
聲明式UI構(gòu)建頁面的過程,其實是組合組件的過程,聲明式UI的思想,主要體現(xiàn)在兩個方面:
- 聲明式描述:描述UI的呈現(xiàn)結(jié)果,而不關(guān)心過程
- 狀態(tài)驅(qū)動視圖更新
類似蘋果的SwiftUI中通過組合視圖View,安卓Jetpack Compose中通過組合@Composable函數(shù),ArkUI作為HarmonyOS應(yīng)用開發(fā)的UI開發(fā)框架,其使用ArkTS語言構(gòu)建自定義組件,通過組合自定義組件完成頁面的構(gòu)建。
2. 自定義組件的組成
ArkTS通過struct聲明組件名,并通過@Component和@Entry裝飾器,來構(gòu)成一個自定義組件。
使用@Entry和@Component裝飾的自定義組件作為頁面的入口,會在頁面加載時首先進(jìn)行渲染。
@Entry
@Component
struct ToDoList {...}
使用@Component裝飾的自定義組件,如ToDoItem這個自定義組件則對應(yīng)如下內(nèi)容,作為頁面的組成部分。
@Component
struct ToDoItem {...}
在自定義組件內(nèi)需要使用build方法來進(jìn)行UI描述。
@Entry
@Component
struct ToDoList
...
build() {
...
}
}
build方法內(nèi)可以容納內(nèi)置組件和其他自定義組件,如Column和Text都是內(nèi)置組件,由ArkUI框架提供,ToDoItem為自定義組件,需要開發(fā)者使用ArkTS自行聲明。
@Entry
@Component
struct ToDoList {
...
build() {
Column(...) {
Text(...)
...
ForEach(...{
TodoItem(...)
},...)
}
...
}
}
3. 配置屬性與布局
自定義組件的組成使用基礎(chǔ)組件和容器組件等內(nèi)置組件進(jìn)行組合。但有時內(nèi)置組件的樣式并不能滿足我們的需求,ArkTS提供了屬性方法用于描述界面的樣式。
- 常量傳遞
例如使用fontSize(50)來配置字體大小。
Text('Hello World').fontSize(50)
- 變量傳遞
在組件內(nèi)定義了相應(yīng)的變量后,例如組件內(nèi)部成員變量size,就可以使用this.size方式使用該變量。
Text('Hello World').fontSize(this.size)
- 鏈?zhǔn)秸{(diào)用
在配置多個屬性時,ArkTS提供了鏈?zhǔn)秸{(diào)用的方式,通過’.'方式連續(xù)配置。
Text('Hello World')
.fontSize(this.size)
.width(100)
.height(100)
- 表達(dá)式傳遞
屬性中還可以傳入普通表達(dá)式以及三目運算表達(dá)式。
Text('Hello World')
.fontSize(this.size)
.width(this.count + 100)
.height(this.count % 2 === 0 ? 100 : 200)
- 內(nèi)置枚舉類型
除此之外,ArkTS中還提供了內(nèi)置枚舉類型,如Color,F(xiàn)ontWeight等,例如設(shè)置fontColor改變字體顏色為紅色,并私有fontWeight為加粗。
Text('Hello World')
.fontSize(this.size)
.width(this.count + 100)
.height(this.count % 2 === 0 ? 100 : 200)
.fontColor(Color.Red)
.fontWeight(FontWeight.Bold)
對于有多種組件需要進(jìn)行組合時,容器組件則是描述了這些組件應(yīng)該如何排列的結(jié)果。
ArkUI中的布局容器有很多種,在不同的適用場合選擇不同的布局容器實現(xiàn),ArkTS使用容器組件采用花括號語法,內(nèi)部放置UI描述。
這里介紹最基礎(chǔ)的兩個布局——列布局和行布局。
對于如下每一項的布局,兩個元素為橫向排列,選擇Row布局
Row布局
Row() {
Image($r('app.media.ic_default'))
...
Text(this.content)
...
}
...
類似下圖所示的布局,整體都是從上往下縱向排列,適用的布局方式是Column列布局。
Column布局
Column() {
Text($r('app.string.page_title'))
...
ForEach(this.totalTasks,(item) =]]> {
TodoItem({content:item})
},...)
}
4. 改變組件狀態(tài)
實際開發(fā)中由于交互,頁面的內(nèi)容可能需要產(chǎn)生變化,以每一個ToDoItem為例,其在完成時的狀態(tài)與未完成時的展示效果是不一樣的。
不同狀態(tài)的視圖
聲明式UI的特點就是UI是隨數(shù)據(jù)更改而自動刷新的,我們這里定義了一個類型為boolean的變量isComplete,其被@State裝飾后,框架內(nèi)建立了數(shù)據(jù)和視圖之間的綁定,其值的改變影響UI的顯示。
@State isComplete : boolean = false;
@State裝飾器的作用
用圓圈和對勾這樣兩個圖片,分別來表示該項是否完成,這部分涉及到內(nèi)容的切換,需要使用條件渲染if / else語法來進(jìn)行組件的顯示與消失,當(dāng)判斷條件為真時,組件為已完成的狀態(tài),反之則為未完成。
if (this.isComplete) {
Image($r('app.media.ic_ok'))
.objectFit(ImageFit.Contain)
.width($r('app.float.checkbox_width'))
.height($r('app.float.checkbox_width'))
.margin($r('app.float.checkbox_margin'))
} else {
Image($r('app.media.ic_default'))
.objectFit(ImageFit.Contain)
.width($r('app.float.checkbox_width'))
.height($r('app.float.checkbox_width'))
.margin($r('app.float.checkbox_margin'))
}
由于兩個Image的實現(xiàn)具有大量重復(fù)代碼,ArkTS提供了@Builder裝飾器,來修飾一個函數(shù),快速生成布局內(nèi)容,從而可以避免重復(fù)的UI描述內(nèi)容。這里使用@Bulider聲明了一個labelIcon的函數(shù),參數(shù)為url,對應(yīng)要傳給Image的圖片路徑。
@Builder labelIcon(url) {
Image(url)
.objectFit(ImageFit.Contain)
.width($r('app.float.checkbox_width'))
.height($r('app.float.checkbox_width'))
.margin($r('app.float.checkbox_margin'))
}
使用時只需要使用this關(guān)鍵字訪問@Builder裝飾的函數(shù)名,即可快速創(chuàng)建布局。
if (this.isComplete) {
this.labelIcon($r('app.media.ic_ok'))
} else {
this.labelIcon($r('app.media.ic_default'))
}
為了讓待辦項帶給用戶的體驗更符合已完成的效果,給內(nèi)容的字體也增加了相應(yīng)的樣式變化,這里使用了三目運算符來根據(jù)狀態(tài)變化修改其透明度和文字樣式,如opacity是控制透明度,decoration是文字是否有劃線。通過isComplete的值來控制其變化。
Text(this.content)
...
.opacity(this.isComplete ? CommonConstants.OPACITY_COMPLETED : CommonConstants.OPACITY_DEFAULT)
.decoration({ type: this.isComplete
? TextDecorationType.LineThrough
: TextDecorationType.None })
最后,為了實現(xiàn)與用戶交互的效果,在組件上添加了onClick點擊事件,當(dāng)用戶點擊該待辦項時,數(shù)據(jù)isComplete的更改就能夠觸發(fā)UI的更新。
@Componentstruct
ToDoItem {
@State isComplete : boolean = false;
@Builder labelIcon(icon) {...}
...
build() {
Row() {
if (this.isComplete) {
this.labelIcon($r('app.media.ic_ok'))
} else {
this.labelIcon($r('app.media.ic_default'))
}
...
}
...
.onClick(() => {
this.isComplete= !this.isComplete;
})
}
}
5. 循環(huán)渲染列表數(shù)據(jù)
剛剛只是完成了一個ToDoItem組件的開發(fā),當(dāng)我們有多條待辦數(shù)據(jù)需要顯示在頁面時,就需要使用到ForEach循環(huán)渲染語法。
例如這里我們有五條待辦數(shù)據(jù)需要展示在頁面上。
total_Tasks: Array<string]]> = ['早起晨練','準(zhǔn)備早餐','閱讀名著','學(xué)習(xí)ArkTS','看劇放松']
ForEach基本使用中,只需要了解要渲染的數(shù)據(jù)以及要生成的UI內(nèi)容兩個部分,例如這里要渲染的數(shù)組為以上的五條待辦事項,要渲染的內(nèi)容是ToDoItem這個自定義組件,也可以是其他內(nèi)置組件。
ForEach基本使用
ToDoItem這個自定義組件中,每一個ToDoItem要顯示的文本參數(shù)content需要外部傳入,參數(shù)傳遞使用花括號的形式,用content接受數(shù)組內(nèi)的內(nèi)容項item。
最終完成的代碼及其效果如下。文章來源:http://www.zghlxwxcb.cn/news/detail-721772.html
@Entry
@Componentstruct
ToDoList {
...
build() {
Row() {
Column() {
Text(...)
...
ForEach(this.totalTasks,(item) => {
TodoItem({content:item})
},...)
}
.width('100%')
}
.height('100%')
}
}
ToDoList頁面文章來源地址http://www.zghlxwxcb.cn/news/detail-721772.html
到了這里,關(guān)于HarmonyOS學(xué)習(xí) -- ArkTS開發(fā)語言入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!