概述:
在華為開發(fā)者大會(huì)2023年8月4日(HDC.Together)大會(huì)上,HarmonyOS?4正式發(fā)布,其實(shí)在2021年那會(huì)學(xué)習(xí)了一點(diǎn)鴻蒙的開發(fā):
不過因?yàn)楝F(xiàn)在的鴻蒙手機(jī)完全兼容Android應(yīng)用,所以學(xué)習(xí)動(dòng)力也不是很足,一直就擱置了,直到今年華為官方出了這么一則消息才讓我對(duì)于學(xué)習(xí)它有一種緊迫感了,如下:
所以。。這次必須得把它給攻克,不然未來自己的飯碗可能都不保。。
IDE升級(jí)配置:
在正式學(xué)習(xí)之前,先來將IDE進(jìn)行一個(gè)升級(jí),目前我本機(jī)的IDE是定格在這個(gè)版本:
而當(dāng)時(shí)在學(xué)習(xí)時(shí)我們采用的開發(fā)語言選擇的是Java,因?yàn)楫?dāng)時(shí)這個(gè)版本在創(chuàng)建項(xiàng)目時(shí)可以進(jìn)行語言的選擇:
但是?。?!在網(wǎng)上又搜到這么一個(gè)“令人痛心”的消息:“HarmonyOS 從API8開始不再支持java作為開發(fā)語言”
這對(duì)我的打擊還是蠻大的,畢竟Android我開發(fā)它主要還是使用Java語言,那為了確認(rèn)這個(gè)事實(shí),先來將IDE先升級(jí)試一下:
下載安裝之后,打開會(huì)發(fā)現(xiàn)有個(gè)設(shè)置向?qū)Ы缑妫?/p>
接下來則需要進(jìn)行IDE的配置了,這里需要先配置Node.js和Ohpm:
點(diǎn)擊下一步則進(jìn)行HarmonyOS SDK的下載:
其中標(biāo)紅處有一個(gè)警告,意思是說我本機(jī)的sdk的管理模式已經(jīng)發(fā)生改變了,畢竟當(dāng)年學(xué)習(xí)鴻蒙開發(fā)是在2前年,所以我們點(diǎn)擊一下“Fix”對(duì)其進(jìn)行一個(gè)修復(fù):
點(diǎn)擊Ok則進(jìn)入到下載頁(yè)面:
然后點(diǎn)擊“Finish”,修復(fù)成功之后則就可以點(diǎn)擊“Next”了:
其中在下載的過程中發(fā)現(xiàn)個(gè)這個(gè)提示:
“ArkTS”,這是個(gè)什么東東?在官方這個(gè)文檔中心文檔中有介紹:
哦,原來是跟TypeScript有關(guān),那很明顯它是跟Java木有關(guān)系的,然后真的新建項(xiàng)目時(shí)語言就選擇不了Java了么?那下完之后我們新建試一下:
對(duì)于一個(gè)從Android轉(zhuǎn)過來學(xué)鴻蒙的來說,簡(jiǎn)直晴天霹靂呀,其學(xué)習(xí)優(yōu)勢(shì)瞬間降為0了。。本來我還在猶豫再重新學(xué)它,到底是用Java還是JS,這下好了直接強(qiáng)制學(xué)習(xí)新語言,如果不學(xué),直接不會(huì)。。
官方教程了解:
要學(xué)習(xí),當(dāng)?shù)靡医坛汤玻热蝗A為是國(guó)內(nèi)自己搞的,直接上官方學(xué)應(yīng)該妥妥的,是的,這里推薦一個(gè)從0開始的官方教程集:HarmonyOS第一課|應(yīng)用開發(fā)視頻教程學(xué)習(xí)|HarmonyOS應(yīng)用開發(fā)官網(wǎng),?先學(xué)基礎(chǔ)知識(shí):
其中官方既有視頻教學(xué),也有文檔記錄:
對(duì)于自己記筆記也非常方便。等學(xué)完了之后,還有一個(gè)綜合的案例來鞏固,代碼都是開源的:
嗯,完美,接下來則按著官方的教程一步步來掌控它,下面的大綱則完全按照官方的這個(gè)教程集進(jìn)行。
運(yùn)行Hello World:
修改IDE的主題顏色:
由于我平常Android Studio使用的是白色風(fēng)格,而默認(rèn)DevEco-Studio是黑色系,不太習(xí)慣,改一下:
就回到了舒服的亮色系了:
創(chuàng)建項(xiàng)目:
接下來則來創(chuàng)建一個(gè)Hello World工程:
都保持默認(rèn),其中DeviceType有一個(gè)Tablet是個(gè)啥設(shè)備呢? 度娘:
哦,懂了,平板。接下來下一步就創(chuàng)建成功了,可以可以看到正在同步一些東東,其中:
前端的東東,本身ArkTS就是基于JS來擴(kuò)展的,所以,貌似前端的小伙伴學(xué)習(xí)鴻蒙的優(yōu)勢(shì)巨大呀。?
運(yùn)行Hello World:
待同步完成之后,就可以來運(yùn)行看一下效果了,目前還沒有創(chuàng)建模擬器,所以先創(chuàng)建:
其中可以看到可以有本地模擬器、遠(yuǎn)程模擬器、遠(yuǎn)程真機(jī),這里學(xué)習(xí)我們默認(rèn)用本地模擬器既可,目前沒有可用的模擬器需要先安裝,點(diǎn)擊“Install”:
下載完成之后,就可以看到這個(gè)界面進(jìn)行模擬器的添加了,整個(gè)添加的過程跟Android Studio模擬器的創(chuàng)建很類似:
選擇手機(jī)模擬器,此時(shí)回到這個(gè)界面,需要下載系統(tǒng)鏡像:
有將近2個(gè)G,比較大,需要耐心等待一下,等下完了之后, 點(diǎn)擊"next"新建一個(gè)模擬器:
最后完成,則整個(gè)模擬器創(chuàng)建成功:
此時(shí)就可以運(yùn)行程序到該模擬器上了,如下:
此時(shí)運(yùn)行工程到手機(jī)上看一下效果:
此時(shí)我們可以簡(jiǎn)單修改一下內(nèi)容:
其中它有一個(gè)模擬器的預(yù)覽界面:
再運(yùn)行一下:
了解基本工程目錄:
關(guān)于工程目錄這塊其實(shí)官方的文檔也說明得非常詳細(xì)了,這里將自己覺得值得一提的過一下。
1、Project&Ohos視圖:
如Android工程一樣,通常在開發(fā)中會(huì)在Project和Android視圖進(jìn)行切換:
而在DevEco中也有兩個(gè)視圖:
其中Project視圖就不用過多解釋了,IDEA都有的,而Ohos就是對(duì)工程代碼進(jìn)行了一個(gè)分類了,查看起來比較清晰:
- AppScope中存放應(yīng)用全局所需要的資源文件。
- entry是應(yīng)用的主模塊,存放HarmonyOS應(yīng)用的代碼、資源等。
- configuration存放的是工程應(yīng)用級(jí)的配置文件。
工程級(jí)目錄:
其實(shí)就是整個(gè)工程的目錄結(jié)構(gòu)。
模塊級(jí)目錄:
關(guān)于這塊的具體細(xì)節(jié),可以參考官方的文檔說明:
ArkTS開發(fā)語言介紹:
在嘗試了第一個(gè)HelloWorld的鴻蒙應(yīng)用運(yùn)行效果之后,接下來則需要打基礎(chǔ)了,先最基本的開發(fā)語言開始熟悉--ArkTS。?
編程語言介紹:
ArkTs它是一個(gè)前端的語言,還有另外兩個(gè)前端的語言想必大家都知道:JavaScript和TypeScript,那這三者是啥關(guān)系呢?這里直接貼一下官方的說明:
所以要想學(xué)好ArkTs,前提是要學(xué)好JavaScript和TypeScript,而通常對(duì)于JavaScript或多或少都接觸過,官方其實(shí)直接跳過它的基礎(chǔ)學(xué)習(xí)了【并非它不重要喲,而是把時(shí)間花在刀刃上】,直接了解TypeScript的基礎(chǔ)語法,所以下面咱們根據(jù)官方的教程將這TypeScript的在實(shí)際開發(fā)中會(huì)用得到的語法給學(xué)一學(xué)。
TypeScript快速入門:
這里的內(nèi)容都可以在官方找到,我這邊是cv大法,目的是自己跟著過一遍。
基礎(chǔ)類型:
TypeScript支持一些基礎(chǔ)的數(shù)據(jù)類型,如布爾型、數(shù)組、字符串等,下文舉例幾個(gè)較為常用的數(shù)據(jù)類型,我們來了解下他們的基本使用。
1、布爾值:
TypeScript中可以使用boolean來表示這個(gè)變量是布爾值,可以賦值為true或者false。
let isDone: boolean = false;
2、數(shù)字:
TypeScript里的所有數(shù)字都是浮點(diǎn)數(shù),這些浮點(diǎn)數(shù)的類型是 number。除了支持十進(jìn)制,還支持二進(jìn)制、八進(jìn)制、十六進(jìn)制。比如定義下面這些數(shù)字變量:
let decLiteral: number = 2023;
let binaryLiteral: number = 0b11111100111;
let octalLiteral: number = 0o3747;
let hexLiteral: number = 0x7e7;
運(yùn)行的話最終都會(huì)轉(zhuǎn)換成十進(jìn)程:
3、字符串:
TypeScript里使用 string表示文本數(shù)據(jù)類型, 可以使用雙引號(hào)( ")或單引號(hào)(')表示字符串。
let name: string = "Jacky";
name = "Tom";
name = 'Mick';
4、數(shù)組:
TypeScrip有兩種方式可以定義數(shù)組。
第一種,可以在元素類型后面接上 [],表示由此類型元素組成的一個(gè)數(shù)組。
let list: number[] = [1, 2, 3];
第二種方式是使用數(shù)組泛型,Array<元素類型>。
let list: Array<number> = [1, 2, 3];
5、元組:
元組類型允許表示一個(gè)已知元素?cái)?shù)量和類型的數(shù)組,各元素的類型不必相同。 比如,你可以定義一對(duì)值分別為 string和number類型的元組。
let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
6、枚舉:
enum類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充,使用枚舉類型可以為一組數(shù)值賦予友好的名字。
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
7、Unknown:
有時(shí)候,我們會(huì)想要為那些在編程階段還不清楚類型的變量指定一個(gè)類型。這種情況下,我們不希望類型檢查器對(duì)這些值進(jìn)行檢查而是直接讓它們通過編譯階段的檢查。那么我們可以使用unknown類型來標(biāo)記這些變量。
let notSure: unknown = 4;
notSure = 'maybe a string instead';
notSure = false;
可以看到,對(duì)于unkown類型的變量,之后可以賦值其它任何類型。
8、Void:
當(dāng)一個(gè)函數(shù)沒有返回值時(shí),你通常會(huì)見到其返回值類型是 void。
function test(): void {
console.log('This is function is void');
}
9、Null 和 Undefined:
TypeScript里,undefined和null兩者各自有自己的類型分別叫做undefined和null。
let u: undefined = undefined;
let n: null = null;
10、聯(lián)合類型【實(shí)際用得比較多】:
聯(lián)合類型(Union Types)表示取值可以為多種類型中的一種。
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
條件語句:
TypeScript 條件語句是通過一條或多條語句的執(zhí)行結(jié)果(True 或 False)來決定執(zhí)行的代碼塊,這塊其實(shí)跟Java沒啥區(qū)別,有不清楚的可以上官網(wǎng)看一下,就列一個(gè)swich..case這種條件語句:
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ù):
TypeScript可以創(chuàng)建有名字的函數(shù)和匿名函數(shù),其創(chuàng)建方法如下:
// 有名函數(shù)
function add(x, y) {
return x + y;
}
// 匿名函數(shù)
let myAdd = function (x, y) {
return x + y;
};
1、為函數(shù)定義類型:
為了確保輸入輸出的準(zhǔn)確性,我們可以為上面那個(gè)函數(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;
};
2、可選參數(shù):
在TypeScript里我們可以在參數(shù)名旁使用 ?實(shí)現(xiàn)可選參數(shù)的功能。 比如,我們想讓lastName是可選的:
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + ' ' + lastName;
else
return firstName;
}
let result1 = buildName('Bob');
let result2 = buildName('Bob', 'Adams');
3、剩余參數(shù):
剩余參數(shù)會(huì)被當(dāng)做個(gè)數(shù)不限的可選參數(shù)。 可以一個(gè)都沒有,同樣也可以有任意個(gè)。 可以使用省略號(hào)( ...)進(jìn)行定義:
function getEmployeeName(firstName: string, ...restOfName: string[]) {
return firstName + ' ' + restOfName.join(' ');
}
let employeeName = getEmployeeName('Joseph', 'Samuel', 'Lucas', 'MacKinzie');
4、箭頭函數(shù)【重要】:
ES6版本的TypeScript提供了一個(gè)箭頭函數(shù),它是定義匿名函數(shù)的簡(jiǎn)寫語法,用于函數(shù)表達(dá)式,它省略了function關(guān)鍵字。箭頭函數(shù)的定義如下,其函數(shù)是一個(gè)語句塊:
( [param1, parma2,…param n] )=> {
// 代碼塊
}
其中,括號(hào)內(nèi)是函數(shù)的入?yún)?,可以?到多個(gè)參數(shù),箭頭后是函數(shù)的代碼塊。我們可以將這個(gè)箭頭函數(shù)賦值給一個(gè)變量,如下所示:
let arrowFun = ( [param1, parma2,…param n] )=> {
// 代碼塊
}
如何要主動(dòng)調(diào)用這個(gè)箭頭函數(shù),可以按如下方法去調(diào)用:
arrowFun(param1, parma2,…param n)
接下來我們看看如何將我們熟悉的函數(shù)定義方式轉(zhuǎn)換為箭頭函數(shù)。我們可以定義一個(gè)判斷正負(fù)數(shù)的函數(shù),如下:
function testNumber(num: number) {
if (num > 0) {
console.log(num + ' 是正數(shù)');
} else if (num < 0) {
console.log(num + ' 是負(fù)數(shù)');
} else {
console.log(num + ' 為0');
}
}
其調(diào)用方法如下:
testNumber(1) //輸出日志:1 是正數(shù)
如果將這個(gè)函數(shù)定義為箭頭函數(shù),定義如下所示:
let testArrowFun = (num: number) => {
if (num > 0) {
console.log(num + ' 是正數(shù)');
} else if (num < 0) {
console.log(num + ' 是負(fù)數(shù)');
} else {
console.log(num + ' 為0');
}
}
其調(diào)用方法如下:
testArrowFun(-1) //輸出日志:-1 是負(fù)數(shù)
后面,我們?cè)趯W(xué)習(xí)HarmonyOS應(yīng)用開發(fā)時(shí)會(huì)經(jīng)常用到箭頭函數(shù)。例如,給一個(gè)按鈕添加點(diǎn)擊事件,其中onClick事件中的函數(shù)就是箭頭函數(shù)。
Button("Click Now")
.onClick(() => {
console.info("Button is click")
})
類:
對(duì)于熟悉Java的童鞋來說是再熟悉不過了,這里來看一下使用TypeScript是如何定義一個(gè)類的,例如,我們可以聲明一個(gè)Person類,這個(gè)類有3個(gè)成員:一個(gè)是屬性(包含name和age),一個(gè)是構(gòu)造函數(shù),一個(gè)是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}`;
}
}
通過上面的Person類,我們可以定義一個(gè)人物Jacky并獲取他的基本信息,其定義如下:
let person1 = new Person('Jacky', 18);
person1.getPersonInfo();
繼承:
TypeScript中允許使用繼承來擴(kuò)展現(xiàn)有的類,對(duì)應(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}`;
}
}
通過上面的Employee類,我們可以定義一個(gè)人物Tom,這里可以獲取他的基本信息,也可以獲取他的雇主信息,其定義如下:
let person2 = new Employee('Tom', 28, 'HuaWei');
person2.getPersonInfo();
person2.getEmployeeInfo();
在TypeScript中,有public、private、protected修飾符,這個(gè)跟Java差不多。
模塊:【重要】
隨著應(yīng)用越來越大,通常要將代碼拆分成多個(gè)文件,即所謂的模塊(module)。模塊可以相互加載,并可以使用特殊的指令 export 和 import 來交換功能,從另一個(gè)模塊調(diào)用一個(gè)模塊的函數(shù)。
兩個(gè)模塊之間的關(guān)系是通過在文件級(jí)別上使用 import 和 export 建立的。模塊里面的變量、函數(shù)和類等在模塊外部是不可見的,除非明確地使用 export 導(dǎo)出它們。類似地,我們必須通過 import 導(dǎo)入其他模塊導(dǎo)出的變量、函數(shù)、類等。
導(dǎo)出:
任何聲明(比如變量,函數(shù),類,類型別名或接口)都能夠通過添加export關(guān)鍵字來導(dǎo)出,例如我們要把NewsData這個(gè)類導(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)入:
要想使用其它模塊的export出來的類,則需要通過如下進(jìn)行類的導(dǎo)入,模塊的導(dǎo)入操作與導(dǎo)出一樣簡(jiǎn)單。 可以使用以下 import形式之一來導(dǎo)入其它模塊中的導(dǎo)出內(nèi)容。
import { NewsData } from '../common/bean/NewsData';
這塊在學(xué)習(xí)Vue時(shí)經(jīng)常碰到:
迭代器:
當(dāng)一個(gè)對(duì)象實(shí)現(xiàn)了Symbol.iterator屬性時(shí),我們認(rèn)為它是可迭代的。一些內(nèi)置的類型如Array,Map,Set,String,Int32Array,Uint32Array等都具有可迭代性。
1、for..of 語句:
for..of會(huì)遍歷可迭代的對(duì)象,調(diào)用對(duì)象上的Symbol.iterator方法。 下面是在數(shù)組上使用for..of的簡(jiǎn)單例子:
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
2、for..of vs. for..in 語句:
for..of和for..in均可迭代一個(gè)列表,但是用于迭代的值卻不同:for..in迭代的是對(duì)象的鍵,而for..of則迭代的是對(duì)象的值。比如:
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ǔ)知識(shí):
有了TypeScript基礎(chǔ)語法的入門,接下來就可以進(jìn)入ArkTs的學(xué)習(xí)了。
ArkTs簡(jiǎn)介:
關(guān)于這塊,官網(wǎng)這塊已經(jīng)把它的生世今生說得非常詳細(xì)了:
用一張官方的介紹圖來了解下:
其中引言中有這么一句話:“Mozilla創(chuàng)造了JS,Microsoft創(chuàng)建了TS,Huawei進(jìn)一步推出了ArkTS。”,另外從兩個(gè)角度來闡述了當(dāng)時(shí)創(chuàng)造ArkTS的一些現(xiàn)狀分析:
等于設(shè)計(jì)的目的是讓開發(fā)者更加簡(jiǎn)單高效,然后又說到了Google的Dart和Jetpack Compose,這個(gè)對(duì)于搞Android來說的很親切:
ArkTS的開發(fā)框架圖如下【我沒看懂】:
而對(duì)于咱們開發(fā)來說,下圖更加有意義:
清晰地闡述聲明式開發(fā)規(guī)范的組成部分,這塊簡(jiǎn)單了解一下。
UI描述規(guī)范:
在視頻中,以這么一個(gè)案例代碼來闡述ArkTS代碼的一些規(guī)范,這樣理解起來就比較直觀,這個(gè)案例是這么一個(gè)列表:
當(dāng)點(diǎn)擊一行時(shí),則會(huì)變色:
其對(duì)應(yīng)的主要代碼是:
這寫法是不是跟Flutter很相似?如果說你不了解其代碼的規(guī)則,那么寫起來就會(huì)摸不著頭腦,所以接下來按照視頻所說來了解ArkTS聲明式UI描述的一些基本概念。
裝飾器:
定義:它是用來裝飾類、結(jié)構(gòu)、方法和變量,賦予其特殊的含義。?
代碼:
而這段代碼中的裝飾器有2個(gè):
1、@Component裝飾器:
ArkTS通過struct聲明組件名,并通過@Component裝飾器,來構(gòu)成一個(gè)自定義組件,用@Component裝飾的struct ListItemComponent代表一個(gè)自定義的結(jié)構(gòu)體,名字是ListItemComponent,它是可重用的UI單元,可以與其它組件組合。
2、@State裝飾器:
關(guān)于它可以參考官方這塊的說明,已經(jīng)非常詳情了:
也就是被它裝飾的變量isChange值發(fā)生改變時(shí),會(huì)觸發(fā)該變量所對(duì)應(yīng)的自定義組件ListItemComponent的UI界面進(jìn)行自動(dòng)刷新,
UI描述:
定義:聲明式的方式描述UI結(jié)構(gòu)
代碼:其實(shí)也就是這塊的代碼:
是以自定義的形式描述該自定義組件ListItemComponent的UI結(jié)構(gòu)。
內(nèi)置組件:
定義:系統(tǒng)提供的基礎(chǔ)組件和容器組件等,可以直接調(diào)用。
代碼:
Row是水平方向布局的容器組件,而Text是文本組件用來展示一段文字。
屬性方法:
定義:用來設(shè)置組件的屬性。
代碼:
事件方法:
定義:設(shè)置組件對(duì)事件的響應(yīng)邏輯。
代碼:
這篇主要是先來學(xué)習(xí)常用的兩個(gè)裝飾器@Component和@Entry,內(nèi)置組件、屬性方法、事件方法等都會(huì)在之后進(jìn)行詳細(xì)學(xué)習(xí)。
自定義組件:
再學(xué)習(xí)裝飾器之前,先來了解一下自定義組件的基本概念,其實(shí)這個(gè)應(yīng)該都或多或少都接觸過,比如Android開發(fā)就有自定義View,其實(shí)HarmonyOS為開發(fā)者定義了豐富的組件:
但是這些組件在實(shí)際開發(fā)中往往滿足不了,為了提升開發(fā)效率通常會(huì)將內(nèi)置組件進(jìn)行組合成一個(gè)自定義組件,以便于其它頁(yè)面可以靈活高效的使用,這種組件就叫自定義組件,比如咱們舉的這個(gè)水果排行版界面中,就會(huì)使用三個(gè)自定義組件來進(jìn)行UI的搭建:
這三個(gè)自定義組件是標(biāo)題欄、排行榜列表頭、排行榜列表項(xiàng),所以自定義組件在實(shí)際開發(fā)中是必須得要掌握的,下面則來具體看一下如何自定義一個(gè)組件。
常用裝飾器@Component與@Entry:
下面以自定義一個(gè)標(biāo)題欄組件為例進(jìn)行一下細(xì)節(jié)說明:
1、定義名為TitleComponent的自定義組件:
也就是它:
2、定義名為RankPage的自定義組件,在其中使用TitleComponent組件:
其中當(dāng)一個(gè)組件使用另一個(gè)組件的內(nèi)容時(shí),這個(gè)組件就被稱為父組件,也就是RankPage是父組件:
而被使用的組件則稱之為子組件:
那么系統(tǒng)是如何知道TitleComponet是自定義組件呢?其實(shí)是通過@Component裝飾器和struct關(guān)鍵字對(duì)TitleComponet進(jìn)行了修飾,struct是組件的數(shù)據(jù)結(jié)構(gòu),@Component是組件化的標(biāo)志:
使用@Entry裝飾的自定義組件作為頁(yè)面的入口,會(huì)在頁(yè)面加載時(shí)首先進(jìn)行渲染,
注意:一個(gè)頁(yè)面有且僅有一個(gè)@Entry,只有被@Entry修飾的組件或者子組件才會(huì)在頁(yè)面中進(jìn)行顯示。
3、導(dǎo)出自定義組件:
通常自定義組件的定義和使用它的父組件在不同的文件中,因此需要將自定義組件導(dǎo)出以供外部使用,而導(dǎo)出是使用export關(guān)鍵字:
然后使用時(shí)則需要使用import進(jìn)行導(dǎo)入:
4、自定義組件生命周期回調(diào)函數(shù):
自定義組件有如下兩個(gè)生命周期回調(diào)函數(shù):
aboutToAppear():在創(chuàng)建自定義組件的實(shí)例后,到執(zhí)行其build函數(shù)之前執(zhí)行,可以在此函數(shù)中對(duì)UI需要展示的數(shù)據(jù)進(jìn)行初始化,或者申請(qǐng)定時(shí)器資源等操作,這樣在后續(xù)build()函數(shù)中可以使用這些數(shù)據(jù)和資源來進(jìn)行UI展示,其類似于Android Activity中的onCreate()生命周期函數(shù)。比如在水果排行版實(shí)例中:
對(duì)水果相關(guān)的數(shù)據(jù)進(jìn)行初始化,用于后續(xù)排行版的數(shù)據(jù)展示。
aboutToDisappear():在自定義組件實(shí)例被銷毀時(shí)調(diào)用,通常做一些釋放的邏輯,其類似于Android Activity中的onDestroy()生命周期函數(shù):
注:這些回調(diào)函數(shù)是私有的,是由系統(tǒng)來調(diào)用的,無法手動(dòng)來調(diào)用。
5、@Entry修飾的頁(yè)面入口組件生命周期回調(diào)函數(shù):
前面也說過,對(duì)于由@Entry修飾的頁(yè)面它是一個(gè)入口組件,對(duì)于這種它還有如下三個(gè)生命周期:
onPageShow():當(dāng)打開應(yīng)用,處于前臺(tái)時(shí)頁(yè)面顯示,該函數(shù)會(huì)被觸發(fā),類似于Android中的onResume()函數(shù)。
onPageHide():當(dāng)應(yīng)用切到后臺(tái)時(shí),該函數(shù)會(huì)被觸發(fā),類似于Android中的onStop()函數(shù)。
onBackPress():當(dāng)返回時(shí)該函數(shù)會(huì)被觸發(fā),返回true表示頁(yè)面自己處理返回邏輯不進(jìn)行頁(yè)面返回,而如果返回false則交由系統(tǒng)處理返回邏輯,默認(rèn)返回false。
代碼如下:
關(guān)于生命周期相關(guān)的進(jìn)一步細(xì)節(jié)可以參考:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/arkts-custom-component-lifecycle-0000001482395076-V3,再貼一張官方的圖:
渲染控制:
通過渲染控制語法可以讓咱們更加自由的繪制UI界面。
條件渲染:使用if/else if/else進(jìn)行條件渲染
還是看水果排行版的這個(gè)實(shí)例,在UI上有這么一個(gè)效果:
前三名的樣式和后面的樣式是有區(qū)分的,咱們就可以使用這個(gè)條件渲染進(jìn)行條件判斷:
循環(huán)渲染:使用ForEach迭代數(shù)組,并為每個(gè)數(shù)組項(xiàng)創(chuàng)建相應(yīng)的組件
比如水果列表的顯示,就需要使用到它:
關(guān)于它的API說有可以參考:https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-rendering-control-foreach-0000001524537153-V3,關(guān)于這個(gè)地址是如何獲得的呢?其實(shí)它來自于https://developer.harmonyos.com/,跟android的類似,點(diǎn)指南就可以搜到內(nèi)容:
然后里面對(duì)于開發(fā)的知識(shí)描述得非常詳細(xì),它是需要傳三個(gè)參數(shù):
第一個(gè)參數(shù)則是循環(huán)渲染的數(shù)據(jù)源數(shù)組;
第二個(gè)參數(shù)生成子組件的lambda函數(shù),為數(shù)組中的每一個(gè)數(shù)據(jù)項(xiàng)創(chuàng)建一個(gè)或多個(gè)子組件,單個(gè)子組件或子組件列表必須包括在大括號(hào)“{...}”中。
第三個(gè)參數(shù)為匿名函數(shù),用于給數(shù)組中的每一個(gè)數(shù)據(jù)項(xiàng)生成唯一且固定的鍵值:
狀態(tài)管理:
現(xiàn)在創(chuàng)建和控制自定義組件已經(jīng)學(xué)會(huì)了,那如何讓組件動(dòng)起來并且能夠根據(jù)用戶的輸入或者數(shù)據(jù)的變化呈現(xiàn)不同的效果呢?水果排行應(yīng)用有兩個(gè)交互場(chǎng)景:點(diǎn)擊選中某一行水果和刷新排行版數(shù)據(jù),接下來就看一下如何通過管理組件的狀態(tài)來實(shí)現(xiàn)這么兩個(gè)功能。
關(guān)于狀態(tài)管理可以參考官方這塊的說明:
@State:
裝飾的變量是組件內(nèi)部的狀態(tài)數(shù)據(jù),當(dāng)這些狀態(tài)數(shù)據(jù)被修改時(shí),將會(huì)調(diào)用所在組件的build方法進(jìn)行UI刷新。
這里以點(diǎn)擊某一行水果排行榜其文字顏色會(huì)發(fā)生變化為例來看一下此狀態(tài)管理是如何弄的:
看一下代碼實(shí)現(xiàn):
定義了一個(gè)isChange變量用來判斷排行榜列表上的水果名稱和得票數(shù)的字體顏色是否改變,其中就用到了@State這個(gè)裝飾器對(duì)該變量進(jìn)行修飾,然后再Text組件中則根據(jù)這個(gè)變量進(jìn)行顏色的判斷:
然后在行點(diǎn)擊時(shí)對(duì)該狀態(tài)變量進(jìn)行一下值更改:
@Link:?
通過@State裝飾器我們可以實(shí)現(xiàn)一個(gè)組件內(nèi)部數(shù)據(jù)更新UI的場(chǎng)景,但是!?。?duì)于復(fù)雜的應(yīng)用會(huì)由多個(gè)自定義的組件組成,那不同組件之間數(shù)據(jù)變化如何進(jìn)行UI更新呢?比如這么一個(gè)場(chǎng)景:
則需要使用@Link和@State這兩個(gè)裝飾器配合使用來實(shí)現(xiàn)此功能了,所以先了解一下@Link:“裝飾的變量可以和父組件的@State變量建立雙向數(shù)據(jù)綁定,需要注意的是:@Link變量不能在組件內(nèi)部進(jìn)行初始化。”
下面來看一下此場(chǎng)景的功能實(shí)現(xiàn)代碼細(xì)節(jié):
1、TitleComponent:
先在頭部組件中使用@Link定義一個(gè)是否需要刷新的變量,并且它受點(diǎn)擊事件的影響:
由于裝飾的變量可以和父組件的@State變量建立雙向數(shù)據(jù)綁定【那雙向數(shù)據(jù)綁定的樣式是啥樣呢?在下面的代碼中會(huì)有體現(xiàn)的】,那么任何一方所做的修改都會(huì)反映給另一方,對(duì)isRefreshData的更改將同步修改父組件對(duì)應(yīng)的@State變量,從而自動(dòng)觸發(fā)父組件的UI刷新,
2、RankPage:
接下來就可以回到父組件定義三個(gè)@State變量:
其中在創(chuàng)建子組件時(shí),先對(duì)其成員變量進(jìn)行一個(gè)初始化:
由于isRefreshData是使用@Link在子組件中進(jìn)行修飾的,所以在父組件中必須使用引用來進(jìn)行初始化:
通過這種方式就創(chuàng)建了子組件和父組件之間的雙向數(shù)據(jù)綁定了,當(dāng)子組件的isRefreshData值變化時(shí),其父組件的isSwitchDataSource值也會(huì)跟著進(jìn)行變化,這樣在構(gòu)建列表時(shí)就可以根據(jù)這個(gè)isSwitchDataSource變量來切換不同的數(shù)據(jù)源了:
其中核心是要理解“數(shù)據(jù)的雙向綁定”。
總結(jié):
最后關(guān)于ArkTS基礎(chǔ)知識(shí)還有個(gè)練習(xí):
這塊下次繼續(xù),重學(xué)鴻蒙,感受最大的就是語言已經(jīng)徹底拋棄Java,讓你已經(jīng)找不到Android那個(gè)Activity的身影了,如果不提前學(xué)到時(shí)等明年鴻蒙5徹底不兼容APK時(shí),身為Android程序可能會(huì)比較被動(dòng),因?yàn)槟膫€(gè)公司都不會(huì)放棄華為這么大的一個(gè)用戶群體,那很顯然地都需要將公司的APP來適配鴻蒙,所以趁還有時(shí)間及早學(xué)習(xí)它是很有必要的。另外整個(gè)學(xué)習(xí)由于官方教程已經(jīng)弄得非常人性了,所以學(xué)習(xí)起來也比較流暢,當(dāng)然前提是一步步一個(gè)腳印的來進(jìn)行學(xué)習(xí),欲速則不達(dá)。
另外對(duì)于Android程序還有一個(gè)“好消息”:昨天雷布斯在微博上發(fā)了個(gè)這。。
“Xiaomi HyperOS”,擦,未來Android程序員真的酸爽,以后是不是還會(huì)有OPPO OS、魅族 OS... 怎么說呢,是挑戰(zhàn)也是機(jī)遇,市場(chǎng)有需求才有你立足的根本,擁抱變化~~
??關(guān)注個(gè)人公眾號(hào),獲得實(shí)時(shí)推送文章來源:http://www.zghlxwxcb.cn/news/detail-755084.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-755084.html
到了這里,關(guān)于零基礎(chǔ)快速上手HarmonyOS ArkTS開發(fā)1---運(yùn)行Hello World、ArkTS開發(fā)語言介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!