• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@Event Decorator: Standardizing Component Output
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiyujia926-->
5<!--Designer: @s10021109-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @zhang_yixin13-->
8
9You 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. Using \@Event to decorate the callback method is a standard, indicating that the child component needs to pass in the callback for updating the data source.
10
11
12\@Event works with \@Param to implement two-way data synchronization. Before reading this topic, you are advised to read [\@Param](./arkts-new-param.md).
13
14>**NOTE**
15>
16> The \@Event decorator is supported since API version 12.
17>
18> This decorator can be used in atomic services since API version 12.
19
20## Overview
21
22Since the variables decorated with \@Param cannot be changed locally, you can use the \@Event decorator todefine a callback for updating the data source. Combined with the synchronization mechanism of [\@Local](arkts-new-local.md), it allows changes to propagate back to \@Param, achieving active updates to @Param decorated variables.
23
24\@Event is used to decorate a component's output methods. When using this decorator, note the following:
25
26- You need to determine the parameters and return value in the callback decorated with \@Event.
27
28- \@Event has no effect when decorating non-callback variables. If uninitialized, it automatically generates an empty function as the default callback.
29- If \@Event is not initialized externally but has a default value, the default function will be used for processing.
30
31\@Param marks the input of a component, indicating that the decorated variable is affected by the parent component. \@Event marks the output of a component, allowing the child component to influence the parent. 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.
32
33## Decorator Description
34
35| \@Event Decorator| Description|
36| ------------------- | ------------------------------------------------------------ |
37| Decorator parameters| None.|
38| Allowed variable types| Callback, such as **()=>void** and **(x:number)=>boolean**. You can specify the return value and whether the callback contains parameters.|
39| Allowed function types| Arrow function.|
40
41## Constraints
42
43- \@Event can be used only in custom components decorated with [\@ComponentV2](arkts-new-componentV2.md). It does not take effect if the decorated variable is not a function.
44
45  ```ts
46  @ComponentV2
47  struct Index {
48    @Event changeFactory: ()=>void = ()=>{}; // Correct usage.
49    @Event message: string = 'abcd'; // Incorrect usage: Decorating a non-function variable, @Event has no effect.
50  }
51  @Component
52  struct Index {
53    @Event changeFactory: ()=>void = ()=>{}; // Incorrect usage. An error is reported during compilation.
54  }
55  ```
56
57
58## Use Scenarios
59
60### Changing Variables in the Parent Component
61
62You 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.
63
64```ts
65@Entry
66@ComponentV2
67struct Index {
68  @Local title: string = 'Title One';
69  @Local fontColor: Color = Color.Red;
70
71  build() {
72    Column() {
73      Child({
74        title: this.title,
75        fontColor: this.fontColor,
76        changeFactory: (type: number) => {
77          if (type == 1) {
78            this.title = 'Title One';
79            this.fontColor = Color.Red;
80          } else if (type == 2) {
81            this.title = 'Title Two';
82            this.fontColor = Color.Green;
83          }
84        }
85      })
86    }
87  }
88}
89
90@ComponentV2
91struct Child {
92  @Param title: string = '';
93  @Param fontColor: Color = Color.Black;
94  @Event changeFactory: (x: number) => void = (x: number) => {};
95
96  build() {
97    Column() {
98      Text(`${this.title}`)
99        .fontColor(this.fontColor)
100      Button('change to Title Two')
101        .onClick(() => {
102          this.changeFactory(2);
103        })
104      Button('change to Title One')
105        .onClick(() => {
106          this.changeFactory(1);
107        })
108    }
109  }
110}
111```
112
113Note 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.
114
115```ts
116@ComponentV2
117struct Child {
118  @Param index: number = 0;
119  @Event changeIndex: (val: number) => void;
120
121  build() {
122    Column() {
123      Text(`Child index: ${this.index}`)
124        .onClick(() => {
125          this.changeIndex(20);
126          console.log(`after changeIndex ${this.index}`);
127        })
128    }
129  }
130}
131@Entry
132@ComponentV2
133struct Index {
134  @Local index: number = 0;
135
136  build() {
137  	Column() {
138  	  Child({
139  	    index: this.index,
140  	    changeIndex: (val: number) => {
141  	      this.index = val;
142          console.log(`in changeIndex ${this.index}`);
143  	    }
144  	  })
145  	}
146  }
147}
148```
149
150In 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:
151
152```
153in changeIndex 20
154after changeIndex 0
155```
156
157This 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.
158