• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# JavaScript
2
3
4You can use a .js file in the ECMAScript compliant JavaScript language to define the service logic of an HML page. With dynamic typing, JavaScript can make your application more expressive with a flexible design. The following describes the JavaScript compilation and running.
5
6
7## Syntax
8
9The ES6 syntax is supported.
10
11- Module declaration
12
13  Import functionality modules.
14
15  ```
16  import router from '@system.router';
17  ```
18
19- Code reference
20
21  Import JavaScript code.
22
23
24  ```
25  import utils from '../../common/utils.js';
26  ```
27
28
29## Objects
30
31- Application objects
32  | Name | Type | Description |
33  | -------- | -------- | -------- |
34  | $def | Object | Object that is exposed in the app.js file and obtained by `this.$app.$def`.<br/>> **NOTE**<br/>> Application objects do not support data binding. Data update should be triggered on the UI. |
35
36  Example
37
38  ```js
39  // app.js
40  export default {
41    onCreate() {
42      console.info('Application onCreate');
43    },
44    onDestroy() {
45      console.info('Application onDestroy');
46    },
47    globalData: {
48      appData: 'appData',
49      appVersion: '2.0',
50    },
51    globalMethod() {
52      console.info('This is a global method!');
53      this.globalData.appVersion = '3.0';
54    }
55  };
56  ```
57
58  ```js
59  // index.js
60  export default {
61    data: {
62      appData: 'localData',
63      appVersion:'1.0',
64    },
65    onInit() {
66      this.appData = this.$app.$def.globalData.appData;
67      this.appVersion = this.$app.$def.globalData.appVersion;
68    },
69    invokeGlobalMethod() {
70      this.$app.$def.globalMethod();
71    },
72    getAppVersion() {
73      this.appVersion = this.$app.$def.globalData.appVersion;
74    }
75  }
76  ```
77
78- Page objects
79  | Attribute | Type | Description |
80  | -------- | -------- | -------- |
81  | 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 attribute 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. |
82  | $refs | Object | DOM elements or child component instances that have registered the ref attribute. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element). |
83  | private | Object | Data model of the page. Private data attribute can be modified only on the current page. |
84  | public | Object | Data model of the page. Behaviors of public data attributes are the same as those of the data attribute. |
85  | props | Array/Object | Used for communication between components. This attribute can be transferred to components via &lt;tag xxxx='value'&gt;. 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). Currently, props does not support functions. For details, see [props](../reference/arkui-js/js-components-custom-props.md). |
86  | computed | Object | Used for pre-processing an object for reading and setting. The result is cached. The name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words. For details, see [props](../reference/arkui-js/js-components-custom-props.md). |
87
88## Methods
89
90- Data methods
91  | Name | Parameter | Description |
92  | -------- | -------- | -------- |
93  | $set | key: string, value: any | Adds an attribute or modifies an existing attribute.<br/>Usage:<br/>this.$set('_key_',_value_): Add an attribute. |
94  | $delete | key: string | Deletes an attribute.<br/>Usage:<br/>this.$delete('key'): Delete an attribute. |
95
96  Example
97
98  ```js
99  // index.js
100  export default {
101    data: {
102      keyMap: {
103        OS: 'OpenHarmony',
104        Version: '2.0',
105      },
106    },
107    getAppVersion() {
108      this.$set('keyMap.Version', '3.0');
109      console.info("keyMap.Version = " + this.keyMap.Version); // keyMap.Version = 3.0
110
111      this.$delete('keyMap');
112      console.info("keyMap.Version = " + this.keyMap); // log print: keyMap.Version = undefined
113    }
114  }
115  ```
116
117- Public methods
118  | Name | Parameter | Description |
119  | -------- | -------- | -------- |
120  | $element | id: string | Obtains the component with a specified ID. If no ID is specified, the root component is returned. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element).<br/>Usage:<br/>```<div id='_xxx_'></div>```<br/>- this.$element('_xxx_'): Obtain the component whose ID is _xxx_.<br/>- this.$element(): Obtain the root component. |
121  | $rootElement | None | Obtains the root element.<br/>Usage: this.$rootElement().scrollTo({ duration: 500, position: 300 }), which scrolls the page by 300 px within 500 ms. |
122  | $root | N/A | Obtains the root ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). |
123  | $parent | N/A | Obtains the parent ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). |
124  | $child | id: string | Obtains the ViewModel instance of a custom child component with a specified ID. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel).<br/>Usage:<br/>this.$child('xxx'): Obtain the ViewModel instance of a custom child component whose ID is _xxx_. |
125
126- Event methods
127  | Name | Parameter | Description |
128  | -------- | -------- | -------- |
129  | $watch | data: string, callback: string \| Function | Listens for attribute changes. If the value of the data attribute changes, the bound event is triggered. For details, see [props](../reference/arkui-js/js-components-custom-props.md)<br/>Usage:<br/>this.$watch('key', callback) |
130
131- Page methods
132  | Name | Parameter | Description |
133  | -------- | -------- | -------- |
134  | scrollTo<sup>6+</sup> | scrollPageParam:  ScrollPageParam | Scrolls the page to the target position. You can specify the position using the ID selector or scrolling distance. |
135
136  **Table 1** ScrollPageParam<sup>6+</sup>
137
138  | Name | Type | Default Value | Description |
139  | -------- | -------- | -------- | -------- |
140  | position | number | - | Position to scroll to. |
141  | id | string | - | ID of the element to be scrolled to. |
142  | duration | number | 300 | Scrolling duration, in milliseconds. |
143  | timingFunction | string | ease | Animation curve for scrolling. Available options:<br/>[Animation Styles](../reference/arkui-js/js-components-common-animation.md) |
144  | complete | () => void | - | Callback to be invoked when the scrolling is complete. |
145
146  Example
147
148
149  ```js
150  this.$rootElement().scrollTo({position: 0})
151  this.$rootElement().scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void})
152  ```
153
154
155## Obtaining a DOM Element
156
1571. Use `$refs` to obtain a DOM element.
158   ```html
159   <!-- index.hml -->
160   <div class="container">
161     <image-animator class="image-player" ref="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
162   </div>
163   ```
164
165   ```js
166   // index.js
167   export default {
168     data: {
169       images: [
170         { src: '/common/frame1.png' },
171         { src: '/common/frame2.png' },
172         { src: '/common/frame3.png' }
173       ]
174     },
175     handleClick() {
176       const animator = this.$refs.animator; // Obtain the DOM element whose $refs attribute is animator.
177       const state = animator.getState();
178       if (state === 'paused') {
179         animator.resume();
180       } else if (state === 'stopped') {
181         animator.start();
182       } else {
183         animator.pause();
184       }
185     },
186   };
187   ```
188
1892. Call `$element` to obtain a DOM element.
190
191   ```html
192   <!-- index.hml -->
193   <div class="container" style="width:500px;height: 700px; margin: 100px;">
194     <image-animator class="image-player" id="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
195   </div>
196   ```
197
198   ```js
199   // index.js
200   export default {
201     data: {
202       images: [
203         { src: '/common/frame1.png' },
204         { src: '/common/frame2.png' },
205         { src: '/common/frame3.png' }
206       ]
207     },
208     handleClick() {
209       const animator = this.$element('animator'); // Obtain the DOM element whose ID is animator.
210       const state = animator.getState();
211       if (state === 'paused') {
212         animator.resume();
213       } else if (state === 'stopped') {
214         animator.start();
215       } else {
216         animator.pause();
217       }
218     },
219   };
220   ```
221
222![en-us_image_0000001118642007](figures/en-us_image_0000001118642007.gif)
223
224## Obtaining the ViewModel
225
226The following shows files of the root page:
227
228```html
229<!-- root.hml -->
230<element name='parentComp' src='../../common/component/parent/parent.hml'></element>
231<div class="container">
232  <div class="container">
233    <text>{{text}}</text>
234    <parentComp></parentComp>
235  </div>
236</div>
237```
238
239```js
240// root.js
241export default {
242  data: {
243    text: 'I am a root!',
244  },
245}
246```
247
248![en-us_image_0000001118642008](figures/en-us_image_0000001118642008.png)
249
250Customize the parent component.
251
252```html
253<!-- parent.hml -->
254<element name='childComp' src='../child/child.hml'></element>
255<div class="item" onclick="textClicked">
256  <text class="text-style" onclick="parentClicked">Click this parent component</text>
257  <text class="text-style" if="{{showValue}}">hello parent component!</text>
258  <childComp id = "selfDefineChild"></childComp>
259</div>
260```
261
262```js
263// parent.js
264export default {
265  data: {
266    showValue: false,
267    text: 'I am the parent component!',
268  },
269  parentClicked () {
270    this.showValue = !this.showValue
271    console.info('parent component get parent text');
272    console.info(`${this.$parent().text}`);
273    console.info("The parent component gets the child function.");
274    console.info(`${this.$child('selfDefineChild').childClicked()}`);
275  },
276}
277```
278
279Customize the child component.
280
281```html
282<!-- child.hml -->
283<div class="item" onclick="textClicked">
284  <text class="text-style" onclick="childClicked">Child component clicked</text>
285  <text class="text-style" if="{{isShow}}">Hello child component</text>
286</div>
287```
288
289```js
290// child.js
291export default {
292  data: {
293    isShow: false,
294    text: 'I am the child component!',
295  },
296  childClicked () {
297    this.isShow = !this.isShow;
298    console.info('child component get parent text');
299    console.info('${this.$parent().text}');
300    console.info('child component get root text');
301    console.info('${this.$root().text}');
302  },
303}
304```
305
306![en-us_image_0000001118642009](figures/en-us_image_0000001118642009.gif)