1# Basic Usage of Custom Components
2
3Custom components are existing components encapsulated based on service requirements. A custom component can be invoked multiple times in a project to improve the code readability. You can import a custom component to the host page through **element** as shown in the following code snippet:
4
5```html
6<element name='comp' src='../common/component/comp.hml'></element>
7<div>
8  <comp prop1='xxxx' @child1="bindParentVmMethod"></comp>
9</div>
10```
11
12The following is an example of using a custom component with **if-else**, which displays **comp1** when **showComp1** is set to **true** and displays **comp2** otherwise.
13
14```html
15<element name='comp1' src='../common/component/comp1/comp1.hml'></element>
16<element name='comp2' src='../common/component/comp2/comp2.hml'></element>
17<div>
18  <comp1 if="{{showComp1}}" prop1='xxxx' @child1="bindParentVmMethodOne"></comp1>
19  <comp2 else prop1='xxxx' @child1="bindParentVmMethodTwo"></comp2>
20</div>
21```
22
23The **name** attribute indicates the custom component name (optional), which is case-insensitive and is in lowercase by default. The **src** attribute indicates the **.hml** file path (mandatory) of the custom component. If **name** is not set, the **.hml** file name is used as the component name by default.
24
25
26## Custom Events
27
28To bind an event to a custom child component, use the **(on|@)event-name="bindParentVmMethod"** syntax. **this.$emit('eventName', { params: 'passedParameters' })** is used in the child component to trigger the event and pass parameters to the parent component. The parent component then calls the **bindParentVmMethod** API and receives parameters passed by the child component.
29
30>  **NOTE**
31>
32>  For child component events that are named in camel case, convert the names to kebab case when binding the events to the parent component. For example, use **\@children-event** in the parent component instead of **childrenEvent** used in the child component.
33
34**Example 1 with parameters passed**
35
36The following example describes how to define a child component **comp**:
37
38```html
39<!-- comp.hml -->
40<div class="item">
41   <text class="text-style" onclick="childClicked">Click here to view the hidden text.</text>
42   <text class="text-style" if="{{showObj}}">hello world</text>
43</div>
44```
45
46```css
47/* comp.css */
48.item {
49  width: 700px;
50  flex-direction: column;
51  height: 300px;
52  align-items: center;
53  margin-top: 100px;
54}
55.text-style {
56  font-weight: 500;
57  font-family: Courier;
58  font-size: 40px;
59}
60```
61
62```js
63// comp.js
64export default {
65  data: {
66    showObj: false,
67  },
68  childClicked () {
69    this.$emit('eventType1');
70    this.showObj = !this.showObj;
71  },
72}
73```
74
75The following example describes how to import **comp** to the parent component:
76
77```html
78<!-- xxx.hml -->
79<element name='comp' src='../common/component/comp.hml'></element>
80<div class="container">
81  <comp @event-type1="textClicked"></comp>
82</div>
83```
84
85```css
86/* xxx.css */
87.container {
88  background-color: #f8f8ff;
89  flex: 1;
90  flex-direction: column;
91  align-content: center;
92}
93```
94
95```js
96// xxx.js
97export default {
98  textClicked () {}
99}
100```
101
102**Example 2 with no parameters passed**
103
104The following example describes how to define a child component **comp**:
105
106```html
107<!-- comp.hml -->
108<div class="item">
109   <text class="text-style" onclick="childClicked">Click here to view the hidden text.</text>
110   <text class="text-style" if="{{ showObj }}">hello world</text>
111</div>
112```
113
114```js
115// comp.js
116export default {
117  childClicked () {
118    this.$emit('eventType1', { text: 'Receive the parameters from the child component.' });
119    this.showObj = !this.showObj;
120  },
121}
122```
123
124In the following example, the child component passes the **text** parameter to the parent component, and the parent component obtains the parameter through **e.detail**:
125
126```html
127<!-- xxx.hml -->
128<element name='comp' src='../common/comp/comp.hml'></element>
129<div class="container">
130   <text>Parent component: {{text}}</text>
131   <comp @event-type1="textClicked"></comp>
132</div>
133```
134
135```js
136// xxx.js
137export default {
138  data: {
139    text: 'Start'
140  },
141  textClicked (e) {
142    this.text = e.detail.text;
143  },
144}
145```
146
147![EventParameters](figures/EventParameters.gif)
148
149
150## Custom Component Data
151
152
153In the JS file of a custom component, you can define, pass, and process data by declaring fields such as **data**, **props**, and **computed**. For details about how to use **props** and **computed**, see [Data Transfer and Processing](js-components-custom-props.md).
154
155**Table 1** Custom component data
156
157| Name     | Type           | Description                                    |
158| -------- | --------------- | ---------------------------------------- |
159| data     | Object \| Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The name cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words (**for**, **if**, **show**, and **tid**).<br>Do not use this attribute and **private** or **public** at the same time.|
160| props    | Array \| Object    | Used for communication between components. This attribute can be passed to components through **\<tag xxxx='value'>**. A **props** name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (**for**, **if**, **show**, and **tid**) in the name. Currently, **props** does not support functions.|
161| computed | Object          | Used for pre-processing for reading and setting parameters. The result is cached. The name cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words.|
162