1e41f4b71Sopenharmony_ci# Data Transfer and Processing
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## props
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciYou can use **props** to declare attributes of a custom component and pass the attributes to the child component. The supported types of **props** include String, Number, Boolean, Array, Object, and Function. Note that a camel case attribute name (**compProp**) should be converted to the kebab case format (**comp-prop**) when you reference the attribute in an external parent component. The following is sample for adding **props** to a custom component and passing the attribute to the child component.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci```html
9e41f4b71Sopenharmony_ci<!-- comp.hml -->
10e41f4b71Sopenharmony_ci<div class="item"> 
11e41f4b71Sopenharmony_ci   <text class="title-style">{{compProp}}</text> 
12e41f4b71Sopenharmony_ci</div>
13e41f4b71Sopenharmony_ci```
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci```js
16e41f4b71Sopenharmony_ci// comp.js 
17e41f4b71Sopenharmony_ciexport default { 
18e41f4b71Sopenharmony_ci  props: ['compProp'],
19e41f4b71Sopenharmony_ci}
20e41f4b71Sopenharmony_ci```
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci```html
23e41f4b71Sopenharmony_ci<!-- xxx.hml -->
24e41f4b71Sopenharmony_ci<element name='comp' src='../common/component/comp/comp.hml'></element>
25e41f4b71Sopenharmony_ci<div class="container"> 
26e41f4b71Sopenharmony_ci   <comp comp-prop="{{title}}"></comp> 
27e41f4b71Sopenharmony_ci</div>
28e41f4b71Sopenharmony_ci```
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci>  **NOTE**
31e41f4b71Sopenharmony_ci>
32e41f4b71Sopenharmony_ci>  The name of a custom attribute cannot start with reserved keywords such as **on**, **@**, **on:**, and **grab:**.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci### Default Value
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ciYou can set the default value for a child component attribute via **default**. The default value is used if the parent component does not have **default** set. In this case, the **props** attribute must be in object format instead of an array.
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci```html
39e41f4b71Sopenharmony_ci<!-- comp.hml -->
40e41f4b71Sopenharmony_ci<div class="item"> 
41e41f4b71Sopenharmony_ci   <text class="title-style">{{title}}</text> 
42e41f4b71Sopenharmony_ci</div>
43e41f4b71Sopenharmony_ci```
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci```js
46e41f4b71Sopenharmony_ci// comp.js
47e41f4b71Sopenharmony_ciexport default { 
48e41f4b71Sopenharmony_ci  props: {
49e41f4b71Sopenharmony_ci    title: {
50e41f4b71Sopenharmony_ci      default: 'title',
51e41f4b71Sopenharmony_ci    },
52e41f4b71Sopenharmony_ci  },
53e41f4b71Sopenharmony_ci}
54e41f4b71Sopenharmony_ci```
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ciIn this example, a **\<text>** component is added to display the title. The title content is a custom attribute, which displays the text specified by a user. If the user has not set a title, the default text will be displayed. Add the attribute when referencing the custom component.
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci```html
59e41f4b71Sopenharmony_ci<!-- xxx.hml -->
60e41f4b71Sopenharmony_ci<element name='comp' src='../common/component/comp/comp.hml'></element>
61e41f4b71Sopenharmony_ci<div class="container"> 
62e41f4b71Sopenharmony_ci   <comp title="Custom component"></comp>
63e41f4b71Sopenharmony_ci</div>
64e41f4b71Sopenharmony_ci```
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci### Unidirectional Value Transfer
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ciData can be transferred only from the parent component to child components. You are not allowed to change the value passed to the child component. However, you can receive the value passed by **props** as a default value in **data**, and then change the **data** value.
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci```js
71e41f4b71Sopenharmony_ci// comp.js
72e41f4b71Sopenharmony_ciexport default { 
73e41f4b71Sopenharmony_ci  props: ['defaultCount'],
74e41f4b71Sopenharmony_ci  data() {
75e41f4b71Sopenharmony_ci    return {
76e41f4b71Sopenharmony_ci      count: this.defaultCount,
77e41f4b71Sopenharmony_ci    };
78e41f4b71Sopenharmony_ci  },
79e41f4b71Sopenharmony_ci  onClick() {
80e41f4b71Sopenharmony_ci    this.count = this.count + 1;
81e41f4b71Sopenharmony_ci  },
82e41f4b71Sopenharmony_ci}
83e41f4b71Sopenharmony_ci```
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci### Monitoring Data Changes by **$watch**
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ciTo listen for attribute changes in a component, you can use the **$watch** method to add a callback. The following code snippet shows how to use **$watch**:
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci```js
90e41f4b71Sopenharmony_ci// comp.js
91e41f4b71Sopenharmony_ciexport default { 
92e41f4b71Sopenharmony_ci  props: ['title'],
93e41f4b71Sopenharmony_ci  onInit() {
94e41f4b71Sopenharmony_ci    this.$watch('title', 'onPropertyChange');
95e41f4b71Sopenharmony_ci  },
96e41f4b71Sopenharmony_ci  onPropertyChange(newV, oldV) {
97e41f4b71Sopenharmony_ci    console.info('title attribute changed'+ newV + ' ' + oldV)
98e41f4b71Sopenharmony_ci  },
99e41f4b71Sopenharmony_ci}
100e41f4b71Sopenharmony_ci```
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci## computed
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ciTo improve the development efficiency, you can use a computed property to pre-process an attribute in a custom component before reading or setting the attribute. In the **computed** field, you can set a getter or setter to be triggered when the attribute is read or written, respectively. The following is an example:
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci```js
108e41f4b71Sopenharmony_ci// comp.js
109e41f4b71Sopenharmony_ciexport default { 
110e41f4b71Sopenharmony_ci  props: ['title'],
111e41f4b71Sopenharmony_ci  data() {
112e41f4b71Sopenharmony_ci    return {
113e41f4b71Sopenharmony_ci      objTitle: this.title,
114e41f4b71Sopenharmony_ci      time: 'Today',
115e41f4b71Sopenharmony_ci    };
116e41f4b71Sopenharmony_ci  },
117e41f4b71Sopenharmony_ci  computed: {
118e41f4b71Sopenharmony_ci    message() {
119e41f4b71Sopenharmony_ci      return this.time + ' ' + this.objTitle;
120e41f4b71Sopenharmony_ci    },
121e41f4b71Sopenharmony_ci    notice: {
122e41f4b71Sopenharmony_ci      get() {
123e41f4b71Sopenharmony_ci        return this.time;
124e41f4b71Sopenharmony_ci      },
125e41f4b71Sopenharmony_ci      set(newValue) {
126e41f4b71Sopenharmony_ci        this.time = newValue;
127e41f4b71Sopenharmony_ci      },
128e41f4b71Sopenharmony_ci    },
129e41f4b71Sopenharmony_ci  },
130e41f4b71Sopenharmony_ci  onClick() {
131e41f4b71Sopenharmony_ci    console.info('get click event ' + this.message);
132e41f4b71Sopenharmony_ci    this.notice = 'Tomorrow';
133e41f4b71Sopenharmony_ci  },
134e41f4b71Sopenharmony_ci}
135e41f4b71Sopenharmony_ci```
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ciThe first computed property **message** has only a getter. The value of **message** changes depending on the **objTitle** value. The getter can only read but cannot set the value (such as **time** defined during initialization in **data**). You need a setter (such as **notice** in the sample code) to set the value of the computed property.
138