1# !!语法:双向绑定
2在状态管理V1中使用[$$](./arkts-two-way-sync.md)用于内置组件双向绑定。
3在状态管理V2中,提供了归一处理,提供`!!`语法糖作为统一处理双向绑定语法。
4
5
6>**说明:**
7>
8>`!!`语法从API version 12开始支持。
9>
10
11## 概述
12
13`!!`双向绑定语法,是一个语法糖方便开发者实现数据双向绑定,用于初始化子组件的\@Param和\@Event。其中\@Event方法名需要声明为“$”+ \@Param属性名,详见[使用场景](#使用场景)。
14
15- 如果父组件使用了`!!`双向绑定语法,则表明父组件的变化会同步给子组件,子组件的变化也会同步给父组件。
16- 如果父组件没有使用`!!`,则父组件发生的变化是单向的。
17
18
19## 使用限制
20`!!`双向绑定语法不支持多层父子组件传递。
21
22
23## 使用场景
24
25### 自定义组件间双向绑定
261. Index中构造Star子组件,双向绑定父子组件中的value,初始化子组件的`@Param value`和`@Event $value`
27- 双向绑定语法糖可视为:
28
29    ```
30    Star({ value: this.value, $value: (val: number) => { this.value = val }})
31    ```
322. 点击改变Index中的Button,改变value,父组件Index和子组件Star中Text更新。
333. 点击改变子组件Star中的Button,调用`this.$value(10)`,父组件Index和子组件Star中Text更新。
34
35```ts
36@Entry
37@ComponentV2
38struct Index {
39  @Local value: number = 0;
40
41  build() {
42    Column() {
43      Text(`${this.value}`)
44      Button(`change value`).onClick(() => {
45        this.value++;
46      })
47      Star({ value: this.value!! })
48    }
49  }
50}
51
52
53@ComponentV2
54struct Star {
55  @Param value: number = 0;
56  @Event $value: (val: number) => void = (val: number) => {};
57
58  build() {
59    Column() {
60      Text(`${this.value}`)
61      Button(`change value `).onClick(() => {
62        this.$value(10);
63      })
64    }
65  }
66}
67```
68
69
70### 内置组件参数双向绑定
71
72!!运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。添加方式是在变量名后添加,例如isShow!!。
73
74内部状态具体指什么取决于组件。例如,[bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md)组件的isShow参数。
75
76#### 使用规则
77
78- 当前!!支持以下接口参数基础类型变量的双向绑定,也就是参数同步当前弹出菜单或气泡状态。!!双向绑定支持基础类型变量,当该变量使用状态管理V2[\@Local](arkts-new-local.md)或状态管理V1[\@State](arkts-state.md)装饰时,变量值的变化会触发UI刷新。
79
80  | 属性                                                         | 支持的参数 | 起始API版本 |
81  | ------------------------------------------------------------ | --------------- | ----------- |
82  | [bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindmenu11) | isShow | 13          |
83  | [bindContextMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindcontextmenu12) | isShown | 13          |
84  | [bindPopup](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#bindpopup) | show | 13   |
85
86- !!绑定的[\@Local](arkts-new-local.md)变量变化时,会触发UI的同步刷新。
87
88
89#### 使用示例
90
91bindMenu接口isShow参数双向绑定功能
92
93```ts
94@Entry
95@ComponentV2
96struct BindMenuInterface {
97  @Local isShow: boolean = false;
98
99  build() {
100    Column() {
101      Row() {
102        Text('click show Menu')
103          .bindMenu(this.isShow!!, // 双向绑定
104            [
105              {
106                value: 'Menu1',
107                action: () => {
108                  console.info('handle Menu1 click');
109                }
110              },
111              {
112                value: 'Menu2',
113                action: () => {
114                  console.info('handle Menu2 click');
115                }
116              },
117            ])
118      }.height('50%')
119      Text("当前isShow: " + this.isShow).fontSize(18).fontColor(Color.Red)
120      Row() {
121        Button("Click")
122          .onClick(() => {
123            this.isShow = true;
124          })
125          .width(100)
126          .fontSize(20)
127          .margin(10)
128      }
129    }.width('100%')
130  }
131}
132```
133
134![bindMenu](figures/bindmenu_doublebind.gif)
135