HarmonyOS Next V2 @Local 和@Param
@Local 背景
@Local 是harmony應(yīng)用開發(fā)中的 v2 版本中 對(duì)標(biāo)**@State**的狀態(tài)管理修飾器,它解決了 @State 對(duì)狀態(tài)變量更改的檢測(cè)混亂的問題:
- @State 修飾的狀態(tài)變量 可以是組件內(nèi)部自己定義的
- @State 修飾的狀態(tài) 也可以由外部父組件傳遞
這樣就導(dǎo)致了狀態(tài)數(shù)據(jù)來(lái)源不唯一,在大型項(xiàng)目中會(huì)引發(fā)難易檢測(cè)和維護(hù)狀態(tài)的問題。如以下代碼:
@Entry
@Component
struct Index {
@State num: number = 100
build() {
Column() {
Text("父組件的數(shù)據(jù) " + this.num)
Son({ num: this.num })
Son()
}
.height('100%')
.width('100%')
}
}
@Component
struct Son {
@State num: number = 0
build() {
Column() {
Button(`子組件 ${this.num}`)
.onClick(() = > {
this.num++
})
}
}
}
@Local 基本使用
@Local的出現(xiàn)就是為了解決這一類問題
- @Local 只能用在 @Componentv2 修飾的組件上
- 被**@Local**裝飾的變量無(wú)法從外部初始化(無(wú)法由父組件傳遞進(jìn)來(lái)),因此必須在組件內(nèi)部進(jìn)行初始化
我們對(duì)上面代碼稍作修改
@Entry
@Component
struct Index {
@State num: number = 100
build() {
Column() {
Text("父組件的數(shù)據(jù) " + this.num)
Son({ num: this.num }) // 這里就報(bào)錯(cuò)啦
Son()
}
.height('100%')
.width('100%')
}
}
@ComponentV2 // 此處調(diào)整為 @ComponentV2
struct Son {
// 此處調(diào)整為 @Local
@Local num: number = 0
build() {
Column() {
Button(`子組件 ${this.num}`)
.onClick(() = > {
this.num++
})
}
}
}
@Local 與@State 對(duì)比
@State | @Local | |
---|---|---|
參數(shù) | 無(wú)。 | 無(wú)。 |
從父組件初始化 | 可選。 | 不允許外部初始化。 |
觀察能力 | 能觀測(cè)變量本身以及一層的成員屬性,無(wú)法深度觀測(cè)。 | 能觀測(cè)變量本身,深度觀測(cè)依賴@Trace 裝飾器。 |
數(shù)據(jù)傳遞 | 可以作為數(shù)據(jù)源和子組件中狀態(tài)變量同步。 | 可以作為數(shù)據(jù)源和子組件中狀態(tài)變量同步。 |
@Local 特別注意
- @Local 支持觀測(cè) number、boolean、string、Object、class 等基本類型以及 Array、Set、Map、Date 等內(nèi)嵌類型。
- @Local 的觀測(cè)能力僅限于被裝飾的 變量本身 。當(dāng)裝飾簡(jiǎn)單類型時(shí),能夠觀測(cè)到對(duì)變量的賦值;當(dāng)裝飾對(duì)象類型時(shí),僅能觀測(cè)到對(duì)對(duì)象整體的賦值;當(dāng)裝飾數(shù)組類型時(shí),能觀測(cè)到數(shù)組整體以及數(shù)組元素項(xiàng)的變化;當(dāng)裝飾 Array、Set、Map、Date 等內(nèi)嵌類型時(shí),可以觀測(cè)到通過 API 調(diào)用帶來(lái)的變化。
@Params
@Params主要表示 子組件 接收父組件傳遞的數(shù)據(jù)。可以和 @Local 搭配一起使用
@Params 背景
在 V1 版本的狀態(tài)管理修飾符中,可以用來(lái)處理 父子傳參的技術(shù)有:
- 普通屬性,不需要特別的修飾符 , 不具備單向同步
- @Prop 單向同步,不能監(jiān)聽深層次屬性的改變,也不能做到雙向同步
- @Link 可以做到雙向同步,但是不能監(jiān)聽深層次屬性的改變,而且不能直接用在 列表渲染技術(shù) - ForEach 中
- @ObjectLink 可以做到雙向同步,但是必須和 @Observed 搭配使用 ,而且只能用在自定義組件上
1. 普通屬性
普通屬性,不需要特別的修飾符 , 不具備單向同步
@Entry
@Component
struct Index {
@State num: number = 100
build() {
Column() {
// 父組件傳遞過去的數(shù)據(jù)
Son({ num: this.num })
.onClick(() = > {
this.num++
console.log("", this.num)
})
}
.height('100%')
.width('100%')
}
}
@Component
struct Son {
num: number = 0
build() {
Column() {
Button(`子組件 ${this.num}`)
}
}
}
2. @Prop 單向同步
@Prop 單向同步
- 不能監(jiān)聽深層次屬性的改變
- 也不能做到雙向同步
在上面代碼基礎(chǔ)上 加入**@Prop**,可以檢測(cè)到基本類型數(shù)據(jù)的更新
@Component
struct Son {
@Prop num: number = 0
但是無(wú)法檢測(cè)深層次屬性的改變,如
class Animal {
dog: Dog = {
age: 100
}
}
class Dog {
age: number = 100
}
@Entry
@Component
struct Index {
@State
animal: Animal = new Animal()
build() {
Column() {
// 父組件傳遞過去的數(shù)據(jù)
Son({ dog: this.animal.dog })
.onClick(() = > {
this.animal.dog.age++
console.log("", this.animal.dog.age)
})
}
.height('100%')
.width('100%')
}
}
@Component
struct Son {
@Prop dog: Dog
build() {
Column() {
Button(`子組件 ${this.dog.age}`)
}
}
}
3. @Link 雙向同步
@Link 用法和@Prop 基本一致
可以做到雙向同步,但是
不能監(jiān)聽深層次屬性的改變
而且不能直接用在 列表渲染技術(shù) - ForEach 中 以下代碼演示這個(gè)效果
class Dog { age: number = 100 } @Entry @Component struct Index { @State dogList: Dog [] = [new Dog(), new Dog(), new Dog(), new Dog()] build() { Column() { ForEach(this.dogList, (item: Dog) = > { // 此處會(huì)報(bào)錯(cuò) Assigning the attribute 'item' to the '@Link' decorated attribute 'dog' is not allowed. < ArkTSCheck > Son({ dog: item }) .onClick(() = > { item.age++ console.log("", item.age) }) }) } .height('100%') .width('100%') } } @Component struct Son { @Link dog: Dog build() { Column() { Button(`子組件 ${this.dog.age}`) } } }
4. @ObjectLink
@ObjectLink 可以做到雙向同步,但是必須和 @Observed 搭配使用 ,而且只能用在自定義組件上
小結(jié)
可以看到,如果都是使用 v1 版本的這一套 父子傳參的技術(shù),是十分復(fù)雜難易直接上手使用的。
@Params 介紹
Param 表示組件從外部傳入的狀態(tài),使得父子組件之間的數(shù)據(jù)能夠進(jìn)行同步:
- @Param 裝飾的變量支持本地初始化,但是不允許在組件內(nèi)部直接修改變量本身。
- 如果不本地初始化,那么必須加入 @Require
- @Param 可以做到單向同步
- @Param 可以檢測(cè)深層次屬性的修改,但是該修改在數(shù)據(jù)源上必須是整體對(duì)象的更新
- @Params 如果也想要深度監(jiān)聽單個(gè)屬性的修改,那么需要使用 @ObservedV2 和 @Trace
以下代碼主要演示:@Param 可以檢測(cè)深層次屬性的修改,但是該修改在數(shù)據(jù)源上必須是整體對(duì)象的更新
class Person {
age: number = 100
}
@Entry
@ComponentV2
struct Index {
@Local
person: Person = new Person()
build() {
Column() {
Son({ age: this.person.age })
.onClick(() = > {
this.person.age++
console.log("", this.person.age)
if (this.person.age === 105) {
const p = new Person()
p.age = 200
// 整體更新,子組件可以感知到
this.person = p
}
})
}
.height('100%')
.width('100%')
}
}
@ComponentV2
struct Son {
// 要么設(shè)置 @Require 表示父組件必須傳遞數(shù)據(jù)
// 要么設(shè)置 默認(rèn)值
@Require @Param age: number
build() {
Column() {
Button(`子組件 ${this.age}`)
}
}
}
總結(jié)
- @Local 可以看成是 @State 的替代 ,單獨(dú)表示組件內(nèi)部的狀態(tài)
- @Params 可以看成 @Prop @Link @ObjectLink 的替代,更加嚴(yán)謹(jǐn)
- @Local 和 @Params 搭配一起使用,都只能用在 @Componentv2 修飾的自定義組件上
審核編輯 黃宇
-
HarmonyOS
+關(guān)注
關(guān)注
79文章
2052瀏覽量
32109
發(fā)布評(píng)論請(qǐng)先 登錄
脫離安卓,完全自研,純血鴻蒙HarmonyOS NEXT開始打造自主生態(tài)圈

第三屆大會(huì)回顧第2期 | HarmonyOS NEXT內(nèi)核驅(qū)動(dòng)生態(tài)兼容與競(jìng)爭(zhēng)力思考

HarmonyOS Next V2 @Monitor 和@Computed
HarmonyOS Next V2 @Event
微軟OmniParser V2:大模型轉(zhuǎn)化為計(jì)算機(jī)智能體
SAM IoT Wx v2硬件用戶指南

名單公布!【書籍評(píng)測(cè)活動(dòng)NO.56】極速探索HarmonyOS NEXT:純血鴻蒙應(yīng)用開發(fā)實(shí)踐
HarmonyOS NEXT 應(yīng)用開發(fā)練習(xí):智能視頻推薦
華為大氣啊!HarmonyOS NEXT公測(cè)發(fā)福利~這個(gè)可以有

華為HarmonyOS NEXT 10月8日開啟公測(cè)

華為“純血”鴻蒙系統(tǒng) HarmonyOS NEXT 將于9月底推出正式版
華為HarmonyOS NEXT鴻蒙星河版正式開啟Beta計(jì)劃
HarmonyOS NEXT Developer Beta1中的Kit
HDC 2024上,HarmonyOS NEXT有哪些精彩亮點(diǎn)值得期待?

評(píng)論