1# \@Event Decorator: Component Output
2
3You 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.
4
5>**NOTE**
6>
7>The \@Event decorator is supported since API version 12.
8>
9
10## Overview
11
12The 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.
13
14When using \@Event to decorate a component:
15
16- You need to determine the parameters and return value in the callback decorated by \@Event.
17
18- 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.
19- If \@Event is not initialized externally but has a default value, the default function will be used for processing.
20
21\@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.
22
23## Decorator Description
24
25| \@Event Decorator| Description|
26| ------------------- | ------------------------------------------------------------ |
27| Decorator parameters| None.|
28| Allowed variable types| Callback, such as **()=>void** and **(x:number)=>boolean**. You can determine the return value and whether the callback contains parameters.|
29| Allowed function types| Arrow function.|
30
31## Constraints
32
33- \@Event can be used only in custom components decorated by \@ComponentV2. It does not take effect if the decorated variable is not a function.
34
35  ```ts
36  @ComponentV2
37  struct Index {
38    @Event changeFactory: ()=>void = ()=>{}; // Correct usage.
39    @Event message: string = "abcd"; // Incorrect usage. Variable of the non-function type is decorated.
40  }
41  @Component
42  struct CompA {
43    @Event changeFactory: ()=>void = ()=>{}; // Incorrect usage. An error is reported during compilation.
44  }
45  ```
46
47
48## Use Scenarios
49
50### Changing Variables in the Parent Component
51
52You 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.
53
54```ts
55@Entry
56@ComponentV2
57struct Index {
58  @Local title: string = "Titile One";
59  @Local fontColor: Color = Color.Red;
60
61  build() {
62    Column() {
63      Child({
64        title: this.title,
65        fontColor: this.fontColor,
66        changeFactory: (type: number) => {
67          if (type == 1) {
68            this.title = "Title One";
69            this.fontColor = Color.Red;
70          } else if (type == 2) {
71            this.title = "Title Two";
72            this.fontColor = Color.Green;
73          }
74        }
75      })
76    }
77  }
78}
79
80@ComponentV2
81struct Child {
82  @Param title: string = '';
83  @Param fontColor: Color = Color.Black;
84  @Event changeFactory: (x: number) => void = (x: number) => {};
85
86  build() {
87    Column() {
88      Text(`${this.title}`)
89        .fontColor(this.fontColor)
90      Button("change to Title Two")
91        .onClick(() => {
92          this.changeFactory(2);
93        })
94      Button("change to Title One")
95        .onClick(() => {
96          this.changeFactory(1);
97        })
98    }
99  }
100}
101```
102
103Note 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.
104
105```ts
106@ComponentV2
107struct Child {
108  @Param index: number = 0;
109  @Event changeIndex: (val: number) => void;
110
111  build() {
112    Column() {
113      Text(`Child index: ${this.index}`)
114        .onClick(() => {
115          this.changeIndex(20);
116          console.log(`after changeIndex ${this.index}`);
117        })
118    }
119  }
120}
121@Entry
122@ComponentV2
123struct Index {
124  @Local index: number = 0;
125
126  build() {
127  	Column() {
128  	  Child({
129  	    index: this.index,
130  	    changeIndex: (val: number) => {
131  	      this.index = val;
132          console.log(`in changeIndex ${this.index}`);
133  	    }
134  	  })
135  	}
136  }
137}
138```
139
140In 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:
141
142```
143in changeIndex 20
144after changeIndex 0
145```
146
147This 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