# \@Link装饰器:父ååŒå‘åŒæ¥ å组件ä¸è¢«\@Link装饰的å˜é‡ä¸Žå…¶çˆ¶ç»„ä»¶ä¸å¯¹åº”çš„æ•°æ®æºå»ºç«‹åŒå‘æ•°æ®ç»‘定。 在阅读\@Link文档å‰ï¼Œå»ºè®®å¼€å‘者首先了解[\@State](./arkts-state.md)的基本用法。 > **说明:** > > 从API version 9开始,该装饰器支æŒåœ¨ArkTSå¡ç‰‡ä¸ä½¿ç”¨ã€‚ > > 从API version 11开始,该装饰器支æŒåœ¨åŽŸå化æœåŠ¡ä¸ä½¿ç”¨ã€‚ ## 概述 \@Link装饰的å˜é‡ä¸Žå…¶çˆ¶ç»„ä»¶ä¸çš„æ•°æ®æºå…±äº«ç›¸åŒçš„值。 ## 装饰器使用规则说明 | \@Linkå˜é‡è£…饰器 | 说明 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | è£…é¥°å™¨å‚æ•° | æ— | | åŒæ¥ç±»åž‹ | åŒå‘åŒæ¥ã€‚<br/>父组件ä¸çš„状æ€å˜é‡å¯ä»¥ä¸Žå组件\@Link建立åŒå‘åŒæ¥ï¼Œå½“å…¶ä¸ä¸€æ–¹æ”¹å˜æ—¶ï¼Œå¦å¤–一方能够感知到å˜åŒ–。 | | å…许装饰的å˜é‡ç±»åž‹ | Objectã€classã€stringã€numberã€booleanã€enum类型,以åŠè¿™äº›ç±»åž‹çš„æ•°ç»„。<br/>支æŒDate类型。<br/>API11åŠä»¥ä¸Šæ”¯æŒMapã€Set类型。<br/>支æŒArkUI框架定义的è”åˆç±»åž‹Lengthã€ResourceStrã€ResourceColor类型。<br/>类型必须被指定,且和åŒå‘绑定状æ€å˜é‡çš„类型相åŒã€‚<br/>支æŒç±»åž‹çš„场景请å‚考[观察å˜åŒ–](#观察å˜åŒ–)。<br/>䏿”¯æŒany。<br/>API11åŠä»¥ä¸Šæ”¯æŒä¸Šè¿°æ”¯æŒç±»åž‹çš„è”åˆç±»åž‹ï¼Œæ¯”如string \| number, string \| undefined 或者 ClassA \| null,示例è§[Link支æŒè”åˆç±»åž‹å®žä¾‹](#link支æŒè”åˆç±»åž‹å®žä¾‹)。 <br/>**注æ„**<br/>当使用undefinedå’Œnullçš„æ—¶å€™ï¼Œå»ºè®®æ˜¾å¼æŒ‡å®šç±»åž‹ï¼Œéµå¾ªTypeScriptç±»åž‹æ ¡éªŒï¼Œæ¯”å¦‚ï¼š`@Link a : string \| undefined`。 | | 被装饰å˜é‡çš„åˆå§‹å€¼ | æ— ï¼Œç¦æ¢æœ¬åœ°åˆå§‹åŒ–。 | ## å˜é‡çš„ä¼ é€’/访问规则说明 | ä¼ é€’/访问 | 说明 | | ---------- | ---------------------------------------- | | 从父组件åˆå§‹åŒ–和更新 | 必选。与父组件\@State, \@StorageLinkå’Œ\@Link 建立åŒå‘绑定。å…许父组件ä¸[\@State](./arkts-state.md)ã€\@Linkã€[\@Prop](./arkts-prop.md)ã€[\@Provide](./arkts-provide-and-consume.md)ã€[\@Consume](./arkts-provide-and-consume.md)ã€[\@ObjectLink](./arkts-observed-and-objectlink.md)ã€[\@StorageLink](./arkts-appstorage.md#storagelink)ã€[\@StorageProp](./arkts-appstorage.md#storageprop)ã€[\@LocalStorageLink](./arkts-localstorage.md#localstoragelink)å’Œ[\@LocalStorageProp](./arkts-localstorage.md#localstorageprop)装饰å˜é‡åˆå§‹åŒ–å组件\@Link。<br/>从API version 9开始,\@Linkå组件从父组件åˆå§‹åŒ–\@Stateçš„è¯æ³•为Comp({ aLink: this.aState })ã€‚åŒæ ·Comp({aLink: $aState})也支æŒã€‚ | | 用于åˆå§‹åŒ–å组件 | å…许,å¯ç”¨äºŽåˆå§‹åŒ–常规å˜é‡ã€\@Stateã€\@Linkã€\@Propã€\@Provide。 | | æ˜¯å¦æ”¯æŒç»„件外访问 | ç§æœ‰ï¼Œåªèƒ½åœ¨æ‰€å±žç»„件内访问。 | **图1** åˆå§‹åŒ–规则图示   ## 观察å˜åŒ–和行为表现 ### 观察å˜åŒ– - 当装饰的数æ®ç±»åž‹ä¸ºbooleanã€stringã€number类型时,å¯ä»¥åŒæ¥è§‚察到数值的å˜åŒ–,示例请å‚考[简å•类型和类对象类型的@Link](#简å•类型和类对象类型的link)。 - 当装饰的数æ®ç±»åž‹ä¸ºclass或者Object时,å¯ä»¥è§‚察到赋值和属性赋值的å˜åŒ–,å³Object.keys(observedObject)返回的所有属性,示例请å‚考[简å•类型和类对象类型的@Link](#简å•类型和类对象类型的link)。 - 当装饰的对象是array时,å¯ä»¥è§‚å¯Ÿåˆ°æ•°ç»„æ·»åŠ ã€åˆ é™¤ã€æ›´æ–°æ•°ç»„å•元的å˜åŒ–,示例请å‚考[数组类型的@Link](#数组类型的link)。 - 当装饰的对象是Date时,å¯ä»¥è§‚察到Dateæ•´ä½“çš„èµ‹å€¼ï¼ŒåŒæ—¶å¯é€šè¿‡è°ƒç”¨Date的接å£`setFullYear`, `setMonth`, `setDate`, `setHours`, `setMinutes`, `setSeconds`, `setMilliseconds`, `setTime`, `setUTCFullYear`, `setUTCMonth`, `setUTCDate`, `setUTCHours`, `setUTCMinutes`, `setUTCSeconds`, `setUTCMilliseconds` æ›´æ–°Date的属性。 ```ts @Component struct DateComponent { @Link selectedDate: Date; build() { Column() { Button(`child increase the year by 1`).onClick(() => { this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1) }) Button('child update the new date') .margin(10) .onClick(() => { this.selectedDate = new Date('2023-09-09') }) DatePicker({ start: new Date('1970-1-1'), end: new Date('2100-1-1'), selected: this.selectedDate }) } } } @Entry @Component struct ParentComponent { @State parentSelectedDate: Date = new Date('2021-08-08'); build() { Column() { Button('parent increase the month by 1') .margin(10) .onClick(() => { this.parentSelectedDate.setMonth(this.parentSelectedDate.getMonth() + 1) }) Button('parent update the new date') .margin(10) .onClick(() => { this.parentSelectedDate = new Date('2023-07-07') }) DatePicker({ start: new Date('1970-1-1'), end: new Date('2100-1-1'), selected: this.parentSelectedDate }) DateComponent({ selectedDate:this.parentSelectedDate }) } } } ``` - 当装饰的å˜é‡æ˜¯Map时,å¯ä»¥è§‚察到Mapæ•´ä½“çš„èµ‹å€¼ï¼ŒåŒæ—¶å¯é€šè¿‡è°ƒç”¨Map的接å£`set`, `clear`, `delete` æ›´æ–°Map的值。详è§[装饰Map类型å˜é‡](#装饰map类型å˜é‡)。 - 当装饰的å˜é‡æ˜¯Set时,å¯ä»¥è§‚察到Setæ•´ä½“çš„èµ‹å€¼ï¼ŒåŒæ—¶å¯é€šè¿‡è°ƒç”¨Set的接å£`add`, `clear`, `delete` æ›´æ–°Set的值。详è§[装饰Set类型å˜é‡](#装饰set类型å˜é‡)。 ### 框架行为 \@Link装饰的å˜é‡å’Œå…¶æ‰€å±žçš„自定义组件共享生命周期。 为了了解\@Linkå˜é‡åˆå§‹åŒ–和更新机制,有必è¦å…ˆäº†è§£çˆ¶ç»„件和拥有\@Linkå˜é‡çš„å组件的关系,åˆå§‹æ¸²æŸ“å’ŒåŒå‘æ›´æ–°çš„æµç¨‹ï¼ˆä»¥çˆ¶ç»„件为\@State为例)。 1. åˆå§‹æ¸²æŸ“:执行父组件的build()函数åŽå°†åˆ›å»ºå组件的新实例。åˆå§‹åŒ–过程如下: 1. 必须指定父组件ä¸çš„\@Stateå˜é‡ï¼Œç”¨äºŽåˆå§‹åŒ–å组件的\@Linkå˜é‡ã€‚å组件的\@Linkå˜é‡å€¼ä¸Žå…¶çˆ¶ç»„ä»¶çš„æ•°æ®æºå˜é‡ä¿æŒåŒæ¥ï¼ˆåŒå‘æ•°æ®åŒæ¥ï¼‰ã€‚ 2. 父组件的\@State状æ€å˜é‡åŒ…è£…ç±»é€šè¿‡æž„é€ å‡½æ•°ä¼ ç»™å组件,å组件的\@Link包装类拿到父组件的\@State的状æ€å˜é‡åŽï¼Œå°†å½“å‰\@Link包装类this指针注册给父组件的\@Stateå˜é‡ã€‚ 2. \@Linkçš„æ•°æ®æºçš„æ›´æ–°ï¼šå³çˆ¶ç»„ä»¶ä¸çжæ€å˜é‡æ›´æ–°ï¼Œå¼•起相关å组件的\@Linkçš„æ›´æ–°ã€‚å¤„ç†æ¥éª¤ï¼š 1. 通过åˆå§‹æ¸²æŸ“çš„æ¥éª¤å¯çŸ¥ï¼Œå组件\@Link包装类把当å‰this指针注册给父组件。父组件\@Stateå˜é‡å˜æ›´åŽï¼Œä¼šé历更新所有ä¾èµ–它的系统组件(elementid)和状æ€å˜é‡ï¼ˆæ¯”如\@Link包装类)。 2. 通知\@Link包装类更新åŽï¼Œåç»„ä»¶ä¸æ‰€æœ‰ä¾èµ–\@Link状æ€å˜é‡çš„系统组件(elementId)都会被通知更新。以æ¤å®žçŽ°çˆ¶ç»„ä»¶å¯¹åç»„ä»¶çš„çŠ¶æ€æ•°æ®åŒæ¥ã€‚ 3. \@Link的更新:当å组件ä¸\@Linkæ›´æ–°åŽï¼Œå¤„ç†æ¥éª¤å¦‚下(以父组件为\@State为例): 1. \@Linkæ›´æ–°åŽï¼Œè°ƒç”¨çˆ¶ç»„ä»¶çš„\@State包装类的set方法,将更新åŽçš„æ•°å€¼åŒæ¥å›žçˆ¶ç»„件。 2. å组件\@Link和父组件\@State分别é历ä¾èµ–的系统组件,进行对应的UI的更新。以æ¤å®žçްå组件\@LinkåŒæ¥å›žçˆ¶ç»„ä»¶\@State。 ## é™åˆ¶æ¡ä»¶ 1. \@Link装饰器ä¸èƒ½åœ¨[\@Entry](./arkts-create-custom-components.md#自定义组件的基本结构)装饰的自定义组件ä¸ä½¿ç”¨ã€‚ 2. \@Link装饰的å˜é‡ç¦æ¢æœ¬åœ°åˆå§‹åŒ–,å¦åˆ™ç¼–译期会报错。 ```ts // 错误写法,编译报错 @Link count: number = 10; // æ£ç¡®å†™æ³• @Link count: number; ``` 3. \@Link装饰的å˜é‡çš„类型è¦å’Œæ•°æ®æºç±»åž‹ä¿æŒä¸€è‡´ï¼Œå¦åˆ™æ¡†æž¶ä¼šæŠ›å‡ºè¿è¡Œæ—¶é”™è¯¯ã€‚ ã€å例】 ```ts class Info { info: string = 'Hello'; } class Cousin { name: string = 'Hello'; } @Component struct Child { // 错误写法,@Link与@Stateæ•°æ®æºç±»åž‹ä¸ä¸€è‡´ @Link test: Cousin; build() { Text(this.test.name) } } @Entry @Component struct LinkExample { @State info: Info = new Info(); build() { Column() { // 错误写法,@Link与@Stateæ•°æ®æºç±»åž‹ä¸ä¸€è‡´ Child({test: new Cousin()}) } } } ``` ã€æ£ä¾‹ã€‘ ```ts class Info { info: string = 'Hello'; } @Component struct Child { // æ£ç¡®å†™æ³• @Link test: Info; build() { Text(this.test.info) } } @Entry @Component struct LinkExample { @State info: Info = new Info(); build() { Column() { // æ£ç¡®å†™æ³• Child({test: this.info}) } } } ``` 4. \@Link装饰的å˜é‡ä»…能被状æ€å˜é‡åˆå§‹åŒ–,ä¸èƒ½ç”¨å¸¸é‡åˆå§‹åŒ–,编译期会有warn告è¦ï¼Œè¿è¡Œæ—¶ä¼šæŠ›å‡ºis not callableè¿è¡Œæ—¶é”™è¯¯ã€‚ ã€å例】 ```ts class Info { info: string = 'Hello'; } @Component struct Child { @Link msg: string; @Link info: string; build() { Text(this.msg + this.info) } } @Entry @Component struct LinkExample { @State message: string = 'Hello'; @State info: Info = new Info(); build() { Column() { // 错误写法,常规å˜é‡ä¸èƒ½åˆå§‹åŒ–@Link Child({msg: 'World', info: this.info.info}) } } } ``` ã€æ£ä¾‹ã€‘ ```ts class Info { info: string = 'Hello'; } @Component struct Child { @Link msg: string; @Link info: Info; build() { Text(this.msg + this.info.info) } } @Entry @Component struct LinkExample { @State message: string = 'Hello'; @State info: Info = new Info(); build() { Column() { // æ£ç¡®å†™æ³• Child({msg: this.message, info: this.info}) } } } ``` 5. \@Link䏿”¯æŒè£…饰Function类型的å˜é‡ï¼Œæ¡†æž¶ä¼šæŠ›å‡ºè¿è¡Œæ—¶é”™è¯¯ã€‚ ## 使用场景 ### 简å•类型和类对象类型的\@Link 以下示例ä¸ï¼Œç‚¹å‡»çˆ¶ç»„ä»¶ShufflingContainerä¸çš„“Parent View: Set yellowButtonâ€å’Œâ€œParent View: Set GreenButtonâ€ï¼Œå¯ä»¥ä»Žçˆ¶ç»„ä»¶å°†å˜åŒ–åŒæ¥ç»™å组件。 1.点击å组件GreenButtonå’ŒYellowButtonä¸çš„Button,å组件会å‘生相应å˜åŒ–,将å˜åŒ–åŒæ¥ç»™çˆ¶ç»„ä»¶ã€‚å› ä¸º@Link是åŒå‘åŒæ¥ï¼Œä¼šå°†å˜åŒ–åŒæ¥ç»™@State。 2.当点击父组件ShufflingContainerä¸çš„Button时,@Stateå˜åŒ–ï¼Œä¹Ÿä¼šåŒæ¥ç»™@Link,å组件也会å‘生对应的刷新。 ```ts class GreenButtonState { width: number = 0; constructor(width: number) { this.width = width; } } @Component struct GreenButton { @Link greenButtonState: GreenButtonState; build() { Button('Green Button') .width(this.greenButtonState.width) .height(40) .backgroundColor('#64bb5c') .fontColor('#FFFFFF,90%') .onClick(() => { if (this.greenButtonState.width < 700) { // æ›´æ–°class的属性,å˜åŒ–å¯ä»¥è¢«è§‚å¯Ÿåˆ°åŒæ¥å›žçˆ¶ç»„ä»¶ this.greenButtonState.width += 60; } else { // æ›´æ–°class,å˜åŒ–å¯ä»¥è¢«è§‚å¯Ÿåˆ°åŒæ¥å›žçˆ¶ç»„ä»¶ this.greenButtonState = new GreenButtonState(180); } }) } } @Component struct YellowButton { @Link yellowButtonState: number; build() { Button('Yellow Button') .width(this.yellowButtonState) .height(40) .backgroundColor('#f7ce00') .fontColor('#FFFFFF,90%') .onClick(() => { // å组件的简å•类型å¯ä»¥åŒæ¥å›žçˆ¶ç»„ä»¶ this.yellowButtonState += 40.0; }) } } @Entry @Component struct ShufflingContainer { @State greenButtonState: GreenButtonState = new GreenButtonState(180); @State yellowButtonProp: number = 180; build() { Column() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { // 简å•类型从父组件@Stateå‘å组件@Linkæ•°æ®åŒæ¥ Button('Parent View: Set yellowButton') .width(312) .height(40) .margin(12) .fontColor('#FFFFFF,90%') .onClick(() => { this.yellowButtonProp = (this.yellowButtonProp < 700) ? this.yellowButtonProp + 40 : 100; }) // class类型从父组件@Stateå‘å组件@Linkæ•°æ®åŒæ¥ Button('Parent View: Set GreenButton') .width(312) .height(40) .margin(12) .fontColor('#FFFFFF,90%') .onClick(() => { this.greenButtonState.width = (this.greenButtonState.width < 700) ? this.greenButtonState.width + 100 : 100; }) // class类型åˆå§‹åŒ–@Link GreenButton({ greenButtonState: $greenButtonState }).margin(12) // 简å•类型åˆå§‹åŒ–@Link YellowButton({ yellowButtonState: $yellowButtonProp }).margin(12) } } } } ```  ### 数组类型的\@Link ```ts @Component struct Child { @Link items: number[]; build() { Column() { Button(`Button1: push`) .margin(12) .width(312) .height(40) .fontColor('#FFFFFF,90%') .onClick(() => { this.items.push(this.items.length + 1); }) Button(`Button2: replace whole item`) .margin(12) .width(312) .height(40) .fontColor('#FFFFFF,90%') .onClick(() => { this.items = [100, 200, 300]; }) } } } @Entry @Component struct Parent { @State arr: number[] = [1, 2, 3]; build() { Column() { Child({ items: $arr }) .margin(12) ForEach(this.arr, (item: number) => { Button(`${item}`) .margin(12) .width(312) .height(40) .backgroundColor('#11a2a2a2') .fontColor('#e6000000') }, (item: ForEachInterface) => item.toString() ) } } } ```  上文所述,ArkUI框架å¯ä»¥è§‚å¯Ÿåˆ°æ•°ç»„å…ƒç´ çš„æ·»åŠ ï¼Œåˆ é™¤å’Œæ›¿æ¢ã€‚在该示例ä¸\@Stateå’Œ\@Link的类型是相åŒçš„number[],ä¸å…许将\@Link定义æˆnumber类型(\@Link item : number),并在父组件ä¸ç”¨\@Stateæ•°ç»„ä¸æ¯ä¸ªæ•°æ®é¡¹åˆ›å»ºå组件。如果è¦ä½¿ç”¨è¿™ä¸ªåœºæ™¯ï¼Œå¯ä»¥å‚考[\@Prop](arkts-prop.md)å’Œ[\@Observed](./arkts-observed-and-objectlink.md)。 ### 装饰Map类型å˜é‡ > **说明:** > > 从API version 11开始,\@Link支æŒMap类型。 在下é¢çš„示例ä¸ï¼Œvalue类型为Map\<number, string\>,点击Button改å˜message的值,视图会éšä¹‹åˆ·æ–°ã€‚ ```ts @Component struct Child { @Link value: Map<number, string> build() { Column() { ForEach(Array.from(this.value.entries()), (item: [number, string]) => { Text(`${item[0]}`).fontSize(30) Text(`${item[1]}`).fontSize(30) Divider() }) Button('child init map').onClick(() => { this.value = new Map([[0, "a"], [1, "b"], [3, "c"]]) }) Button('child set new one').onClick(() => { this.value.set(4, "d") }) Button('child clear').onClick(() => { this.value.clear() }) Button('child replace the first one').onClick(() => { this.value.set(0, "aa") }) Button('child delete the first one').onClick(() => { this.value.delete(0) }) } } } @Entry @Component struct MapSample { @State message: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]) build() { Row() { Column() { Child({ value: this.message }) } .width('100%') } .height('100%') } } ``` ### 装饰Set类型å˜é‡ > **说明:** > > 从API version 11开始,\@Link支æŒSet类型。 在下é¢çš„示例ä¸ï¼Œmessage类型为Set\<number\>,点击Button改å˜message的值,视图会éšä¹‹åˆ·æ–°ã€‚ ```ts @Component struct Child { @Link message: Set<number> build() { Column() { ForEach(Array.from(this.message.entries()), (item: [number, string]) => { Text(`${item[0]}`).fontSize(30) Divider() }) Button('init set').onClick(() => { this.message = new Set([0, 1, 2, 3, 4]) }) Button('set new one').onClick(() => { this.message.add(5) }) Button('clear').onClick(() => { this.message.clear() }) Button('delete the first one').onClick(() => { this.message.delete(0) }) } .width('100%') } } @Entry @Component struct SetSample { @State message: Set<number> = new Set([0, 1, 2, 3, 4]) build() { Row() { Column() { Child({ message: this.message }) } .width('100%') } .height('100%') } } ``` ### 使用åŒå‘åŒæ¥æœºåˆ¶æ›´æ”¹æœ¬åœ°å…¶ä»–å˜é‡ 使用[\@Watch](./arkts-watch.md)å¯ä»¥åœ¨åŒå‘åŒæ¥æ—¶ï¼Œæ›´æ”¹æœ¬åœ°å˜é‡ã€‚ 下é¢çš„示例ä¸ï¼Œåœ¨\@Linkçš„\@Watch里é¢ä¿®æ”¹äº†ä¸€ä¸ª\@State装饰的å˜é‡sourceNumber,实现了父å组件间的å˜é‡åŒæ¥ã€‚但是\@State装饰的å˜é‡memberMessage在本地修改åˆä¸ä¼šå½±å“到父组件ä¸çš„å˜é‡æ”¹å˜ã€‚ ```ts @Entry @Component struct Parent { @State sourceNumber: number = 0; build() { Column() { Text(`父组件的sourceNumber:` + this.sourceNumber) Child({ sourceNumber: this.sourceNumber }) Button('父组件更改sourceNumber') .onClick(() => { this.sourceNumber++; }) } .width('100%') .height('100%') } } @Component struct Child { @State memberMessage: string = 'Hello World'; @Link @Watch('onSourceChange') sourceNumber: number; onSourceChange() { this.memberMessage = this.sourceNumber.toString(); } build() { Column() { Text(this.memberMessage) Text(`å组件的sourceNumber:` + this.sourceNumber.toString()) Button('å组件更改memberMessage') .onClick(() => { this.memberMessage = 'Hello memberMessage'; }) } } } ``` ## Link支æŒè”åˆç±»åž‹å®žä¾‹ @Link支æŒè”åˆç±»åž‹å’Œundefinedå’Œnull,在下é¢çš„示例ä¸ï¼Œname类型为string | undefined,点击父组件Indexä¸çš„Button改å˜name的属性或者类型,Childä¸ä¹Ÿä¼šå¯¹åº”刷新。 ```ts @Component struct Child { @Link name: string | undefined build() { Column() { Button('Child change name to Bob') .onClick(() => { this.name = "Bob" }) Button('Child change name to undefined') .onClick(() => { this.name = undefined }) }.width('100%') } } @Entry @Component struct Index { @State name: string | undefined = "mary" build() { Column() { Text(`The name is ${this.name}`).fontSize(30) Child({ name: this.name }) Button('Parents change name to Peter') .onClick(() => { this.name = "Peter" }) Button('Parents change name to undefined') .onClick(() => { this.name = undefined }) } } } ``` ## 常è§é—®é¢˜ ### \@Link装饰状æ€å˜é‡ç±»åž‹é”™è¯¯ 在å组件ä¸ä½¿ç”¨\@Link装饰状æ€å˜é‡éœ€è¦ä¿è¯è¯¥å˜é‡ä¸Žæ•°æ®æºç±»åž‹å®Œå…¨ç›¸åŒï¼Œä¸”è¯¥æ•°æ®æºéœ€ä¸ºè¢«è¯¸å¦‚\@Stateç‰è£…饰器装饰的状æ€å˜é‡ã€‚ ã€å例】 ```ts @Observed class Info { public age: number = 0; constructor(age: number) { this.age = age; } } @Component struct LinkChild { @Link testNum: number; build() { Text(`LinkChild testNum ${this.testNum}`) } } @Entry @Component struct Parent { @State info: Info = new Info(1); build() { Column() { Text(`Parent testNum ${this.info.age}`) .onClick(() => { this.info.age += 1; }) // @Link装饰的å˜é‡éœ€è¦å’Œæ•°æ®æº@State类型一致 LinkChild({ testNum: this.info.age }) } } } ``` \@Link testNum: number从父组件的LinkChild({testNum:this.info.age})åˆå§‹åŒ–。\@Linkçš„æ•°æ®æºå¿…须是装饰器装饰的状æ€å˜é‡ï¼Œç®€è€Œè¨€ä¹‹ï¼Œ\@Link装饰的数æ®å¿…é¡»å’Œæ•°æ®æºç±»åž‹ç›¸åŒï¼Œæ¯”如\@Link: Tå’Œ\@State : T。所以,这里应该改为\@Link testNum: Info,从父组件åˆå§‹åŒ–的方å¼ä¸ºLinkChild({testNum: this.info}) ã€æ£ä¾‹ã€‘ ```ts @Observed class Info { public age: number = 0; constructor(age: number) { this.age = age; } } @Component struct LinkChild { @Link testNum: Info; build() { Text(`LinkChild testNum ${this.testNum?.age}`) .onClick(() => { this.testNum.age += 1; }) } } @Entry @Component struct Parent { @State info: Info = new Info(1); build() { Column() { Text(`Parent testNum ${this.info.age}`) .onClick(() => { this.info.age += 1; }) // @Link装饰的å˜é‡éœ€è¦å’Œæ•°æ®æº@State类型一致 LinkChild({ testNum: this.info }) } } } ``` ### 使用a.b(this.object)å½¢å¼è°ƒç”¨ï¼Œä¸ä¼šè§¦å‘UI刷新 在build方法内,当@Link装饰的å˜é‡æ˜¯Object类型ã€ä¸”通过a.b(this.object)å½¢å¼è°ƒç”¨æ—¶ï¼Œbæ–¹æ³•å†…ä¼ å…¥çš„æ˜¯this.objectçš„åŽŸç”Ÿå¯¹è±¡ï¼Œä¿®æ”¹å…¶å±žæ€§ï¼Œæ— æ³•è§¦å‘UI刷新。如下例ä¸ï¼Œé€šè¿‡é™æ€æ–¹æ³•Score.changeScore1或者this.changeScore2修改Child组件ä¸çš„this.score.value时,UIä¸ä¼šåˆ·æ–°ã€‚ ã€å例】 ```ts class Score { value: number; constructor(value: number) { this.value = value; } static changeScore1(score:Score) { score.value += 1; } } @Entry @Component struct Parent { @State score: Score = new Score(1); build() { Column({space:8}) { Text(`The value in Parent is ${this.score.value}.`) .fontSize(30) .fontColor(Color.Red) Child({ score: this.score }) } .width('100%') .height('100%') } } @Component struct Child { @Link score: Score; changeScore2(score:Score) { score.value += 2; } build() { Column({space:8}) { Text(`The value in Child is ${this.score.value}.`) .fontSize(30) Button(`changeScore1`) .onClick(()=>{ // é€šè¿‡é™æ€æ–¹æ³•è°ƒç”¨ï¼Œæ— æ³•è§¦å‘UI刷新 Score.changeScore1(this.score); }) Button(`changeScore2`) .onClick(()=>{ // 使用thisé€šè¿‡è‡ªå®šä¹‰ç»„ä»¶å†…éƒ¨æ–¹æ³•è°ƒç”¨ï¼Œæ— æ³•è§¦å‘UI刷新 this.changeScore2(this.score); }) } } } ``` å¯ä»¥é€šè¿‡å¦‚下先赋值ã€å†è°ƒç”¨æ–°èµ‹å€¼çš„å˜é‡çš„æ–¹å¼ä¸ºthis.scoreåŠ ä¸ŠProxy代ç†ï¼Œå®žçްUI刷新。 ã€æ£ä¾‹ã€‘ ```ts class Score { value: number; constructor(value: number) { this.value = value; } static changeScore1(score:Score) { score.value += 1; } } @Entry @Component struct Parent { @State score: Score = new Score(1); build() { Column({space:8}) { Text(`The value in Parent is ${this.score.value}.`) .fontSize(30) .fontColor(Color.Red) Child({ score: this.score }) } .width('100%') .height('100%') } } @Component struct Child { @Link score: Score; changeScore2(score:Score) { score.value += 2; } build() { Column({space:8}) { Text(`The value in Child is ${this.score.value}.`) .fontSize(30) Button(`changeScore1`) .onClick(()=>{ // é€šè¿‡èµ‹å€¼æ·»åŠ Proxy ä»£ç† let score1 = this.score; Score.changeScore1(score1); }) Button(`changeScore2`) .onClick(()=>{ // é€šè¿‡èµ‹å€¼æ·»åŠ Proxy ä»£ç† let score2 = this.score; this.changeScore2(score2); }) } } } ``` <!--no_check-->