# @Link
**@Link**装饰的变量可以和父组件的**@State**变量建立双向数据绑定:
- **支持多种类型:@Link**变量的值与**@State**变量的类型相同,即class、number、string、boolean或这些类型的数组;
- **私有:**仅在组件内访问;
- **单个数据源:**初始化**@Link**变量的父组件的变量必须是**@State**变量;
- **双向通信:**子组件对**@Link**变量的更改将同步修改父组件的**@State**变量;
- **创建自定义组件时需要将变量的引用传递给@Link变量:**在创建组件的新实例时,必须使用命名参数初始化所有**@Link**变量。**@Link**变量可以使用**@State**变量或**@Link**变量的引用进行初始化。**@State**变量可以通过'**$**'操作符创建引用。
> **说明:**
>**@Link**变量不能在组件内部进行初始化。
## 简单类型示例
```
@Entry
@Component
struct Player {
@State isPlaying: boolean = false
build() {
Column() {
PlayButton({buttonPlaying: $isPlaying})
Text(`Player is ${this.isPlaying? '':'not'} playing`)
}
}
}
@Component
struct PlayButton {
@Link buttonPlaying: boolean
build() {
Column() {
Button() {
Image(this.buttonPlaying? 'play.png' : 'pause.png')
}.onClick(() => {
this.buttonPlaying = !this.buttonPlaying
})
}
}
}
```
**@Link**语义是从'**$**'操作符引出,即**$isPlaying**是**this.isPlaying**内部状态的双向数据绑定。当您单击**PlayButton**时,PlayButton 的**Image**组件和**Text**组件将同时进行刷新。
## 复杂类型示例
```
@Entry
@Component
struct Parent {
@State arr: number[] = [1, 2, 3]
build() {
Column() {
Child({items: $arr})
ForEach(this.arr,
item => Text(`${item}`),
item => item.toString())
}
}
}
@Component
struct Child {
@Link items: number[]
build() {
Column() {
Button() {
Text('Button1: push')
}.onClick(() => {
this.items.push(100)
})
Button() {
Text('Button2: replace whole item')
}.onClick(() => {
this.items = [100, 200, 300]
})
}
}
}
```
在上面的示例中,点击**Button1**和**Button2**以更改父组件中显示的文本项目列表。
## @Link和@State、@Prop结合使用示例
```
@Entry
@Component
struct ParentView {
@State counter: number = 0
build() {
Column() {
ChildA({counterVal: this.counter}) // pass by value
ChildB({counterRef: $counter}) // $ creates a Reference that can be bound to counterRef
}
}
}
@Component
struct ChildA {
@Prop counterVal: number
build() {
Button() {
Text(`ChildA: (${this.counterVal}) + 1`)
}.onClick(() => {this.counterVal+= 1})
}
}
@Component
struct ChildB {
@Link counterRef: number
build() {
Button() {
Text(`ChildB: (${this.counterRef}) + 1`)
}.onClick(() => {this.counterRef+= 1})
}
}
```
上述示例中,ParentView包含ChildA和ChildB两个子组件,ParentView的状态变量**counter**分别初始化ChildA和ChildB:
- ChildB使用**@Link**建立双向状态绑定。当**ChildB**修改**counterRef**状态变量值时,该更改将同步到**ParentView**和**ChildA**共享;
- ChildA使用**@Prop**建立从**ParentView**到自身的单向状态绑定。当**ChildA**修改状态时,**ChildA**将重新渲染,但该更改不会传达给**ParentView**和**ChildB。**