1e41f4b71Sopenharmony_ci# \@Event Decorator: Component Output
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciYou can use \@Event, a variable decorator in state management V2, to enable a child component to require the parent component to update the \@Param decorated variables.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci>**NOTE**
6e41f4b71Sopenharmony_ci>
7e41f4b71Sopenharmony_ci>The \@Event decorator is supported since API version 12.
8e41f4b71Sopenharmony_ci>
9e41f4b71Sopenharmony_ci>State management V2 is still under development, and some features may be incomplete or not always work as expected.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## Overview
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciThe variables decorated by \@Param cannot be changed locally. You can use the \@Event decorator to decorate a callback, which is called to change the variables of the data source. You can synchronize the changes to \@Param by using the synchronization mechanism of \@Local. In this way, the variables decorated by \@Param can be updated actively.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciWhen using \@Event to decorate a component:
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci- You need to determine the parameters and return value in the callback decorated by \@Event.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci- Variables of non-callback types decorated by \@Event do not take effect. If \@Event is not initialized, an empty function will be automatically generated as the default callback.
20e41f4b71Sopenharmony_ci- If \@Event is not initialized externally but has a default value, the default function will be used for processing.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci\@Param indicates the input of a component, and this variable is affected by the parent component. \@Event indicates the output of a component, and the output method affects the parent component. Decorating a callback with \@Event indicates that the callback is the output of the custom component. The parent component needs to determine whether to provide the corresponding method for the child component to change the data source of the \@Param variable.
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci## Decorator Description
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci| \@Event Decorator| Description|
27e41f4b71Sopenharmony_ci| ------------------- | ------------------------------------------------------------ |
28e41f4b71Sopenharmony_ci| Decorator parameters| None.|
29e41f4b71Sopenharmony_ci| Allowed variable types| Callback, such as **()=>void** and **(x:number)=>boolean**. You can determine the return value and whether the callback contains parameters.|
30e41f4b71Sopenharmony_ci| Allowed function types| Arrow function.|
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci## Constraints
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci- \@Event can be used only in custom components decorated by \@ComponentV2. \@Event does not take effect if the decorated variable is not a function.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci  ```ts
37e41f4b71Sopenharmony_ci  @ComponentV2
38e41f4b71Sopenharmony_ci  struct Index {
39e41f4b71Sopenharmony_ci    @Event changeFactory: ()=>void = ()=>{}; // Correct usage.
40e41f4b71Sopenharmony_ci    @Event message: string = "abcd"; // Incorrect usage. The variable decorated is not a function.
41e41f4b71Sopenharmony_ci  }
42e41f4b71Sopenharmony_ci  @Component
43e41f4b71Sopenharmony_ci  struct CompA {
44e41f4b71Sopenharmony_ci    @Event changeFactory: ()=>void = ()=>{}; // Incorrect usage.
45e41f4b71Sopenharmony_ci  }
46e41f4b71Sopenharmony_ci  ```
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci## Use Scenarios
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci### Changing Variables in the Parent Component
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ciYou can use \@Event to change a variable in the parent component. When the variable is used as the data source of the \@Param variable in the child component, this change will be synchronized accordingly.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci```ts
56e41f4b71Sopenharmony_ci@Entry
57e41f4b71Sopenharmony_ci@ComponentV2
58e41f4b71Sopenharmony_cistruct Index {
59e41f4b71Sopenharmony_ci  @Local title: string = "Titile One";
60e41f4b71Sopenharmony_ci  @Local fontColor: Color = Color.Red;
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci  build() {
63e41f4b71Sopenharmony_ci    Column() {
64e41f4b71Sopenharmony_ci      Child({
65e41f4b71Sopenharmony_ci        title: this.title,
66e41f4b71Sopenharmony_ci        fontColor: this.fontColor,
67e41f4b71Sopenharmony_ci        changeFactory: (type: number) => {
68e41f4b71Sopenharmony_ci          if (type == 1) {
69e41f4b71Sopenharmony_ci            this.title = "Title One";
70e41f4b71Sopenharmony_ci            this.fontColor = Color.Red;
71e41f4b71Sopenharmony_ci          } else if (type == 2) {
72e41f4b71Sopenharmony_ci            this.title = "Title Two";
73e41f4b71Sopenharmony_ci            this.fontColor = Color.Green;
74e41f4b71Sopenharmony_ci          }
75e41f4b71Sopenharmony_ci        }
76e41f4b71Sopenharmony_ci      })
77e41f4b71Sopenharmony_ci    }
78e41f4b71Sopenharmony_ci  }
79e41f4b71Sopenharmony_ci}
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci@ComponentV2
82e41f4b71Sopenharmony_cistruct Child {
83e41f4b71Sopenharmony_ci  @Param title: string = '';
84e41f4b71Sopenharmony_ci  @Param fontColor: Color = Color.Black;
85e41f4b71Sopenharmony_ci  @Event changeFactory: (x: number) => void = (x: number) => {};
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci  build() {
88e41f4b71Sopenharmony_ci    Column() {
89e41f4b71Sopenharmony_ci      Text(`${this.title}`)
90e41f4b71Sopenharmony_ci      Button("change to Title Two")
91e41f4b71Sopenharmony_ci        .onClick(() => {
92e41f4b71Sopenharmony_ci          this.changeFactory(2);
93e41f4b71Sopenharmony_ci        })
94e41f4b71Sopenharmony_ci      Button("change to Title One")
95e41f4b71Sopenharmony_ci        .onClick(() => {
96e41f4b71Sopenharmony_ci          this.changeFactory(1);
97e41f4b71Sopenharmony_ci        })
98e41f4b71Sopenharmony_ci    }
99e41f4b71Sopenharmony_ci  }
100e41f4b71Sopenharmony_ci}
101e41f4b71Sopenharmony_ci````
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ciNote that using \@Event to change the value of the parent component takes effect immediately. However, the process of synchronizing the change from the parent component to the child component is asynchronous. That is, after the method of \@Event is called, the value of the child component does not change immediately. This is because \@Event passes the actual change capability of the child component value to the parent component for processing. After the parent component determines how to process the value, the final value is synchronized back to the child component before rendering.
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci```ts
106e41f4b71Sopenharmony_ci@ComponentV2
107e41f4b71Sopenharmony_cistruct Child {
108e41f4b71Sopenharmony_ci  @Param index: number = 0;
109e41f4b71Sopenharmony_ci  @Event changeIndex: (val: number) => void;
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci  build() {
112e41f4b71Sopenharmony_ci    Column() {
113e41f4b71Sopenharmony_ci      Text(`Child index: ${this.index}`)
114e41f4b71Sopenharmony_ci        .onClick(() => {
115e41f4b71Sopenharmony_ci          this.changeIndex(20);
116e41f4b71Sopenharmony_ci          console.log(`after changeIndex ${this.index}`);
117e41f4b71Sopenharmony_ci        })
118e41f4b71Sopenharmony_ci    }
119e41f4b71Sopenharmony_ci  }
120e41f4b71Sopenharmony_ci}
121e41f4b71Sopenharmony_ci@Entry
122e41f4b71Sopenharmony_ci@ComponentV2
123e41f4b71Sopenharmony_cistruct Index {
124e41f4b71Sopenharmony_ci  @Local index: number = 0;
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci  build() {
127e41f4b71Sopenharmony_ci  	Column() {
128e41f4b71Sopenharmony_ci  	  Child({
129e41f4b71Sopenharmony_ci  	    index: this.index,
130e41f4b71Sopenharmony_ci  	    changeIndex: (val: number) => {
131e41f4b71Sopenharmony_ci  	      this.index = val;
132e41f4b71Sopenharmony_ci          console.log(`in changeIndex ${this.index}`);
133e41f4b71Sopenharmony_ci  	    }
134e41f4b71Sopenharmony_ci  	  })
135e41f4b71Sopenharmony_ci  	}
136e41f4b71Sopenharmony_ci  }
137e41f4b71Sopenharmony_ci}
138e41f4b71Sopenharmony_ci```
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ciIn the preceding example, clicking the text triggers the \@Event function event to change the value of the child component. The printed log is as follows:
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci```
143e41f4b71Sopenharmony_ciin changeIndex 20
144e41f4b71Sopenharmony_ciafter changeIndex 0
145e41f4b71Sopenharmony_ci```
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ciThis indicates that after **changeIndex** is called, the **index** in the parent component has changed, but the one in the child component has not changed yet.
148