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 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 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 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 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 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 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