1e41f4b71Sopenharmony_ci# HML
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciHML is an HTML-like language that allows you to build pages based on components and events. Pages built using HML have advanced capabilities such as data binding, event binding, loop rendering, conditional rendering, and logic control.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci## HML Page Structure
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci```html
9e41f4b71Sopenharmony_ci<!-- xxx.hml -->
10e41f4b71Sopenharmony_ci<div class="item-container">
11e41f4b71Sopenharmony_ci  <text class="item-title">Image Show</text>
12e41f4b71Sopenharmony_ci  <div class="item-content">
13e41f4b71Sopenharmony_ci    <image src="/common/xxx.png" class="image"></image>
14e41f4b71Sopenharmony_ci  </div>
15e41f4b71Sopenharmony_ci</div>
16e41f4b71Sopenharmony_ci```
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci## Data Binding
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci```html
22e41f4b71Sopenharmony_ci<!-- xxx.hml -->
23e41f4b71Sopenharmony_ci<div class="container" onclick="changeText">
24e41f4b71Sopenharmony_ci  <text> {{content[1]}} </text>
25e41f4b71Sopenharmony_ci</div>
26e41f4b71Sopenharmony_ci```
27e41f4b71Sopenharmony_ci```css
28e41f4b71Sopenharmony_ci/*xxx.css*/
29e41f4b71Sopenharmony_ci.container{
30e41f4b71Sopenharmony_ci    margin: 200px;
31e41f4b71Sopenharmony_ci}
32e41f4b71Sopenharmony_ci```
33e41f4b71Sopenharmony_ci```js
34e41f4b71Sopenharmony_ci// xxx.js
35e41f4b71Sopenharmony_ciexport default {
36e41f4b71Sopenharmony_ci  data: {
37e41f4b71Sopenharmony_ci    content: ['Hello World!', 'Welcome to my world!']
38e41f4b71Sopenharmony_ci  },
39e41f4b71Sopenharmony_ci  changeText: function() {
40e41f4b71Sopenharmony_ci    this.content.splice(1, 1, this.content[0]);
41e41f4b71Sopenharmony_ci  }
42e41f4b71Sopenharmony_ci}
43e41f4b71Sopenharmony_ci```
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci> **NOTE**
46e41f4b71Sopenharmony_ci> - To make the array data modification take effect, use the **splice** method to change array items.
47e41f4b71Sopenharmony_ci>
48e41f4b71Sopenharmony_ci> - ECMAScript 6 (ES6) syntax is not supported in HML.
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci![en-us_image_0000001118642003](figures/en-us_image_0000001118642003.png)
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci## Common Event Binding
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ciEvents are bound to components through **'on'** or **'\@'**. When a component triggers an event, the corresponding event processing function in the **.js** file is executed.
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ciEvents can be written in the following formats:
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci- **funcName**: name of the event callback, which is implemented by defining the corresponding function in the **.js** file.
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci- **funcName(a,b)**: function parameters, such as **a** and **b**, which can be constants, or variables defined in **data** in the **.js** file. Do not add the prefix **this.** to variables.
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci- Example
63e41f4b71Sopenharmony_ci  ```html
64e41f4b71Sopenharmony_ci  <!-- xxx.hml -->
65e41f4b71Sopenharmony_ci  <div class="container">
66e41f4b71Sopenharmony_ci      <text class="title">{{count}}</text>
67e41f4b71Sopenharmony_ci      <div class="box">
68e41f4b71Sopenharmony_ci          <input type="button" class="btn" value="increase" onclick="increase" />
69e41f4b71Sopenharmony_ci          <input type="button" class="btn" value="decrease" @click="decrease" />
70e41f4b71Sopenharmony_ci          <!-- Pass additional parameters. -->
71e41f4b71Sopenharmony_ci          <input type="button" class="btn" value="double" @click="multiply(2)" />
72e41f4b71Sopenharmony_ci          <input type="button" class="btn" value="decuple" @click="multiply(10)" />
73e41f4b71Sopenharmony_ci          <input type="button" class="btn" value="square" @click="multiply(count)" />
74e41f4b71Sopenharmony_ci      </div>
75e41f4b71Sopenharmony_ci  </div>
76e41f4b71Sopenharmony_ci  ```
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci  ```js
79e41f4b71Sopenharmony_ci  // xxx.js
80e41f4b71Sopenharmony_ci  export default {
81e41f4b71Sopenharmony_ci    data: {
82e41f4b71Sopenharmony_ci      count: 0
83e41f4b71Sopenharmony_ci    },
84e41f4b71Sopenharmony_ci    increase() {
85e41f4b71Sopenharmony_ci      this.count++;
86e41f4b71Sopenharmony_ci    },
87e41f4b71Sopenharmony_ci    decrease() {
88e41f4b71Sopenharmony_ci      this.count--;
89e41f4b71Sopenharmony_ci    },
90e41f4b71Sopenharmony_ci    multiply(multiplier) {
91e41f4b71Sopenharmony_ci      this.count = multiplier * this.count;
92e41f4b71Sopenharmony_ci    }
93e41f4b71Sopenharmony_ci  };
94e41f4b71Sopenharmony_ci  ```
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci  ```css
97e41f4b71Sopenharmony_ci  /* xxx.css */
98e41f4b71Sopenharmony_ci  .container {
99e41f4b71Sopenharmony_ci      display: flex;
100e41f4b71Sopenharmony_ci      flex-direction: column;
101e41f4b71Sopenharmony_ci      justify-content: center;
102e41f4b71Sopenharmony_ci      align-items: center;
103e41f4b71Sopenharmony_ci      left: 0px;
104e41f4b71Sopenharmony_ci      top: 0px;
105e41f4b71Sopenharmony_ci      width: 454px;
106e41f4b71Sopenharmony_ci      height: 454px;
107e41f4b71Sopenharmony_ci  }
108e41f4b71Sopenharmony_ci  .title {
109e41f4b71Sopenharmony_ci      font-size: 30px;
110e41f4b71Sopenharmony_ci      text-align: center;
111e41f4b71Sopenharmony_ci      width: 200px;
112e41f4b71Sopenharmony_ci      height: 100px;
113e41f4b71Sopenharmony_ci  }
114e41f4b71Sopenharmony_ci  .box {
115e41f4b71Sopenharmony_ci      width: 454px;
116e41f4b71Sopenharmony_ci      height: 200px;
117e41f4b71Sopenharmony_ci      justify-content: center;
118e41f4b71Sopenharmony_ci      align-items: center;
119e41f4b71Sopenharmony_ci      flex-wrap: wrap;
120e41f4b71Sopenharmony_ci  }
121e41f4b71Sopenharmony_ci  .btn {
122e41f4b71Sopenharmony_ci      width: 200px;
123e41f4b71Sopenharmony_ci      border-radius: 0;
124e41f4b71Sopenharmony_ci      margin-top: 10px;
125e41f4b71Sopenharmony_ci      margin-left: 10px;
126e41f4b71Sopenharmony_ci  }
127e41f4b71Sopenharmony_ci  ```
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci![en-us_image_0000001118642002](figures/en-us_image_0000001118642002.gif)
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci## Binding for Event Bubbling<sup>5+</sup>
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ciBinding for event bubbling covers the following:
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci- Bind an event callback for event bubbling: **on:{event}.bubble**. **on:{event}** is equivalent to **on:{event}.bubble**.
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci- Bind an event callback, but stop the event from bubbling upwards: **grab:{event}.bubble**. **grab:{event}** is equivalent to **grab:{event}.bubble**.
138e41f4b71Sopenharmony_ci  > **NOTE**
139e41f4b71Sopenharmony_ci  >
140e41f4b71Sopenharmony_ci  > Event bubbling occurs when the target element and its ancestors have registered a listener for the same event. When the event happens on the element, it first runs the event handler on it, then on its parent, and then all the way up on other ancestors. If an element triggers this event, it first triggers the callback on the element, then on its parent, and then all the way up on other ancestors.
141e41f4b71Sopenharmony_ci  >
142e41f4b71Sopenharmony_ci  > For details about event bubbling, see [Universal Events](../reference/apis-arkui/arkui-js/js-components-common-events.md).
143e41f4b71Sopenharmony_ci- Example
144e41f4b71Sopenharmony_ci  ```html
145e41f4b71Sopenharmony_ci  <!-- xxx.hml -->
146e41f4b71Sopenharmony_ci  <div>
147e41f4b71Sopenharmony_ci     <!-- Bind an event callback for event bubbling.5+ -->
148e41f4b71Sopenharmony_ci      <div on:touchstart.bubble="touchstartfunc"></div>
149e41f4b71Sopenharmony_ci      <div on:touchstart="touchstartfunc"></div>
150e41f4b71Sopenharmony_ci      <!-- Bind an event callback, but stop the event from bubbling upwards.5+ -->
151e41f4b71Sopenharmony_ci      <div grab:touchstart.bubble="touchstartfunc"></div>
152e41f4b71Sopenharmony_ci      <div grab:touchstart="touchstartfunc"></div>
153e41f4b71Sopenharmony_ci      <!-- Bind an event callback for event bubbling.6+ -->
154e41f4b71Sopenharmony_ci      <div on:click.bubble="clickfunc"></div>
155e41f4b71Sopenharmony_ci      <div on:click="clickfunc"></div>
156e41f4b71Sopenharmony_ci      <!-- Bind an event callback, but stop the event from bubbling upwards.6+ -->
157e41f4b71Sopenharmony_ci      <div grab:click.bubble="clickfunc"></div>
158e41f4b71Sopenharmony_ci      <div grab:click="clickfunc"></div>
159e41f4b71Sopenharmony_ci  </div>
160e41f4b71Sopenharmony_ci  ```
161e41f4b71Sopenharmony_ci
162e41f4b71Sopenharmony_ci  ```js
163e41f4b71Sopenharmony_ci  // xxx.js
164e41f4b71Sopenharmony_ci  export default {
165e41f4b71Sopenharmony_ci      clickfunc: function(e) {
166e41f4b71Sopenharmony_ci          console.log(e);
167e41f4b71Sopenharmony_ci      },
168e41f4b71Sopenharmony_ci      touchstartfuc: function(e) {
169e41f4b71Sopenharmony_ci          console.log(e);
170e41f4b71Sopenharmony_ci      },
171e41f4b71Sopenharmony_ci  }
172e41f4b71Sopenharmony_ci  ```
173e41f4b71Sopenharmony_ci
174e41f4b71Sopenharmony_ci> **NOTE**
175e41f4b71Sopenharmony_ci>
176e41f4b71Sopenharmony_ci> Events bound using a traditional statement (such as **onclick**) will bubble only when the API version in use is 6 or later.
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci## Binding for Event Capturing<sup>5+</sup>
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ciTouch events can be captured. In the capture phase, which precedes the bubbling phase, an event starts from the parent component to the child component.
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ciBinding for event capturing covers the following:
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci- Bind an event callback for event capturing: **on:{event}.capture**.
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ci- Bind an event callback, but stop the event from being captured during downward transfer: **grab:{event}.capture**.
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci- Example
189e41f4b71Sopenharmony_ci  ```html
190e41f4b71Sopenharmony_ci  <!-- xxx.hml -->
191e41f4b71Sopenharmony_ci  <div>
192e41f4b71Sopenharmony_ci      <!-- Bind an event callback for event capturing.5+ -->   
193e41f4b71Sopenharmony_ci      <div on:touchstart.capture="touchstartfunc"></div>
194e41f4b71Sopenharmony_ci      <!-- Bind an event callback, but stop the event from being captured during downward transfer.5+ -->
195e41f4b71Sopenharmony_ci      <div grab:touchstart.capture="touchstartfunc"></div>
196e41f4b71Sopenharmony_ci  </div>
197e41f4b71Sopenharmony_ci  ```
198e41f4b71Sopenharmony_ci
199e41f4b71Sopenharmony_ci  ```js
200e41f4b71Sopenharmony_ci  // xxx.js
201e41f4b71Sopenharmony_ci  export default {
202e41f4b71Sopenharmony_ci      touchstartfuc: function(e) {
203e41f4b71Sopenharmony_ci          console.log(e);
204e41f4b71Sopenharmony_ci      },
205e41f4b71Sopenharmony_ci  }
206e41f4b71Sopenharmony_ci  ```
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci## Loop Rendering
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ci```html
212e41f4b71Sopenharmony_ci<!-- xxx.hml -->
213e41f4b71Sopenharmony_ci<div class="array-container" style="flex-direction: column;margin: 200px;">
214e41f4b71Sopenharmony_ci  <!-- div loop rendering -->
215e41f4b71Sopenharmony_ci  <!-- By default, $item indicates the element in the array, and $idx indicates the index of the element in the array. -->
216e41f4b71Sopenharmony_ci  <div for="{{array}}" tid="id" onclick="changeText">
217e41f4b71Sopenharmony_ci    <text>{{$idx}}.{{$item.name}}</text>
218e41f4b71Sopenharmony_ci  </div>
219e41f4b71Sopenharmony_ci  <!-- Define the name for an element variable. -->
220e41f4b71Sopenharmony_ci  <div for="{{value in array}}" tid="id" onclick="changeText">    
221e41f4b71Sopenharmony_ci    <text>{{$idx}}.{{value.name}}</text>
222e41f4b71Sopenharmony_ci  </div>
223e41f4b71Sopenharmony_ci  <!-- Define an element variable and its index name. -->
224e41f4b71Sopenharmony_ci  <div for="{{(index, value) in array}}" tid="id" onclick="changeText">    
225e41f4b71Sopenharmony_ci    <text>{{index}}.{{value.name}}</text>
226e41f4b71Sopenharmony_ci  </div>
227e41f4b71Sopenharmony_ci</div>
228e41f4b71Sopenharmony_ci
229e41f4b71Sopenharmony_ci```
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci```js
232e41f4b71Sopenharmony_ci// xxx.js
233e41f4b71Sopenharmony_ciexport default {
234e41f4b71Sopenharmony_ci  data: {
235e41f4b71Sopenharmony_ci    array: [
236e41f4b71Sopenharmony_ci      {id: 1, name: 'jack', age: 18}, 
237e41f4b71Sopenharmony_ci      {id: 2, name: 'tony', age: 18},
238e41f4b71Sopenharmony_ci    ],
239e41f4b71Sopenharmony_ci  },
240e41f4b71Sopenharmony_ci  changeText: function() {
241e41f4b71Sopenharmony_ci    if (this.array[1].name === "tony"){
242e41f4b71Sopenharmony_ci      this.array.splice(1, 1, {id:2, name: 'Isabella', age: 18});
243e41f4b71Sopenharmony_ci    } else {
244e41f4b71Sopenharmony_ci      this.array.splice(2, 1, {id:3, name: 'Bary', age: 18});
245e41f4b71Sopenharmony_ci    }
246e41f4b71Sopenharmony_ci  },
247e41f4b71Sopenharmony_ci}
248e41f4b71Sopenharmony_ci```
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ciThe **tid** attribute accelerates the **for** loop and improves the re-rendering efficiency when data in a loop changes. It specifies the unique ID of each element in the array. If it is not specified, the index of each element in the array is used as the ID. For example, **tid="id"** indicates that the **id** attribute of each element is its unique ID. The **for** loop supports the following statements:
251e41f4b71Sopenharmony_ci
252e41f4b71Sopenharmony_ci- for="array": **array** is an array object, whose element variable is **$item** by default.
253e41f4b71Sopenharmony_ci
254e41f4b71Sopenharmony_ci- for="v in array": **v** is a custom element variable, whose index is **$idx** by default.
255e41f4b71Sopenharmony_ci
256e41f4b71Sopenharmony_ci- for="(i, v) in array": **i** indicates the element index, and **v** indicates the element variable. All elements of the array object will be looped through.
257e41f4b71Sopenharmony_ci
258e41f4b71Sopenharmony_ci> **NOTE**
259e41f4b71Sopenharmony_ci> - Each element in the array must have the data attribute specified by **tid**. Otherwise, an exception may occur.
260e41f4b71Sopenharmony_ci>
261e41f4b71Sopenharmony_ci> - The attribute specified by **tid** in the array must be unique. Otherwise, performance loss occurs. In the above example, only **id** and **name** can be used as **tid** because they are unique fields.
262e41f4b71Sopenharmony_ci>
263e41f4b71Sopenharmony_ci> - The **tid** attribute does not support expressions.
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci![en-us_image_0000001118642001](figures/en-us_image_0000001118642001.gif)
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci## Conditional Rendering
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ciThere are two ways to implement conditional rendering: **if-elif-else** or **show**. In **if-elif-else**, when the **if** statement evaluates to **false**, the component is not built in the VDOM and is not rendered. For **show**, when show is **false**, the component is not rendered but is built in the VDOM. In addition, the **if-elif-else** statements must be used in sibling nodes. Otherwise, the compilation fails. The following example uses both ways to implement conditional rendering:
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci```html
272e41f4b71Sopenharmony_ci<!-- xxx.hml -->
273e41f4b71Sopenharmony_ci<div class="container">
274e41f4b71Sopenharmony_ci  <button class="btn" type="capsule" value="toggleShow" onclick="toggleShow"></button>
275e41f4b71Sopenharmony_ci  <button class="btn" type="capsule" value="toggleDisplay" onclick="toggleDisplay"></button>
276e41f4b71Sopenharmony_ci  <text if="{{visible}}"> Hello-world1 </text>
277e41f4b71Sopenharmony_ci  <text elif="{{display}}"> Hello-world2 </text>
278e41f4b71Sopenharmony_ci  <text else> Hello-World </text>
279e41f4b71Sopenharmony_ci</div>
280e41f4b71Sopenharmony_ci```
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci```css
283e41f4b71Sopenharmony_ci/* xxx.css */
284e41f4b71Sopenharmony_ci.container{
285e41f4b71Sopenharmony_ci  flex-direction: column;
286e41f4b71Sopenharmony_ci  align-items: center;
287e41f4b71Sopenharmony_ci}
288e41f4b71Sopenharmony_ci.btn{
289e41f4b71Sopenharmony_ci  width: 280px;
290e41f4b71Sopenharmony_ci  font-size: 26px;
291e41f4b71Sopenharmony_ci  margin: 10px 0;
292e41f4b71Sopenharmony_ci}
293e41f4b71Sopenharmony_ci```
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ci```js
296e41f4b71Sopenharmony_ci// xxx.js
297e41f4b71Sopenharmony_ciexport default {
298e41f4b71Sopenharmony_ci  data: {
299e41f4b71Sopenharmony_ci    visible: false,
300e41f4b71Sopenharmony_ci    display: true,
301e41f4b71Sopenharmony_ci  },
302e41f4b71Sopenharmony_ci  toggleShow: function() {
303e41f4b71Sopenharmony_ci    this.visible = !this.visible;
304e41f4b71Sopenharmony_ci  },
305e41f4b71Sopenharmony_ci  toggleDisplay: function() {
306e41f4b71Sopenharmony_ci    this.display = !this.display;
307e41f4b71Sopenharmony_ci  }
308e41f4b71Sopenharmony_ci}
309e41f4b71Sopenharmony_ci```
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci![en-us_image_0000001118642004](figures/en-us_image_0000001118642004.gif)
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ciIn the optimized rendering (**show**), if **show** is **true**, the node is rendered properly; if it is **false**, the display style will be **none**.
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci```html
316e41f4b71Sopenharmony_ci<!-- xxx.hml -->
317e41f4b71Sopenharmony_ci<div class="container">
318e41f4b71Sopenharmony_ci  <button class="btn" type="capsule" value="toggle" onclick="toggle"></button>
319e41f4b71Sopenharmony_ci  <text show="{{visible}}" > Hello World </text>
320e41f4b71Sopenharmony_ci</div>
321e41f4b71Sopenharmony_ci```
322e41f4b71Sopenharmony_ci
323e41f4b71Sopenharmony_ci```css
324e41f4b71Sopenharmony_ci/* xxx.css */
325e41f4b71Sopenharmony_ci.container{
326e41f4b71Sopenharmony_ci  flex-direction: column;
327e41f4b71Sopenharmony_ci  align-items: center;
328e41f4b71Sopenharmony_ci}
329e41f4b71Sopenharmony_ci.btn{
330e41f4b71Sopenharmony_ci  width: 280px;
331e41f4b71Sopenharmony_ci  font-size: 26px;
332e41f4b71Sopenharmony_ci  margin: 10px 0;
333e41f4b71Sopenharmony_ci}
334e41f4b71Sopenharmony_ci```
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ci```js
337e41f4b71Sopenharmony_ci// xxx.js
338e41f4b71Sopenharmony_ciexport default {
339e41f4b71Sopenharmony_ci  data: {
340e41f4b71Sopenharmony_ci    visible: false,
341e41f4b71Sopenharmony_ci  },
342e41f4b71Sopenharmony_ci  toggle: function() {
343e41f4b71Sopenharmony_ci    this.visible = !this.visible;
344e41f4b71Sopenharmony_ci  },
345e41f4b71Sopenharmony_ci}
346e41f4b71Sopenharmony_ci```
347e41f4b71Sopenharmony_ci
348e41f4b71Sopenharmony_ci> **NOTE**
349e41f4b71Sopenharmony_ci>
350e41f4b71Sopenharmony_ci> Do not use **for** and **if** attributes at the same time in an element.
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ci![en-us_image_0000001118642005](figures/en-us_image_0000001118642005.gif)
353e41f4b71Sopenharmony_ci
354e41f4b71Sopenharmony_ci## Logic Control Block
355e41f4b71Sopenharmony_ci
356e41f4b71Sopenharmony_ci**\<block>** makes loop rendering and conditional rendering more flexible. A **\<block>** will not be compiled as a real component. Note that the **\<block>** tag supports only the **for** and **if** attributes.
357e41f4b71Sopenharmony_ci
358e41f4b71Sopenharmony_ci```html
359e41f4b71Sopenharmony_ci<!-- xxx.hml -->
360e41f4b71Sopenharmony_ci<list>
361e41f4b71Sopenharmony_ci  <block for="glasses">
362e41f4b71Sopenharmony_ci    <list-item type="glasses">
363e41f4b71Sopenharmony_ci      <text>{{$item.name}}</text>
364e41f4b71Sopenharmony_ci    </list-item>
365e41f4b71Sopenharmony_ci    <block for="$item.kinds">
366e41f4b71Sopenharmony_ci      <list-item type="kind">
367e41f4b71Sopenharmony_ci        <text>{{$item.color}}</text>
368e41f4b71Sopenharmony_ci      </list-item>
369e41f4b71Sopenharmony_ci    </block>
370e41f4b71Sopenharmony_ci  </block>
371e41f4b71Sopenharmony_ci</list>
372e41f4b71Sopenharmony_ci```
373e41f4b71Sopenharmony_ci
374e41f4b71Sopenharmony_ci```js
375e41f4b71Sopenharmony_ci// xxx.js
376e41f4b71Sopenharmony_ciexport default {
377e41f4b71Sopenharmony_ci  data: {
378e41f4b71Sopenharmony_ci    glasses: [
379e41f4b71Sopenharmony_ci      {name:'sunglasses', kinds:[{name:'XXX',color:'XXX'},{name:'XXX',color:'XXX'}]},
380e41f4b71Sopenharmony_ci      {name:'nearsightedness mirror', kinds:[{name:'XXX',color:'XXX'}]},
381e41f4b71Sopenharmony_ci    ],
382e41f4b71Sopenharmony_ci  },
383e41f4b71Sopenharmony_ci}
384e41f4b71Sopenharmony_ci```
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci![en-us_image_0000001118642006](figures/en-us_image_0000001118642006.png)
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ci## Template Reference
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ciHML supports using **element** to reference template files. For details, see [Custom Components](../reference/apis-arkui/arkui-js/js-components-custom-basic-usage.md).
391e41f4b71Sopenharmony_ci
392e41f4b71Sopenharmony_ci```html
393e41f4b71Sopenharmony_ci<!-- template.hml -->
394e41f4b71Sopenharmony_ci<div class="item"> 
395e41f4b71Sopenharmony_ci  <text>Name: {{name}}</text>
396e41f4b71Sopenharmony_ci  <text>Age: {{age}}</text>
397e41f4b71Sopenharmony_ci</div>
398e41f4b71Sopenharmony_ci```
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci```html
401e41f4b71Sopenharmony_ci<!-- index.hml -->
402e41f4b71Sopenharmony_ci<element name='comp' src='../../common/template.hml'></element>
403e41f4b71Sopenharmony_ci<div>
404e41f4b71Sopenharmony_ci  <comp name="Tony" age="18"></comp>
405e41f4b71Sopenharmony_ci</div>
406e41f4b71Sopenharmony_ci```
407