未验证 提交 39dc5531 编写于 作者: O openharmony_ci 提交者: Gitee

!2743 中英文ui及英文device下vibrator开发指南提供

Merge pull request !2743 from 葛亚芳/OpenHarmony-3.1-Release
# Vibrator Development
## When to Use
You can set different vibration effects as needed, for example, customizing vibration effects with different intensities and durations for buttons on the device, and customizing one-shot or periodic vibration effects with different intensities and durations for alarm clocks and incoming calls.
## Available APIs
| Module | API | Description |
| -------- | -------- | -------- |
| ohos.vibrator | vibrate(duration: number): Promise<void> | Triggers vibration with the specified duration. This API uses a promise to return the result. |
| ohos.vibrator | vibrate(duration: number, callback?: AsyncCallback<void>): void | Triggers vibration with the specified duration. This API uses a callback to return the result. |
| ohos.vibrator | vibrate(effectId: EffectId): Promise<void> | Triggers vibration with the specified effect. This API uses a promise to return the result. |
| ohos.vibrator | vibrate(effectId: EffectId, callback?: AsyncCallback<void>): void | Triggers vibration with the specified effect. This API uses a callback to return the result. |
| ohos.vibrator | stop(stopMode: VibratorStopMode): Promise<void> | Stops vibration. This API uses a promise to return the result. |
| ohos.vibrator | stop(stopMode: VibratorStopMode, callback?: AsyncCallback<void>): void | Stops vibration. This API uses a callback to return the result. |
## How to Develop
1. Declare the permissions required for controlling vibrators on the hardware device in the **config.json** file.
```
"reqPermissions":[
{
"name":"ohos.permission.ACCELEROMETER",
"reason"":"",
"usedScene":{
"ability""[
".MainAbility"
],
"when":"inuse"
}
},
{
"name":"ohos.permission.VIBRATE",
"reason"":"",
"usedScene":{
"ability""[
".MainAbility"
],
"when":"inuse"
}
},
{
"name":"ohos.permission.ACTIVITY_MOTION",
"reason"":"",
"usedScene":{
"ability""[
".MainAbility"
],
"when":"inuse"
}
},
]
```
2. Trigger the device to vibrate.
```
import vibrator from "@ohos.vibrator"
vibrator.vibrate(duration: number).then((error)=>{
if(error){// The call fails, and error.code and error.message are printed.
console.log("Promise return failed.error.code"+error.code+"error.message"+error.message);
}else{// The call succeeded. The device starts to vibrate.
console.log("Promise returned to indicate a successful vibration.")
};
})
```
3. Stop the vibration.
```
import vibrator from "@ohos.vibrator"
vibrator.stop(stopMode: VibratorStopMode).then((error)=>{
if(error){// The call fails, and error.code and error.message are printed.
console.log("Promise return failed. error.code"+error.code+"error.message"+error.message);
}else{// The call succeeded. The device stops vibration.
Console.log("Promise returned to indicate a successful stop.");
};
})
```
# Vibrator Overview
The vibrator service opens up the latest capabilities of the vibrator hardware to the maximum extent. By expanding the native vibrator service to implement integrated vibration and interaction design, the service delivers an exquisite integrated vibration experience and differentiated experience, and improves user interaction efficiency and usability.
## Working Principles
The vibrator is a Misc device that consists of four modules: Vibrator API, Vibrator Framework, Vibrator Service, and HD_IDL.
**Figure1** Vibrator in Misc devices
![en-us_image_0000001180249428](figures/en-us_image_0000001180249428.png)
- Vibrator API: provides basic vibrator APIs, including the APIs for querying the vibrator list, querying the vibrator by effect, and triggering and stopping vibration.
- Vibrator Framework: manages the framework layer of the vibrator and communicates with the Misc Device Service.
- Vibrator Service: manages services of vibrators.
- HD_IDL: adapts to different devices.
## Constraints
When using a vibrator, you need to declare and obtain the **ohos.permission.VIBRATE** permission first so that you can control the vibration effect.
# UI # UI
- JavaScript-based Web-Like Development Paradigm - [ArkUI Overview](arkui-overview.md)
- JavaScript-based Web-like Development Paradigm
- [Overview](ui-js-overview.md) - [Overview](ui-js-overview.md)
- Framework - Framework
- [File Organization](js-framework-file.md) - [File Organization](js-framework-file.md)
...@@ -26,21 +27,22 @@ ...@@ -26,21 +27,22 @@
- [Defining Events](ui-js-building-ui-event.md) - [Defining Events](ui-js-building-ui-event.md)
- [Defining Page Routes](ui-js-building-ui-routes.md) - [Defining Page Routes](ui-js-building-ui-routes.md)
- Common Component Development Guidelines - Common Component Development Guidelines
- [Text](ui-js-components-text.md) - [<text> Development](ui-js-components-text.md)
- [Input](ui-js-components-input.md) - [<input> Development](ui-js-components-input.md)
- [Button](ui-js-components-button.md) - [<button> Development](ui-js-components-button.md)
- [List](ui-js-components-list.md) - [<list> Development](ui-js-components-list.md)
- [Picker](ui-js-components-picker.md) - [<picker> Development](ui-js-components-picker.md)
- [Dialog](ui-js-components-dialog.md) - [<dialog> Development](ui-js-components-dialog.md)
- [Form](ui-js-components-form.md) - [<form> Development](ui-js-components-form.md)
- [Stepper](ui-js-components-stepper.md) - [<stepper> Development](ui-js-components-stepper.md)
- [Tabs](ui-js-component-tabs.md) - [<tabs> Development](ui-js-component-tabs.md)
- [Image](ui-js-components-images.md) - [<image> Development](ui-js-components-images.md)
- Animation Development Guidelines - Animation Development Guidelines
- CSS Animation - CSS Animation
- [Defining Attribute Style Animations](ui-js-animate-attribute-style.md) - [Defining Attribute Style Animations](ui-js-animate-attribute-style.md)
- [Defining Animations with the transform Attribute](ui-js-animate-transform.md) - [Defining Animations with the transform Attribute](ui-js-animate-transform.md)
- [Defining Animations with the background-position Attribute](ui-js-animate-background-position-style.md) - [Defining Animations with the background-position Attribute](ui-js-animate-background-position-style.md)
- [Defining Animations for SVG Components](ui-js-animate-svg.md)
- JS Animation - JS Animation
- [Component Animation](ui-js-animate-component.md) - [Component Animation](ui-js-animate-component.md)
- Interpolator Animation - Interpolator Animation
...@@ -65,9 +67,9 @@ ...@@ -65,9 +67,9 @@
- General UI Description Specifications - General UI Description Specifications
- [Basic Concepts](ts-general-ui-concepts.md) - [Basic Concepts](ts-general-ui-concepts.md)
- Declarative UI Description Specifications - Declarative UI Description Specifications
- [Parameterless Configuration](ts-parameterless-configuration.md) - [Configuration Without Parameters](ts-parameterless-configuration.md)
- [Configuration with Mandatory Parameters](ts-configuration-with-mandatory-parameters.md) - [Configuration with Mandatory Parameters](ts-configuration-with-mandatory-parameters.md)
- [Attribution Configuration](ts-attribution-configuration.md) - [Attribute Configuration](ts-attribution-configuration.md)
- [Event Configuration](ts-event-configuration.md) - [Event Configuration](ts-event-configuration.md)
- [Child Component Configuration](ts-child-component-configuration.md) - [Child Component Configuration](ts-child-component-configuration.md)
- Componentization - Componentization
...@@ -77,6 +79,7 @@ ...@@ -77,6 +79,7 @@
- [@Builder](ts-component-based-builder.md) - [@Builder](ts-component-based-builder.md)
- [@Extend](ts-component-based-extend.md) - [@Extend](ts-component-based-extend.md)
- [@CustomDialog](ts-component-based-customdialog.md) - [@CustomDialog](ts-component-based-customdialog.md)
- [@Styles](ts-component-based-styles.md)
- About UI State Management - About UI State Management
- [Basic Concepts](ts-ui-state-mgmt-concepts.md) - [Basic Concepts](ts-ui-state-mgmt-concepts.md)
- Managing Component States - Managing Component States
...@@ -88,7 +91,7 @@ ...@@ -88,7 +91,7 @@
- [PersistentStorage](ts-application-states-apis-persistentstorage.md) - [PersistentStorage](ts-application-states-apis-persistentstorage.md)
- [Environment](ts-application-states-apis-environment.md) - [Environment](ts-application-states-apis-environment.md)
- Managing Other States - Managing Other States
- [@observed and @objectLink](ts-other-states-observed-objectlink.md) - [@Observed and @ObjectLink](ts-other-states-observed-objectlink.md)
- [@Consume and @Provide](ts-other-states-consume-provide.md) - [@Consume and @Provide](ts-other-states-consume-provide.md)
- [@Watch](ts-other-states-watch.md) - [@Watch](ts-other-states-watch.md)
- About Rendering Control Syntax - About Rendering Control Syntax
...@@ -97,10 +100,12 @@ ...@@ -97,10 +100,12 @@
- [LazyForEach](ts-rending-control-syntax-lazyforeach.md) - [LazyForEach](ts-rending-control-syntax-lazyforeach.md)
- About @Component - About @Component
- [build Function](ts-function-build.md) - [build Function](ts-function-build.md)
- [Custom Component Initialization](ts-custom-component-initialization.md) - [Initialization of Custom Components' Member Variables](ts-custom-component-initialization.md)
- [Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md) - [Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md)
- [Example: Component Creation and Re-Initialization](ts-component-creation-re-initialization.md) - [Component Creation and Re-initialization](ts-component-creation-re-initialization.md)
- [Syntactic Sugar](ts-syntactic-sugar.md) - [About Syntactic Sugar](ts-syntactic-sugar.md)
- Common Component Development Guidelines
- [<web> Development](ui-ts-components-web.md)
- Experiencing the Declarative UI - Experiencing the Declarative UI
- [Creating a Declarative UI Project](ui-ts-creating-project.md) - [Creating a Declarative UI Project](ui-ts-creating-project.md)
- [Getting to Know Components](ui-ts-components.md) - [Getting to Know Components](ui-ts-components.md)
...@@ -110,4 +115,3 @@ ...@@ -110,4 +115,3 @@
- [Building a Food Category List Layout](ui-ts-building-category-list-layout.md) - [Building a Food Category List Layout](ui-ts-building-category-list-layout.md)
- [Building a Food Category Grid Layout](ui-ts-building-category-grid-layout.md) - [Building a Food Category Grid Layout](ui-ts-building-category-grid-layout.md)
- [Implementing Page Redirection and Data Transmission](ui-ts-page-redirection-data-transmission.md) - [Implementing Page Redirection and Data Transmission](ui-ts-page-redirection-data-transmission.md)
# ArkUI Overview
## Introduction
ArkUI is a UI development framework that provides what you'll need to develop application UIs.
## Basic Concepts
- Component: the smallest unit for UI building and display. You build a UI that meets your needs through flexible combinations of components.
- Page: the smallest unit for ArkUI application scheduling. You can design multiple pages for your application, manage their files on a per-page basis, and schedule page redirection through routing APIs, so as to implement decoupling of application functions.
## Key Capabilities
- Diverse components: In addition to a wide range of basic components, such as components for text display, image display, and keypress interaction, ArkUI provides media components that support video playback. Better yet, it also provides polymorphic components, which can adapt to styles of different devices.
- Flexible layouts: Creating a responsive UI in ArkUI is easy, with our carefully-designed layout approaches: Besides the classic flexible layout capability, you also have access to the list, grid, and atomic layouts that auto-adapt to screen resolutions.
- Animation: Apart from animations embedded in components, ArkUI offers additional animation features: attribute animation, transition animation, and custom animation.
- UI interaction: ArkUI allows users to interact with your application UI properly, regardless of the system platform and input device. By default, the UI accepts input from touch gestures, remote controls, and mouse devices, with support for the event notification capability.
- Drawing: ArkUI offers advanced drawing capabilities that allow you to draw custom shapes with a range of editors, from images to fill colors and texts.
- Platform API channel: ArkUI provides an API extension mechanism through which platform capabilities are encapsulated to produce JavaScript APIs in a unified style.
## Development Paradigms
ArkUI comes with two development paradigms: JavaScript-based web-like development paradigm (web-like development paradigm for short) and TypeScript-based declarative development paradigm (declarative development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
### Web-like Development Paradigm
The web-like development paradigm uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically updates with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications. It could be helpful if you are developing small- and medium-sized applications with simple UIs.
### Declarative Development Paradigm
The declarative development paradigm uses the TypeScript programming language and extends the declarative UI syntax, providing UI drawing capabilities from three dimensions: component, animation, and state management. The programming mode used is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development. With type annotations in TypeScript, you can enforce type checking at compile time. If you are developing large applications, the declarative development paradigm is more applicable.
### Web-like Development Paradigm vs. Declarative Development Paradigm
| Development Paradigm | Language | UI Update Mode | Applicable To | Intended Audience |
| -------- | -------- | -------- | -------- | -------- |
| Web-like development paradigm | JavaScript | Data-driven | Applets and service widgets with simple UIs | Frontend web developers |
| Declarative development paradigm | Extended TypeScript (eTS) | Data-driven | Applications involving technological sophistication and teamwork | Mobile application and system application developers |
### Framework Structure
![en-us_image_0000001267647869](figures/en-us_image_0000001267647869.png)
As shown above, the two development paradigms share the UI backend engine and language runtime. The UI backend engine implements the six basic capabilities of the ArkUI framework. The declarative development paradigm does not require the JS Framework for managing the page DOM. As such, it has more streamlined rendering and update links and less memory usage. This makes the declarative development paradigm a better choice for building application UIs.
# File Organization<a name="EN-US_TOPIC_0000001127125012"></a> # File Organization
## Directory Structure<a name="section119431650182015"></a> ## Directory Structure
The following figure shows the typical directory structure of the JavaScript module \(**entry/src/main/js/module**\) for an application with feature abilities \(FA\) using JavaScript APIs. The following figure shows the typical directory structure of the JavaScript module \(entry/src/main/js/module\) for an application with feature abilities \(FA\) using JavaScript APIs.
**Figure 1** Directory structure<a name="fig72881050193012"></a>
**Figure1** Directory structure
![](figures/unnaming-(1).png) ![](figures/unnaming-(1).png)
**Figure 2** Directory structure for resource sharing <sup>5+</sup><a name="fig103221917162010"></a> **Figure2** Directory structure for resource sharing <sup>5+</sup>
![](figures/directory-structure-for-resource-sharing-5+.png "directory-structure-for-resource-sharing-5+") ![](figures/directory-structure-for-resource-sharing-5+.png "directory-structure-for-resource-sharing-5+")
Functions of the files are as follows: Functions of the files are as follows:
- **.hml** files describe the page layout. - .hml files describe the page layout.
- **.css** files describe the page style. - .css files describe the page style.
- **.js** files process the interactions between pages and users. - .js files process the interactions between pages and users.
Functions of the folders are as follows: Functions of the folders are as follows:
- The **app.js** file manages global JavaScript logics and application lifecycle. For details, see [app.js](js-framework-js-file.md). - The app.js file manages global JavaScript logics and application lifecycle. For details, see [app.js](js-framework-js-file.md).
- The **pages** directory stores all component pages. - The pages directory stores all component pages.
- The **common** directory stores public resource files, such as media resources, custom components, and **.js** files. - The common directory stores public resource files, such as media resources, custom components, and .js files.
- The **resources** directory stores resource configuration files, for example, for multi-resolution loading. For details, see [Resource Limitations and Access](js-framework-resource-restriction.md). - The resources directory stores resource configuration files, for example, for multi-resolution loading. For details, see [Resource Limitations and Access](js-framework-resource-restriction.md).
- The **share** directory<sup>5+</sup> is used to configure resources shared by multiple instances. For example, images and JSON files in this directory can be shared by **default1** and **default2** instances. - The share directory<sup>5+</sup> is used to configure resources shared by multiple instances. For example, images and JSON files in this directory can be shared by default1 and default2 instances.
>![](../public_sys-resources/icon-note.gif) **NOTE:** >![](public_sys-resources/icon-note.gif) **NOTE**:
>- Reserved folders \(**i18n** and **resources**\) cannot be renamed. >- Reserved folders \(i18n and resources\) cannot be renamed.
>- If the same resource name and directory are used under the **share** directory and the instance \(**default**\) directory, the resource in the instance directory will be used when you reference the directory. >- If the same resource name and directory are used under the share directory and the instance \(default\) directory, the resource in the instance directory will be used when you reference the directory.
>- The **share** directory does not support **i18n**. >- The share directory does not support i18n.
>- You should create the optional folders \(shown in the directory structure\) as needed after you create the project in DevEco Studio. >- You should create the optional folders \(shown in the directory structure\) as needed after you create the project in DevEco Studio.
## File Access Rules<a name="section6620355202117"></a> ## File Access Rules
Application resources can be accessed via an absolute or relative path. In the JS UI framework, an absolute path starts with a slash \(/\), and a relative path starts with **./** or **../**. The rules are as follows: Application resources can be accessed via an absolute or relative path. In the JS UI framework, an absolute path starts with a slash \(/\), and a relative path starts with ./ or ../. The rules are as follows:
- To reference a code file, use a relative path, for example, **../common/utils.js**. - To reference a code file, use a relative path, for example, ../common/utils.js.
- To reference a resource file, use an absolute path, for example, **/common/xxx.png**. - To reference a resource file, use an absolute path, for example, /common/xxx.png.
- Store code files and resource files in the **common** directory and access the files in a required fashion. - Store code files and resource files in the common directory and access the files in a required fashion.
- In a **.css** file, use the **url\(\)** function to create a URL, for example, **url\(/common/xxx.png\)**. - In a .css file, use the url\(\) function to create a URL, for example, url\(/common/xxx.png\).
>![](../public_sys-resources/icon-note.gif) **NOTE:** >![](public_sys-resources/icon-note.gif) **NOTE**:
>When code file A needs to reference code file B: >When code file A needs to reference code file B:
>
>- If code files A and B are in the same directory, you can use either a relative or absolute path in code file B to reference resource files. >- If code files A and B are in the same directory, you can use either a relative or absolute path in code file B to reference resource files.
>- If code files A and B are in different directories, you must use an absolute path in code file B to reference resource files because the directory of code file B changes during Webpack packaging. >- If code files A and B are in different directories, you must use an absolute path in code file B to reference resource files because the directory of code file B changes during Webpack packaging.
>- Use an absolute path if you want to dynamically change the resource file path through data binding in a **.js** file. >- Use an absolute path if you want to dynamically change the resource file path through data binding in a .js file.
## Media File Formats<a name="section79731562617"></a> ## Media File Formats
**Table 1** Supported image formats Table1 Supported image formats
<a name="table59058237819"></a> | Image Format | File Format |
<table><thead align="left"><tr id="row890542312811"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1290662316815"><a name="p1290662316815"></a><a name="p1290662316815"></a>Image Format</p> | ------------ | ----------- |
</th> | BMP | .bmp |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p12906623088"><a name="p12906623088"></a><a name="p12906623088"></a>File Format</p> | GIF | .gif |
</th> | JPEG | .jpg |
</tr> | PNG | .png |
</thead> | WebP | .webp |
<tbody><tr id="row49065231788"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p10906112316811"><a name="p10906112316811"></a><a name="p10906112316811"></a>BMP</p>
</td> Table2 Supported video formats
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p590619232813"><a name="p590619232813"></a><a name="p590619232813"></a>.bmp</p>
</td> | Video Formats | File Format |
</tr> | ------------------------------- | ----------- |
<tr id="row1690615234816"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p6906122313816"><a name="p6906122313816"></a><a name="p6906122313816"></a>GIF</p> | H.264 AVC Baseline Profile (BP) | .3gp .mp4 |
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p290662317818"><a name="p290662317818"></a><a name="p290662317818"></a>.gif</p>
</td>
</tr>
<tr id="row5906823580"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p109061423685"><a name="p109061423685"></a><a name="p109061423685"></a>JPEG</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p109061723488"><a name="p109061723488"></a><a name="p109061723488"></a>.jpg</p>
</td>
</tr>
<tr id="row310155772112"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p17101195717217"><a name="p17101195717217"></a><a name="p17101195717217"></a>PNG</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p161021157162120"><a name="p161021157162120"></a><a name="p161021157162120"></a>.png</p>
</td>
</tr>
<tr id="row942813247228"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p6428152432218"><a name="p6428152432218"></a><a name="p6428152432218"></a>WebP</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p04281246226"><a name="p04281246226"></a><a name="p04281246226"></a>.webp</p>
</td>
</tr>
</tbody>
</table>
**Table 2** Supported video formats
<a name="table31310367289"></a>
<table><thead align="left"><tr id="row713736152813"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p11383616283"><a name="p11383616283"></a><a name="p11383616283"></a>Video Formats</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p91353619287"><a name="p91353619287"></a><a name="p91353619287"></a>File Formats</p>
</th>
</tr>
</thead>
<tbody><tr id="row1613136102817"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1713736192820"><a name="p1713736192820"></a><a name="p1713736192820"></a>H.264 AVC</p>
<p id="p181343620281"><a name="p181343620281"></a><a name="p181343620281"></a>Baseline Profile (BP)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1014136162818"><a name="p1014136162818"></a><a name="p1014136162818"></a>.3gp</p>
<p id="p121418360288"><a name="p121418360288"></a><a name="p121418360288"></a>.mp4</p>
</td>
</tr>
</tbody>
</table>
# app.js<a name="EN-US_TOPIC_0000001173164711"></a> # app.js
## Application Lifecycle<a name="section597315421776"></a>
You can customize the [lifecycle](js-framework-lifecycle.md) implementation logic on an application-by-application basis in **app.js**. The following example only prints the corresponding logs in the **lifecycle** function: ## Application Lifecycle
You can customize the [lifecycle](js-framework-lifecycle.md) implementation logic on an application-by-application basis in app.js. The following example only prints the corresponding logs in the lifecycle function:
``` ```
// app.js // app.js
...@@ -17,29 +18,15 @@ export default { ...@@ -17,29 +18,15 @@ export default {
} }
``` ```
## Application Object<sup>6+</sup><a name="section61671730771"></a> ## Application Object<sup>6+</sup>
<a name="table2114112717810"></a> | Attribute | Data Type | Description |
<table><thead align="left"><tr id="r03f71ea1fd1245fd80e907a22a315e99"><th class="cellrowborder" valign="top" width="8.63%" id="mcps1.1.4.1.1"><p id="ae816119c3e0143c892512012c7927037"><a name="ae816119c3e0143c892512012c7927037"></a><a name="ae816119c3e0143c892512012c7927037"></a>Attribute</p> | -------- | -------- | -------- |
</th> | getApp | Function | Obtains the object exposed in the app.js file from the custom .js file. |
<th class="cellrowborder" valign="top" width="9.370000000000001%" id="mcps1.1.4.1.2"><p id="ab72e901bb3ef4657b303513b8fa5ec1f"><a name="ab72e901bb3ef4657b303513b8fa5ec1f"></a><a name="ab72e901bb3ef4657b303513b8fa5ec1f"></a>Data Type</p>
</th>
<th class="cellrowborder" valign="top" width="82%" id="mcps1.1.4.1.3"><p id="ae95f3df496fc41939ac6c1cf74aef9d8"><a name="ae95f3df496fc41939ac6c1cf74aef9d8"></a><a name="ae95f3df496fc41939ac6c1cf74aef9d8"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row16114627482"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p1311416272810"><a name="p1311416272810"></a><a name="p1311416272810"></a>getApp</p>
</td>
<td class="cellrowborder" valign="top" width="9.370000000000001%" headers="mcps1.1.4.1.2 "><p id="p171148271181"><a name="p171148271181"></a><a name="p171148271181"></a>Function</p>
</td>
<td class="cellrowborder" valign="top" width="82%" headers="mcps1.1.4.1.3 "><p id="p1111420275815"><a name="p1111420275815"></a><a name="p1111420275815"></a>Obtains the object exposed in the <strong id="b18467112117297"><a name="b18467112117297"></a><a name="b18467112117297"></a>app.js</strong> file from the custom <strong id="b2399945121212"><a name="b2399945121212"></a><a name="b2399945121212"></a>.js</strong> file.</p>
</td>
</tr>
</tbody>
</table>
The following is a sample code snippet: The following is a sample code snippet:
``` ```
// app.js // app.js
export default { export default {
...@@ -47,16 +34,16 @@ export default { ...@@ -47,16 +34,16 @@ export default {
test: "by getAPP" test: "by getAPP"
}, },
onCreate() { onCreate() {
console.info('Application onCreate'); console.info('AceApplication onCreate');
}, },
onDestroy() { onDestroy() {
console.info('Application onDestroy'); console.info('AceApplication onDestroy');
}, },
}; };
``` ```
``` ```
// test.js Customize the logic code. // test.js Customize the logic code.
export var appData = getApp().data; export var appData = getApp().data;
``` ```
# "js" Tag<a name="EN-US_TOPIC_0000001173324643"></a> # "js" Tag
The "js" tag contains the instance name, window style, and page route information. The "js" tag contains the instance name, window style, and page route information.
<a name="t092f7d78cacb46d583b3499e7cf3e7f2"></a>
<table><thead align="left"><tr id="r8ff2bb3ff6c84115be187bad81bb8dce"><th class="cellrowborder" valign="top" width="25%" id="mcps1.1.6.1.1"><p id="a16a1bbba39d7414b8e77ae9bcf230b7b"><a name="a16a1bbba39d7414b8e77ae9bcf230b7b"></a><a name="a16a1bbba39d7414b8e77ae9bcf230b7b"></a>Tag</p> | Tag | Data Type | Default Value | Mandatory | Description |
</th> | -------- | -------- | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="12%" id="mcps1.1.6.1.2"><p id="a1fdbf4e9a38840029b6eb94a7f89b29a"><a name="a1fdbf4e9a38840029b6eb94a7f89b29a"></a><a name="a1fdbf4e9a38840029b6eb94a7f89b29a"></a>Data Type</p> | name | string | default | Yes | Name of the JavaScript instance. |
</th> | pages | Array | - | Yes | Route information. For details, see ["pages"](#pages). |
<th class="cellrowborder" valign="top" width="12%" id="mcps1.1.6.1.3"><p id="a07bcb8a8bbea4e8d9c60b8a4b1031970"><a name="a07bcb8a8bbea4e8d9c60b8a4b1031970"></a><a name="a07bcb8a8bbea4e8d9c60b8a4b1031970"></a>Default Value</p> | window | Object | - | No | Window information. For details, see ["window"](#window). |
</th>
<th class="cellrowborder" valign="top" width="9%" id="mcps1.1.6.1.4"><p id="a39b2ea2535e04e37a418e8374f3271e4"><a name="a39b2ea2535e04e37a418e8374f3271e4"></a><a name="a39b2ea2535e04e37a418e8374f3271e4"></a>Mandatory</p>
</th> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
<th class="cellrowborder" valign="top" width="42%" id="mcps1.1.6.1.5"><p id="ae9e9127cfa374d18a3741f4247791acf"><a name="ae9e9127cfa374d18a3741f4247791acf"></a><a name="ae9e9127cfa374d18a3741f4247791acf"></a>Description</p> > The "name", "window", and "pages" tags are configured in the "js" tag of the config.json file.
</th>
</tr>
</thead> ## "pages"
<tbody><tr id="row19493102613510"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.6.1.1 "><p id="p6494172618357"><a name="p6494172618357"></a><a name="p6494172618357"></a>name</p>
</td> The "pages" defines the route information of each page. Each page consists of the page path and page name. The following is an example:
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.2 "><p id="p1449472643513"><a name="p1449472643513"></a><a name="p1449472643513"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.3 "><p id="p1749412619355"><a name="p1749412619355"></a><a name="p1749412619355"></a>default</p>
</td>
<td class="cellrowborder" valign="top" width="9%" headers="mcps1.1.6.1.4 "><p id="p64947262359"><a name="p64947262359"></a><a name="p64947262359"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="42%" headers="mcps1.1.6.1.5 "><p id="p8494122612352"><a name="p8494122612352"></a><a name="p8494122612352"></a>Name of the JavaScript instance.</p>
</td>
</tr>
<tr id="r3d05cd5e24f14308a71d21d2d01adb81"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.6.1.1 "><p id="a5a33cd31feb7416ab1ee44a6b863e57d"><a name="a5a33cd31feb7416ab1ee44a6b863e57d"></a><a name="a5a33cd31feb7416ab1ee44a6b863e57d"></a>pages</p>
</td>
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.2 "><p id="a90233739ef8a4977ba0a9a48282d324d"><a name="a90233739ef8a4977ba0a9a48282d324d"></a><a name="a90233739ef8a4977ba0a9a48282d324d"></a>Array</p>
</td>
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.3 "><p id="aaa1317b02aef4aee98e42227902ac7e5"><a name="aaa1317b02aef4aee98e42227902ac7e5"></a><a name="aaa1317b02aef4aee98e42227902ac7e5"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="9%" headers="mcps1.1.6.1.4 "><p id="a225959a4c42f44f4ad25fac5f48f34f5"><a name="a225959a4c42f44f4ad25fac5f48f34f5"></a><a name="a225959a4c42f44f4ad25fac5f48f34f5"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="42%" headers="mcps1.1.6.1.5 "><p id="a5f03a4f4a1fd461b9e4bc025569fcb2d"><a name="a5f03a4f4a1fd461b9e4bc025569fcb2d"></a><a name="a5f03a4f4a1fd461b9e4bc025569fcb2d"></a>Route information. For details, see <a href="#section3239252133513">"pages"</a>.</p>
</td>
</tr>
<tr id="row12517192619239"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.6.1.1 "><p id="p18517172622317"><a name="p18517172622317"></a><a name="p18517172622317"></a>window</p>
</td>
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.2 "><p id="p15517626112313"><a name="p15517626112313"></a><a name="p15517626112313"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="12%" headers="mcps1.1.6.1.3 "><p id="p3517112615234"><a name="p3517112615234"></a><a name="p3517112615234"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="9%" headers="mcps1.1.6.1.4 "><p id="p1451782692314"><a name="p1451782692314"></a><a name="p1451782692314"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="42%" headers="mcps1.1.6.1.5 "><p id="p1517326152317"><a name="p1517326152317"></a><a name="p1517326152317"></a>Window information. For details, see <a href="#section728811177376">"window"</a>.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The **"name"**, "window", and **"pages"** tags are configured in the **"js"** tag of the config.json file.
## "pages"<a name="section3239252133513"></a>
The **"pages"** defines the route information of each page. Each page consists of the page path and page name. The following is an example:
``` ```
{ {
...@@ -69,59 +31,31 @@ The **"pages"** defines the route information of each page. Each page consists ...@@ -69,59 +31,31 @@ The **"pages"** defines the route information of each page. Each page consists
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- The first page in the **pages** list is the home page, also referred to as the entry, of the application. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- The page name should not be a component name, for example, **text.hml** or **button.hml**. >
> - The first page in the pages list is the home page, also referred to as the entry, of the application.
## window<a name="section728811177376"></a> >
>
The **"window"** defines window-related configurations. To solve the screen adaptation problem, you can use either of the following methods: > - The page name should not be a component name, for example, text.hml or button.hml.
- Specify **designWidth**, which is the logical screen width. All size styles, such as **width** and **font-size**, are scaled at the ratio of **designWidth** to the physical screen width. For example, when **designWidth** is 720 px and if you set **width** to 100 px, the actual display width is scaled to 200 physical px on the screen whose physical width is 1440 px. ## window
- Set **autoDesignWidth** to **true**, the **designWidth** field will be ignored, and the component and layout will be scaled automatically based on the screen density. The logical screen width is automatically calculated based on the physical screen width and screen density. The logical screen width may vary depending on the device. Use the relative layout to adapt to different devices. For example, on a device with a resolution of 466x466 and 320 DPI \(a screen density of 2x, with 160 DPI as the base\), 1 px is equivalent to 2 physical px.
The "window" defines window-related configurations. To solve the screen adaptation problem, you can use either of the following methods:
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>1. The default **<length\>** value in the current style is calculated based on the screen density. For example, if the screen density is x2 \(with 160 DPI as the baseline\) and the default **<length\>** value is 1 px, the actual length rendered on the device is 2 physical px. - Specify designWidth, which is the logical screen width. All size styles, such as width and font-size, are scaled at the ratio of designWidth to the physical screen width. For example, when designWidth is 720 px and if you set width to 100 px, the actual display width is scaled to 200 physical px on the screen whose physical width is 1440 px.
>2. Values of **autoDesignWidth** and **designWidth** do not affect how the default **<length\>** value is calculated and the final effect.
- Set autoDesignWidth to true, the designWidth field will be ignored, and the component and layout will be scaled automatically based on the screen density. The logical screen width is automatically calculated based on the physical screen width and screen density. The logical screen width may vary depending on the device. Use the relative layout to adapt to different devices. For example, on a device with a resolution of 466x466 and 320 DPI (a screen density of 2x, with 160 DPI as the base), 1 px is equivalent to 2 physical px.
<a name="table4231104116370"></a> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
<table><thead align="left"><tr id="row17231541183714"><th class="cellrowborder" valign="top" width="16.28837116288371%" id="mcps1.1.6.1.1"><p id="p1723112411376"><a name="p1723112411376"></a><a name="p1723112411376"></a>Attribute</p> > 1. The default &lt;length&gt; value in the current style is calculated based on the screen density. For example, if the screen density is x2 (with 160 DPI as the baseline) and the default &lt;length&gt; value is 1 px, the actual length rendered on the device is 2 physical px.
</th> >
<th class="cellrowborder" valign="top" width="11.678832116788321%" id="mcps1.1.6.1.2"><p id="p12313414371"><a name="p12313414371"></a><a name="p12313414371"></a>Type</p> > 2. Values of autoDesignWidth and designWidth do not affect how the default &lt;length&gt; value is calculated and the final effect.
</th> | Attribute | Type | Mandatory | Default Value | Description |
<th class="cellrowborder" valign="top" width="10.63893610638936%" id="mcps1.1.6.1.3"><p id="p1323118413374"><a name="p1323118413374"></a><a name="p1323118413374"></a>Mandatory</p> | -------- | -------- | -------- | -------- | -------- |
</th> | | | | | |
<th class="cellrowborder" valign="top" width="6.969303069693031%" id="mcps1.1.6.1.4"><p id="p2423537113218"><a name="p2423537113218"></a><a name="p2423537113218"></a>Default Value</p> | designWidth | number | No | 720<br/> | Logical screen width, which is a reference value for page design. The actual display width is scaled at the ratio of the value to the device width. |
</th> | autoDesignWidth | boolean | No | false | Whether to automatically calculate the baseline width. If autoDesignWidth is set to true, designWidth is ignored. The baseline width is calculated based on the physical screen width and screen density. |
<th class="cellrowborder" valign="top" width="54.42455754424558%" id="mcps1.1.6.1.5"><p id="p17231124163710"><a name="p17231124163710"></a><a name="p17231124163710"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1423174133715"><td class="cellrowborder" valign="top" width="16.28837116288371%" headers="mcps1.1.6.1.1 "><p id="p1923284111373"><a name="p1923284111373"></a><a name="p1923284111373"></a>designWidth</p>
</td>
<td class="cellrowborder" valign="top" width="11.678832116788321%" headers="mcps1.1.6.1.2 "><p id="p1023219418372"><a name="p1023219418372"></a><a name="p1023219418372"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="10.63893610638936%" headers="mcps1.1.6.1.3 "><p id="p023217410379"><a name="p023217410379"></a><a name="p023217410379"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="6.969303069693031%" headers="mcps1.1.6.1.4 "><p id="p15424137103212"><a name="p15424137103212"></a><a name="p15424137103212"></a>720</p>
</td>
<td class="cellrowborder" valign="top" width="54.42455754424558%" headers="mcps1.1.6.1.5 "><p id="p1232174173717"><a name="p1232174173717"></a><a name="p1232174173717"></a>Logical screen width, which is a reference value for page design. The actual display width is scaled at the ratio of the value to the device width.</p>
</td>
</tr>
<tr id="row78924466220"><td class="cellrowborder" valign="top" width="16.28837116288371%" headers="mcps1.1.6.1.1 "><p id="p1289216461925"><a name="p1289216461925"></a><a name="p1289216461925"></a>autoDesignWidth</p>
</td>
<td class="cellrowborder" valign="top" width="11.678832116788321%" headers="mcps1.1.6.1.2 "><p id="p1489220466214"><a name="p1489220466214"></a><a name="p1489220466214"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="10.63893610638936%" headers="mcps1.1.6.1.3 "><p id="p10892184612218"><a name="p10892184612218"></a><a name="p10892184612218"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="6.969303069693031%" headers="mcps1.1.6.1.4 "><p id="p10424237183218"><a name="p10424237183218"></a><a name="p10424237183218"></a>false</p>
</td>
<td class="cellrowborder" valign="top" width="54.42455754424558%" headers="mcps1.1.6.1.5 "><p id="p198921746524"><a name="p198921746524"></a><a name="p198921746524"></a>Whether to automatically calculate the baseline width. If <strong id="b14176155215510"><a name="b14176155215510"></a><a name="b14176155215510"></a>autoDesignWidth</strong> is set to <strong id="b68529554517"><a name="b68529554517"></a><a name="b68529554517"></a>true</strong>, <strong id="b1690031366"><a name="b1690031366"></a><a name="b1690031366"></a>designWidth</strong> is ignored. The baseline width is calculated based on the physical screen width and screen density.</p>
</td>
</tr>
</tbody>
</table>
The following is a sample code snippet: The following is a sample code snippet:
...@@ -136,7 +70,9 @@ The following is a sample code snippet: ...@@ -136,7 +70,9 @@ The following is a sample code snippet:
} }
``` ```
## Example<a name="section19421142983812"></a>
## Example
``` ```
{ {
...@@ -156,11 +92,7 @@ The following is a sample code snippet: ...@@ -156,11 +92,7 @@ The following is a sample code snippet:
"pages": [ "pages": [
"pages/index/index", "pages/index/index",
"pages/detail/detail" "pages/detail/detail"
], ], "window": { "designWidth": 720, "autoDesignWidth": false }
"window": {
"designWidth": 720,
"autoDesignWidth": false
}
} }
], ],
"abilities": [ "abilities": [
...@@ -171,4 +103,3 @@ The following is a sample code snippet: ...@@ -171,4 +103,3 @@ The following is a sample code snippet:
} }
} }
``` ```
# Lifecycle<a name="EN-US_TOPIC_0000001173164671"></a> # Lifecycle
## Application Lifecycle<a name="section9779102014714"></a>
You can define the following application lifecycle functions in the **app.js** file. ## Application Lifecycle
<a name="table8760251124713"></a> You can define the following application lifecycle functions in the app.js file.
<table><thead align="left"><tr id="row147612518471"><th class="cellrowborder" valign="top" width="21.052105210521052%" id="mcps1.1.5.1.1"><p id="p8761165113471"><a name="p8761165113471"></a><a name="p8761165113471"></a>Attribute</p>
</th>
<th class="cellrowborder" valign="top" width="18.421842184218423%" id="mcps1.1.5.1.2"><p id="p157613518475"><a name="p157613518475"></a><a name="p157613518475"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="21.052105210521052%" id="mcps1.1.5.1.3"><p id="p19761051154711"><a name="p19761051154711"></a><a name="p19761051154711"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="39.473947394739476%" id="mcps1.1.5.1.4"><p id="p1976105174713"><a name="p1976105174713"></a><a name="p1976105174713"></a>Called When</p>
</th>
</tr>
</thead>
<tbody><tr id="row12761165124716"><td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.1 "><p id="p15761105113478"><a name="p15761105113478"></a><a name="p15761105113478"></a>onCreate</p>
</td>
<td class="cellrowborder" valign="top" width="18.421842184218423%" headers="mcps1.1.5.1.2 "><p id="p1476285124715"><a name="p1476285124715"></a><a name="p1476285124715"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.3 "><p id="p7762165124714"><a name="p7762165124714"></a><a name="p7762165124714"></a>Listens for application creation.</p>
</td>
<td class="cellrowborder" valign="top" width="39.473947394739476%" headers="mcps1.1.5.1.4 "><p id="p47628519476"><a name="p47628519476"></a><a name="p47628519476"></a>The application is created.</p>
</td>
</tr>
<tr id="row846314312512"><td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.1 "><p id="p246417315512"><a name="p246417315512"></a><a name="p246417315512"></a>onShow<sup id="sup9720688529"><a name="sup9720688529"></a><a name="sup9720688529"></a>6+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="18.421842184218423%" headers="mcps1.1.5.1.2 "><p id="p19386104510"><a name="p19386104510"></a><a name="p19386104510"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.3 "><p id="p1546413125110"><a name="p1546413125110"></a><a name="p1546413125110"></a>Listens for whether the application is running in the foreground.</p>
</td>
<td class="cellrowborder" valign="top" width="39.473947394739476%" headers="mcps1.1.5.1.4 "><p id="p84646335116"><a name="p84646335116"></a><a name="p84646335116"></a>The application is running in the foreground.</p>
</td>
</tr>
<tr id="row2035233945117"><td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.1 "><p id="p73531398511"><a name="p73531398511"></a><a name="p73531398511"></a>onHide<sup id="sup78997116520"><a name="sup78997116520"></a><a name="sup78997116520"></a>6+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="18.421842184218423%" headers="mcps1.1.5.1.2 "><p id="p28393441516"><a name="p28393441516"></a><a name="p28393441516"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.3 "><p id="p43531839145118"><a name="p43531839145118"></a><a name="p43531839145118"></a>Listens for whether the application is running in the background.</p>
</td>
<td class="cellrowborder" valign="top" width="39.473947394739476%" headers="mcps1.1.5.1.4 "><p id="p2041805635112"><a name="p2041805635112"></a><a name="p2041805635112"></a>The application is running in the background.</p>
</td>
</tr>
<tr id="row7762751174719"><td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.1 "><p id="p176215118478"><a name="p176215118478"></a><a name="p176215118478"></a>onDestroy</p>
</td>
<td class="cellrowborder" valign="top" width="18.421842184218423%" headers="mcps1.1.5.1.2 "><p id="p1576295114474"><a name="p1576295114474"></a><a name="p1576295114474"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="21.052105210521052%" headers="mcps1.1.5.1.3 "><p id="p37621351104718"><a name="p37621351104718"></a><a name="p37621351104718"></a>Listens for application uninstallation.</p>
</td>
<td class="cellrowborder" valign="top" width="39.473947394739476%" headers="mcps1.1.5.1.4 "><p id="p976265111475"><a name="p976265111475"></a><a name="p976265111475"></a>The application exits.</p>
</td>
</tr>
</tbody>
</table>
## Page Lifecycle<a name="section921934910481"></a> | Attribute | Type | Description | Called When |
| -------- | -------- | -------- | -------- |
| onCreate | () => void | Listens for application creation. | The application is created. |
| onShow<sup>6+</sup> | () => void | Listens for whether the application is running in the foreground. | The application is running in the foreground. |
| onHide<sup>6+</sup> | () => void | Listens for whether the application is running in the background. | The application is running in the background. |
| onDestroy | () => void | Listens for application uninstallation. | The application exits. |
You can define the following page lifecycle functions in the **.js** file of the page. ## Page Lifecycle
<a name="table8214149144810"></a> You can define the following page lifecycle functions in the .js file of the page.
<table><thead align="left"><tr id="row320574954820"><th class="cellrowborder" valign="top" width="22.12%" id="mcps1.1.5.1.1"><p id="p6205184994816"><a name="p6205184994816"></a><a name="p6205184994816"></a>Attribute</p>
</th>
<th class="cellrowborder" valign="top" width="23.05%" id="mcps1.1.5.1.2"><p id="p1420594918484"><a name="p1420594918484"></a><a name="p1420594918484"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="17.23%" id="mcps1.1.5.1.3"><p id="p1420524994817"><a name="p1420524994817"></a><a name="p1420524994817"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="37.6%" id="mcps1.1.5.1.4"><p id="p22055492486"><a name="p22055492486"></a><a name="p22055492486"></a>Called When</p>
</th>
</tr>
</thead>
<tbody><tr id="row120616499486"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p5205114974810"><a name="p5205114974810"></a><a name="p5205114974810"></a>onInit</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p220514918482"><a name="p220514918482"></a><a name="p220514918482"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p122065491483"><a name="p122065491483"></a><a name="p122065491483"></a>Listens for page initialization.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p72061949104813"><a name="p72061949104813"></a><a name="p72061949104813"></a>Page initialization is complete. This function is called only once in the page lifecycle.</p>
</td>
</tr>
<tr id="row920612490483"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p5206349114812"><a name="p5206349114812"></a><a name="p5206349114812"></a>onReady</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p1206164910486"><a name="p1206164910486"></a><a name="p1206164910486"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p112066492486"><a name="p112066492486"></a><a name="p112066492486"></a>Listens for page creation.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p19206649154818"><a name="p19206649154818"></a><a name="p19206649154818"></a>A page is created. This function is called only once in the page lifecycle.</p>
</td>
</tr>
<tr id="row920615493488"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p16206144911482"><a name="p16206144911482"></a><a name="p16206144911482"></a>onShow</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p1020619492480"><a name="p1020619492480"></a><a name="p1020619492480"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p72061349164819"><a name="p72061349164819"></a><a name="p72061349164819"></a>Listens for page display.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p1920684934812"><a name="p1920684934812"></a><a name="p1920684934812"></a>The page is displayed.</p>
</td>
</tr>
<tr id="row14207184919481"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p1820694917488"><a name="p1820694917488"></a><a name="p1820694917488"></a>onHide</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p1720694914485"><a name="p1720694914485"></a><a name="p1720694914485"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p10207144914813"><a name="p10207144914813"></a><a name="p10207144914813"></a>Listens for page disappearance.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p1020724994815"><a name="p1020724994815"></a><a name="p1020724994815"></a>The page disappears.</p>
</td>
</tr>
<tr id="row11207194916482"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p16207849204813"><a name="p16207849204813"></a><a name="p16207849204813"></a>onDestroy</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p102071490484"><a name="p102071490484"></a><a name="p102071490484"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p1520744911486"><a name="p1520744911486"></a><a name="p1520744911486"></a>Listens for page destruction.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p82071649104811"><a name="p82071649104811"></a><a name="p82071649104811"></a>The page is destroyed.</p>
</td>
</tr>
<tr id="row192082496486"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p1420710493489"><a name="p1420710493489"></a><a name="p1420710493489"></a>onBackPress</p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p12207649174810"><a name="p12207649174810"></a><a name="p12207649174810"></a>() =&gt; boolean</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p14207249154815"><a name="p14207249154815"></a><a name="p14207249154815"></a>Listens for the back button action.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p1020714916483"><a name="p1020714916483"></a><a name="p1020714916483"></a>The back button is touched.</p>
<a name="ul02081949144816"></a><a name="ul02081949144816"></a><ul id="ul02081949144816"><li><strong id="b1355813548581"><a name="b1355813548581"></a><a name="b1355813548581"></a>true</strong> means that the page processes the return logic.</li><li><strong id="b163335813598"><a name="b163335813598"></a><a name="b163335813598"></a>false</strong> means that the default return logic is used.</li><li>If no value is returned, the default return logic is used.</li></ul>
</td>
</tr>
<tr id="row8208174916489"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p1920810495486"><a name="p1920810495486"></a><a name="p1920810495486"></a>onActive()<sup id="sup1920884964819"><a name="sup1920884964819"></a><a name="sup1920884964819"></a>5+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p92081349194817"><a name="p92081349194817"></a><a name="p92081349194817"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p1320812492487"><a name="p1320812492487"></a><a name="p1320812492487"></a>Listens for page activation.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p820834974814"><a name="p820834974814"></a><a name="p820834974814"></a>The page is activated.</p>
</td>
</tr>
<tr id="row92091549174812"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p12084494487"><a name="p12084494487"></a><a name="p12084494487"></a>onInactive()<sup id="sup3208349144814"><a name="sup3208349144814"></a><a name="sup3208349144814"></a>5+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p1820854911485"><a name="p1820854911485"></a><a name="p1820854911485"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p2209114954816"><a name="p2209114954816"></a><a name="p2209114954816"></a>Listens for page suspension.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p1220944974811"><a name="p1220944974811"></a><a name="p1220944974811"></a>The page is suspended.</p>
</td>
</tr>
<tr id="row020918491481"><td class="cellrowborder" valign="top" width="22.12%" headers="mcps1.1.5.1.1 "><p id="p5209849124815"><a name="p5209849124815"></a><a name="p5209849124815"></a>onNewRequest()<sup id="sup32095496485"><a name="sup32095496485"></a><a name="sup32095496485"></a>5+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="23.05%" headers="mcps1.1.5.1.2 "><p id="p22091849144815"><a name="p22091849144815"></a><a name="p22091849144815"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="17.23%" headers="mcps1.1.5.1.3 "><p id="p72091149134813"><a name="p72091149134813"></a><a name="p72091149134813"></a>Listens for a new FA request.</p>
</td>
<td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.1.5.1.4 "><p id="p1920974974818"><a name="p1920974974818"></a><a name="p1920974974818"></a>The FA has been started and a new request is received.</p>
</td>
</tr>
</tbody>
</table>
The lifecycle functions of page A are called in the following sequence: | Attribute | Type | Description | Called When |
| -------- | -------- | -------- | -------- |
| onInit | () => void | Listens for page initialization. | Page initialization is complete. This function is called only once in the page lifecycle. |
| onReady | () => void | Listens for page creation. | A page is created. This function is called only once in the page lifecycle. |
| onShow | () => void | Listens for page display. | The page is displayed. |
| onHide | () => void | Listens for page disappearance. | The page disappears. |
| onDestroy | () => void | Listens for page destruction. | The page is destroyed. |
| onBackPress | () => boolean | Listens for the back button action. | The back button is touched.<br/>- true means that the page processes the return logic.<br/>- false means that the default return logic is used.<br/>- If no value is returned, the default return logic is used. |
| onActive()<sup>5+</sup> | () => void | Listens for page activation. | The page is activated. |
| onInactive()<sup>5+</sup> | () => void | Listens for page suspension. | The page is suspended. |
| onNewRequest()<sup>5+</sup> | () => void | Listens for a new FA request. | The FA has been started and a new request is received. |
- Open page A: onInit\(\) -\> onReady\(\) -\> onShow\(\) The lifecycle functions of page A are called in the following sequence:
- Open page B on page A: onHide\(\) - Open page A: onInit() -> onReady() -> onShow()
- Go back to page A from page B: onShow\(\)
- Exit page A: onBackPress\(\) -\> onHide\(\) -\> onDestroy\(\)
- Hide page A: onInactive\(\) -\> onHide\(\)
- Show background page A on the foreground: onShow\(\) -\> onActive\(\)
![](figures/en-us_image_0000001147417424.png) - Open page B on page A: onHide()
- Go back to page A from page B: onShow()
- Exit page A: onBackPress() -> onHide() -> onDestroy()
- Hide page A: onInactive() -> onHide()
- Show background page A on the foreground: onShow() -> onActive()
![en-us_image_0000001267887881](figures/en-us_image_0000001267887881.png)
# Multi-Language Capability<a name="EN-US_TOPIC_0000001173324681"></a> # Multi-Language Capability
Applications designed based on the JS UI framework apply to different countries and regions. With the multi-language capability, you do not need to develop application versions in different languages, and your users can switch between various locales. This also facilitates project maintenance. Applications designed based on the JS UI framework apply to different countries and regions. With the multi-language capability, you do not need to develop application versions in different languages, and your users can switch between various locales. This also facilitates project maintenance.
You only need to perform operations in [Resource Files](#section733935013515) and [Resource Reference](#section522111116527) to use the multi-language capability of this framework. For details about how to obtain the current system language, see [Language Acquisition](#section2872192475310).
## Resource Files<a name="section733935013515"></a> You only need to perform operations in [Resource Files](#resource-files) and [Resource Reference](#resource-reference) to use the multi-language capability of this framework. For details about how to obtain the current system language, see [Language Acquisition](#language-acquisition).
## Resource Files
Resource files store application content in multiple languages. This framework uses JSON files to store resource definitions. Place the resource file of each locale in the **i18n** directory described in [File Organization](js-framework-file.md). Resource files store application content in multiple languages. This framework uses JSON files to store resource definitions. Place the resource file of each locale in the i18n directory described in [File Organization](js-framework-file.md).
Resource files should be named in _language-script-region_.json format. For example, the resource file for Hong Kong Chinese in the traditional script is named zh-Hant-HK. You can omit the region, for example, zh-CN for simplified Chinese, or omit both the script and region, for example, zh for Chinese.
Resource files should be named in _language-script-region_**.json** format. For example, the resource file for Hong Kong Chinese in the traditional script is named **zh-Hant-HK**. You can omit the region, for example, **zh-CN** for simplified Chinese, or omit both the script and region, for example, **zh** for Chinese.
``` ```
language[-script-region].json language[-script-region].json
...@@ -16,41 +20,19 @@ language[-script-region].json ...@@ -16,41 +20,19 @@ language[-script-region].json
The following table describes the requirements for the qualifiers of resource file names. The following table describes the requirements for the qualifiers of resource file names.
**Table 1** Requirements for qualifier values Table1 Requirements for qualifier values
<a name="table18887936123715"></a> | Qualifier Type | Description and Value Range |
<table><thead align="left"><tr id="row1288893623719"><th class="cellrowborder" valign="top" width="16.3%" id="mcps1.2.3.1.1"><p id="en-us_topic_0000001062847941_p933162572513"><a name="en-us_topic_0000001062847941_p933162572513"></a><a name="en-us_topic_0000001062847941_p933162572513"></a>Qualifier Type</p> | -------- | -------- |
</th> | Language | Indicates the language used by the device. The value consists of two or three lowercase letters, for example, zh indicates Chinese, en indicates English, and mai indicates Maithili.<br/>For details about the value range, refer to ISO 639 (codes for the representation of names of languages). |
<th class="cellrowborder" valign="top" width="83.7%" id="mcps1.2.3.1.2"><p id="en-us_topic_0000001062847941_p0331102502517"><a name="en-us_topic_0000001062847941_p0331102502517"></a><a name="en-us_topic_0000001062847941_p0331102502517"></a>Description and Value Range</p> | Script | Indicates the script type used by the device. The value starts with one uppercase letter followed by three lowercase letters, for example, Hans indicates simplified Chinese and Hant indicates traditional Chinese.<br/>For details about the value range, refer to ISO 15924 (codes for the representation of names of scripts). |
</th> | Country/Region | Indicates the country or region where a user is located. The value consists of two or three uppercase letters or three digits, for example, CN indicates China and GB indicates the United Kingdom.<br/>For details about the value range, refer to ISO 3166-1 (codes for the representation of names of countries and their subdivisions). |
</tr>
</thead> If there is no resource file of the locale that matches the system language, content in the en-US.json file will be used by default.
<tbody><tr id="row198881636143719"><td class="cellrowborder" valign="top" width="16.3%" headers="mcps1.2.3.1.1 "><p id="en-us_topic_0000001062847941_p5331192542519"><a name="en-us_topic_0000001062847941_p5331192542519"></a><a name="en-us_topic_0000001062847941_p5331192542519"></a>Language</p>
</td>
<td class="cellrowborder" valign="top" width="83.7%" headers="mcps1.2.3.1.2 "><p id="en-us_topic_0000001062847941_p19331625202513"><a name="en-us_topic_0000001062847941_p19331625202513"></a><a name="en-us_topic_0000001062847941_p19331625202513"></a>Indicates the language used by the device. The value consists of two or three lowercase letters, for example, <strong id="en-us_topic_0000001062847941_b576443512210"><a name="en-us_topic_0000001062847941_b576443512210"></a><a name="en-us_topic_0000001062847941_b576443512210"></a>zh</strong> indicates Chinese, <strong id="en-us_topic_0000001062847941_b182198414218"><a name="en-us_topic_0000001062847941_b182198414218"></a><a name="en-us_topic_0000001062847941_b182198414218"></a>en</strong> indicates English, and <strong id="en-us_topic_0000001062847941_b157701569717"><a name="en-us_topic_0000001062847941_b157701569717"></a><a name="en-us_topic_0000001062847941_b157701569717"></a>mai</strong> indicates Maithili.</p>
<p id="en-us_topic_0000001062847941_p633232516255"><a name="en-us_topic_0000001062847941_p633232516255"></a><a name="en-us_topic_0000001062847941_p633232516255"></a>For details about the value range, refer to <strong id="en-us_topic_0000001062847941_b4332142515256"><a name="en-us_topic_0000001062847941_b4332142515256"></a><a name="en-us_topic_0000001062847941_b4332142515256"></a>ISO 639</strong> (codes for the representation of names of languages).</p>
</td>
</tr>
<tr id="row5888133693714"><td class="cellrowborder" valign="top" width="16.3%" headers="mcps1.2.3.1.1 "><p id="en-us_topic_0000001062847941_p14332112518252"><a name="en-us_topic_0000001062847941_p14332112518252"></a><a name="en-us_topic_0000001062847941_p14332112518252"></a>Script</p>
</td>
<td class="cellrowborder" valign="top" width="83.7%" headers="mcps1.2.3.1.2 "><p id="en-us_topic_0000001062847941_p9332192522510"><a name="en-us_topic_0000001062847941_p9332192522510"></a><a name="en-us_topic_0000001062847941_p9332192522510"></a>Indicates the script type used by the device. The value starts with one uppercase letter followed by three lowercase letters, for example, <strong id="en-us_topic_0000001062847941_b61243486306"><a name="en-us_topic_0000001062847941_b61243486306"></a><a name="en-us_topic_0000001062847941_b61243486306"></a>Hans</strong> indicates simplified Chinese and <strong id="en-us_topic_0000001062847941_b1643275214309"><a name="en-us_topic_0000001062847941_b1643275214309"></a><a name="en-us_topic_0000001062847941_b1643275214309"></a>Hant</strong> indicates traditional Chinese.</p>
<p id="en-us_topic_0000001062847941_p20332152582517"><a name="en-us_topic_0000001062847941_p20332152582517"></a><a name="en-us_topic_0000001062847941_p20332152582517"></a>For details about the value range, refer to <strong id="en-us_topic_0000001062847941_b986482862513"><a name="en-us_topic_0000001062847941_b986482862513"></a><a name="en-us_topic_0000001062847941_b986482862513"></a>ISO 15924</strong> (codes for the representation of names of scripts).</p>
</td>
</tr>
<tr id="row1888143616376"><td class="cellrowborder" valign="top" width="16.3%" headers="mcps1.2.3.1.1 "><p id="en-us_topic_0000001062847941_p18332825152513"><a name="en-us_topic_0000001062847941_p18332825152513"></a><a name="en-us_topic_0000001062847941_p18332825152513"></a>Country/Region</p>
</td>
<td class="cellrowborder" valign="top" width="83.7%" headers="mcps1.2.3.1.2 "><p id="en-us_topic_0000001062847941_p133212251255"><a name="en-us_topic_0000001062847941_p133212251255"></a><a name="en-us_topic_0000001062847941_p133212251255"></a>Indicates the country or region where a user is located. The value consists of two or three uppercase letters or three digits, for example, <strong id="en-us_topic_0000001062847941_b12684139103216"><a name="en-us_topic_0000001062847941_b12684139103216"></a><a name="en-us_topic_0000001062847941_b12684139103216"></a>CN</strong> indicates China and <strong id="en-us_topic_0000001062847941_b2349716183218"><a name="en-us_topic_0000001062847941_b2349716183218"></a><a name="en-us_topic_0000001062847941_b2349716183218"></a>GB</strong> indicates the United Kingdom.</p>
<p id="en-us_topic_0000001062847941_p5332925172513"><a name="en-us_topic_0000001062847941_p5332925172513"></a><a name="en-us_topic_0000001062847941_p5332925172513"></a>For details about the value range, refer to <strong id="en-us_topic_0000001062847941_b633242532515"><a name="en-us_topic_0000001062847941_b633242532515"></a><a name="en-us_topic_0000001062847941_b633242532515"></a>ISO 3166-1</strong> (codes for the representation of names of countries and their subdivisions).</p>
</td>
</tr>
</tbody>
</table>
If there is no resource file of the locale that matches the system language, content in the **en-US.json** file will be used by default.
The format of the resource file content is as follows: The format of the resource file content is as follows:
en-US.json en-US.json
``` ```
{ {
...@@ -67,12 +49,16 @@ en-US.json ...@@ -67,12 +49,16 @@ en-US.json
} }
``` ```
Different languages have different matching rules for singular and plural forms. In the resource file, **zero**, **one**, **two**, **few**, **many**, and **other** are used to define the string content in different singular and plural forms. For example, there is only the **other** scenario in Chinese since the language does not have singular and plural forms. **one** and **other** scenarios are applicable to English. All six scenarios are needed for Arabic.
The following example takes **en-US.json** and **ar-AE.json** as examples: Different languages have different matching rules for singular and plural forms. In the resource file, zero, one, two, few, many, and other are used to define the string content in different singular and plural forms. For example, there is only the other scenario in Chinese since the language does not have singular and plural forms. one and other scenarios are applicable to English. All six scenarios are needed for Arabic.
The following example takes en-US.json and ar-AE.json as examples:
en-US.json en-US.json
``` ```
{ {
"strings": { "strings": {
...@@ -84,8 +70,10 @@ en-US.json ...@@ -84,8 +70,10 @@ en-US.json
} }
``` ```
ar-AE.json ar-AE.json
``` ```
{ {
"strings": { "strings": {
...@@ -101,77 +89,26 @@ ar-AE.json ...@@ -101,77 +89,26 @@ ar-AE.json
} }
``` ```
## Resource Reference<a name="section522111116527"></a>
Multi-language syntax used on application development pages \(including simple formatting and singular-plural formatting\) can be used in **.hml** or **.js** files. ## Resource Reference
Multi-language syntax used on application development pages (including simple formatting and singular-plural formatting) can be used in .hml or .js files.
- Simple formatting - Simple formatting
Use the $t function to reference to resources of different locales. The $t function is available for both .hml and .js files. The system displays content based on a resource file path specified via $t and the specified resource file whose locale matches the current system language.
Table2 Simple formatting
| Attribute | Type | Parameter | Mandatory | Description |
| -------- | -------- | -------- | -------- | -------- |
| $t | Function | See Table3 | Yes | Sets the parameters based on the system language, for example, this.$t('strings.hello'). |
Use the **$t** function to reference to resources of different locales. The **$t** function is available for both **.hml** and **.js** files. The system displays content based on a resource file path specified via **$t** and the specified resource file whose locale matches the current system language. Table3 $t function parameters
**Table 2** Simple formatting | Parameter | Type | Mandatory | Description |
| -------- | -------- | -------- | -------- |
<a name="table10506333184710"></a> | path | string | Yes | Path of the language resource key |
<table><thead align="left"><tr id="row1250615336479"><th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.1"><p id="p14506163314479"><a name="p14506163314479"></a><a name="p14506163314479"></a>Attribute</p> | params | Array\|Object | No | Content used to replace placeholders during runtime. There are two types of placeholders available:<br/>- Named placeholder, for example, {name}. The actual content must be of the object type, for example, $t('strings.object', { name: 'Hello world' }).<br/>- Digit placeholder, for example, {0}. The actual content must be of the array type, for example, $t('strings.array', ['Hello world']. |
</th>
<th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.2"><p id="p205076333474"><a name="p205076333474"></a><a name="p205076333474"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="20.85%" id="mcps1.2.6.1.3"><p id="p250773354718"><a name="p250773354718"></a><a name="p250773354718"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="9.790000000000001%" id="mcps1.2.6.1.4"><p id="p5742204362716"><a name="p5742204362716"></a><a name="p5742204362716"></a>Mandatory</p>
</th>
<th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.5"><p id="p105079331472"><a name="p105079331472"></a><a name="p105079331472"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1550713344719"><td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.1 "><p id="p185071433174714"><a name="p185071433174714"></a><a name="p185071433174714"></a>$t</p>
</td>
<td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.2 "><p id="p10507193304718"><a name="p10507193304718"></a><a name="p10507193304718"></a>Function</p>
</td>
<td class="cellrowborder" valign="top" width="20.85%" headers="mcps1.2.6.1.3 "><p id="p69461437131511"><a name="p69461437131511"></a><a name="p69461437131511"></a>See <a href="#table1161115496137">Table 3</a>.</p>
</td>
<td class="cellrowborder" valign="top" width="9.790000000000001%" headers="mcps1.2.6.1.4 "><p id="p1991117447"><a name="p1991117447"></a><a name="p1991117447"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.5 "><p id="p1150753310476"><a name="p1150753310476"></a><a name="p1150753310476"></a>Sets the parameters based on the system language, for example, <strong id="b15165861155"><a name="b15165861155"></a><a name="b15165861155"></a>this.$t('strings.hello')</strong>.</p>
</td>
</tr>
</tbody>
</table>
**Table 3** $t function parameters
<a name="table1161115496137"></a>
<table><thead align="left"><tr id="row1061274917131"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p166121249131312"><a name="p166121249131312"></a><a name="p166121249131312"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p261213498139"><a name="p261213498139"></a><a name="p261213498139"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p15612124910139"><a name="p15612124910139"></a><a name="p15612124910139"></a>Mandatory</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p1061274951318"><a name="p1061274951318"></a><a name="p1061274951318"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row15612749191317"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p161215495131"><a name="p161215495131"></a><a name="p161215495131"></a>path</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p176121049101318"><a name="p176121049101318"></a><a name="p176121049101318"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p8612144917136"><a name="p8612144917136"></a><a name="p8612144917136"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p161254911314"><a name="p161254911314"></a><a name="p161254911314"></a>Path of the language resource key</p>
</td>
</tr>
<tr id="row861264931319"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p15612449181316"><a name="p15612449181316"></a><a name="p15612449181316"></a>params</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p496164415306"><a name="p496164415306"></a><a name="p496164415306"></a>Array|Object</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p861284917131"><a name="p861284917131"></a><a name="p861284917131"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p20612194931313"><a name="p20612194931313"></a><a name="p20612194931313"></a>Content used to replace placeholders during runtime. There are two types of placeholders available:</p>
<a name="ul0124131652619"></a><a name="ul0124131652619"></a><ul id="ul0124131652619"><li>Named placeholder, for example, <strong id="b1393217204415"><a name="b1393217204415"></a><a name="b1393217204415"></a>{name}</strong>. The actual content must be of the object type, for example, <strong id="b1190152717414"><a name="b1190152717414"></a><a name="b1190152717414"></a>$t('strings.object', { name: 'Hello world' })</strong>.</li><li>Digit placeholder, for example, <strong id="b64091832204118"><a name="b64091832204118"></a><a name="b64091832204118"></a>{0}</strong>. The actual content must be of the array type, for example, <strong id="b18296193544116"><a name="b18296193544116"></a><a name="b18296193544116"></a>$t('strings.array', ['Hello world']</strong>.</li></ul>
</td>
</tr>
</tbody>
</table>
- Example code for simple formatting - Example code for simple formatting
...@@ -198,6 +135,7 @@ Multi-language syntax used on application development pages \(including simple f ...@@ -198,6 +135,7 @@ Multi-language syntax used on application development pages \(including simple f
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
// The following example uses the $t function in the .js file. // The following example uses the $t function in the .js file.
...@@ -218,71 +156,18 @@ Multi-language syntax used on application development pages \(including simple f ...@@ -218,71 +156,18 @@ Multi-language syntax used on application development pages \(including simple f
``` ```
- Singular-plural formatting - Singular-plural formatting
Table4 Singular-plural formatting
| Attribute | Type | Parameter | Mandatory | Description |
| -------- | -------- | -------- | -------- | -------- |
| $tc | Function | See Table 5. | Yes | Converts between the singular and plural forms based on the system language, for example, this.$tc('strings.people').<br/>> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:<br/>> The resource content is distinguished by the following JSON keys: zero, one, two, few, many, and other. |
**Table 4** Singular-plural formatting Table5 $tc function parameters
<a name="table12722349115211"></a> | Parameter | Type | Mandatory | Description |
<table><thead align="left"><tr id="row11723204985215"><th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.1"><p id="p9723749145217"><a name="p9723749145217"></a><a name="p9723749145217"></a>Attribute</p> | -------- | -------- | -------- | -------- |
</th> | path | string | Yes | Path of the language resource key |
<th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.2"><p id="p1372374910528"><a name="p1372374910528"></a><a name="p1372374910528"></a>Type</p> | count | number | Yes | Number |
</th>
<th class="cellrowborder" valign="top" width="18.790000000000003%" id="mcps1.2.6.1.3"><p id="p1272314496527"><a name="p1272314496527"></a><a name="p1272314496527"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="11.850000000000001%" id="mcps1.2.6.1.4"><p id="p39561320202915"><a name="p39561320202915"></a><a name="p39561320202915"></a>Mandatory</p>
</th>
<th class="cellrowborder" valign="top" width="23.12%" id="mcps1.2.6.1.5"><p id="p12723124915528"><a name="p12723124915528"></a><a name="p12723124915528"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row167231749155214"><td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.1 "><p id="p15723184945217"><a name="p15723184945217"></a><a name="p15723184945217"></a>$tc</p>
</td>
<td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.2 "><p id="p1372310494525"><a name="p1372310494525"></a><a name="p1372310494525"></a>Function</p>
</td>
<td class="cellrowborder" valign="top" width="18.790000000000003%" headers="mcps1.2.6.1.3 "><p id="p3645417495"><a name="p3645417495"></a><a name="p3645417495"></a>See <a href="#table1856962321614">Table 5</a>.</p>
</td>
<td class="cellrowborder" valign="top" width="11.850000000000001%" headers="mcps1.2.6.1.4 "><p id="p1589916493474"><a name="p1589916493474"></a><a name="p1589916493474"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="23.12%" headers="mcps1.2.6.1.5 "><p id="p1080910112617"><a name="p1080910112617"></a><a name="p1080910112617"></a>Converts between the singular and plural forms based on the system language, for example, <strong id="b2975753182417"><a name="b2975753182417"></a><a name="b2975753182417"></a>this.$tc('strings.people')</strong>.</p>
<div class="note" id="note44962033184817"><a name="note44962033184817"></a><a name="note44962033184817"></a><span class="notetitle"> NOTE: </span><div class="notebody"><p id="p1456045614402"><a name="p1456045614402"></a><a name="p1456045614402"></a>The resource content is distinguished by the following JSON keys: <strong id="b682311541227"><a name="b682311541227"></a><a name="b682311541227"></a>zero</strong>, <strong id="b6176092310"><a name="b6176092310"></a><a name="b6176092310"></a>one</strong>, <strong id="b6135846238"><a name="b6135846238"></a><a name="b6135846238"></a>two</strong>, <strong id="b83625772314"><a name="b83625772314"></a><a name="b83625772314"></a>few</strong>, <strong id="b06791310172315"><a name="b06791310172315"></a><a name="b06791310172315"></a>many</strong>, and <strong id="b31161315112320"><a name="b31161315112320"></a><a name="b31161315112320"></a>other</strong>.</p>
</div></div>
</td>
</tr>
</tbody>
</table>
**Table 5** $tc function parameters
<a name="table1856962321614"></a>
<table><thead align="left"><tr id="row13569122391616"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p135698238163"><a name="p135698238163"></a><a name="p135698238163"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p17569152311168"><a name="p17569152311168"></a><a name="p17569152311168"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p1569523171613"><a name="p1569523171613"></a><a name="p1569523171613"></a>Mandatory</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p2569192341613"><a name="p2569192341613"></a><a name="p2569192341613"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row056919234163"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p175691923171610"><a name="p175691923171610"></a><a name="p175691923171610"></a>path</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p11569182319162"><a name="p11569182319162"></a><a name="p11569182319162"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p93611250151616"><a name="p93611250151616"></a><a name="p93611250151616"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p145691323171620"><a name="p145691323171620"></a><a name="p145691323171620"></a>Path of the language resource key</p>
</td>
</tr>
<tr id="row1569142351616"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p956911235161"><a name="p956911235161"></a><a name="p956911235161"></a>count</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p7569182321618"><a name="p7569182321618"></a><a name="p7569182321618"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p6377550111614"><a name="p6377550111614"></a><a name="p6377550111614"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1556962371614"><a name="p1556962371614"></a><a name="p1556962371614"></a>Number</p>
</td>
</tr>
</tbody>
</table>
- Sample code for singular-plural formatting - Sample code for singular-plural formatting
...@@ -305,7 +190,6 @@ Multi-language syntax used on application development pages \(including simple f ...@@ -305,7 +190,6 @@ Multi-language syntax used on application development pages \(including simple f
``` ```
## Language Acquisition<a name="section2872192475310"></a> ## Language Acquisition
For details about how to obtain the language, see the [Application Configuration](../reference/apis/js-apis-basic-features-configuration.md) section.
For details about how to obtain the language, see the Application Configuration section.
# Resource Limitations and Access<a name="EN-US_TOPIC_0000001173164731"></a> # Resource Limitations and Access
## Resource Qualifiers<a name="section197802036142011"></a>
The name of a resource qualifier consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the screen density, and more. The qualifiers are separated using hyphens \(-\). When creating a qualifiers file under **resources**, you need to understand the file naming conventions and the rules for matching qualifiers files and the device status. ## Resource Qualifiers
## Naming Conventions for Resource Qualifiers<a name="section550585117202"></a> The name of a resource qualifier consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the screen density, and more. The qualifiers are separated using hyphens (-). When creating a qualifiers file under resources, you need to understand the file naming conventions and the rules for matching qualifiers files and the device status.
## Naming Conventions for Resource Qualifiers
- Qualifiers are ordered in the following sequence: screen density. You can select one or multiple qualifiers to name your file based on your application scenarios and device characteristics, while following the preceding sequence. - Qualifiers are ordered in the following sequence: screen density. You can select one or multiple qualifiers to name your file based on your application scenarios and device characteristics, while following the preceding sequence.
- The qualifiers are separated using hyphens \(-\), for example, **res-dark-ldpi.json**.
- Value range of qualifiers: The value of each qualifier must meet the requirements specified in the following table. Otherwise, the resource files in the **resources** directory cannot be matched. The qualifiers are case sensitive. - The qualifiers are separated using hyphens (-), for example, res-dark-ldpi.json.
- Qualifier prefix: The name of a qualifier file in the **resources** file has the prefix **res**, for example, **res-ldpi.json**.
- Default resource qualifier file: By default, the resource qualifier file in **resources** is **res-defaults.json**. - Value range of qualifiers: The value of each qualifier must meet the requirements specified in the following table. Otherwise, the resource files in the resources directory cannot be matched. The qualifiers are case sensitive.
- Qualifier prefix: The name of a qualifier file in the resources file has the prefix res, for example, res-ldpi.json.
- Default resource qualifier file: By default, the resource qualifier file in resources is res-defaults.json.
- In the resource qualifier file, color enumeration cannot be used to set resources. - In the resource qualifier file, color enumeration cannot be used to set resources.
**Table 1** Resource qualifiers
Table1 Resource qualifiers
<a name="table153971631192110"></a>
<table><thead align="left"><tr id="row1397133152114"><th class="cellrowborder" valign="top" width="23.400000000000002%" id="mcps1.2.3.1.1"><p id="p7397331152114"><a name="p7397331152114"></a><a name="p7397331152114"></a>Data Type</p> | Data Type | Description and Value Range |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="76.6%" id="mcps1.2.3.1.2"><p id="p1139719318218"><a name="p1139719318218"></a><a name="p1139719318218"></a>Description and Value Range</p> | Screen density | Indicates the screen density of the device, in dpi. The value can be:<br/>- ldpi: low-density screen (~120 dpi) (0.75 x Reference density)<br/>- mdpi: medium-density screen (~160 dpi) (reference density)<br/>- hdpi: high-density screen (~240 dpi) (1.5 x Reference density)<br/>- xhdpi: extra high-density screen (~320 dpi) (2.0 x Reference density)<br/>- xxhdpi: extra extra high-density screen (~480 dpi) (3.0 x Reference density)<br/>- xxxhdpi: extra extra extra high-density screen (~640 dpi) (4.0 x Reference density) |
</th>
</tr>
</thead> ## Rules for Matching Qualifiers Files and Device Resources
<tbody><tr id="row1890413245238"><td class="cellrowborder" valign="top" width="23.400000000000002%" headers="mcps1.2.3.1.1 "><p id="p2090532442315"><a name="p2090532442315"></a><a name="p2090532442315"></a>Screen density</p>
</td> - Qualifiers are matched with the device resources in the following priorities: screen orientation > dark mode > screen density. If no matching resource qualifier file is found, the default resource qualifier file is used.
<td class="cellrowborder" valign="top" width="76.6%" headers="mcps1.2.3.1.2 "><p id="p2389144311231"><a name="p2389144311231"></a><a name="p2389144311231"></a>Indicates the screen density of the device, in dpi. The value can be:</p>
<a name="ul1311184562317"></a><a name="ul1311184562317"></a><ul id="ul1311184562317"><li><strong id="b199641873345"><a name="b199641873345"></a><a name="b199641873345"></a>ldpi</strong>: low-density screen (~120 dpi) (0.75 x Reference density)</li><li><strong id="b13727115783416"><a name="b13727115783416"></a><a name="b13727115783416"></a>mdpi</strong>: medium-density screen (~160 dpi) (reference density)</li><li><strong id="b4271212193512"><a name="b4271212193512"></a><a name="b4271212193512"></a>hdpi</strong>: high-density screen (~240 dpi) (1.5 x Reference density)</li><li><strong id="b2780515183515"><a name="b2780515183515"></a><a name="b2780515183515"></a>xhdpi</strong>: extra high-density screen (~320 dpi) (2.0 x Reference density)</li><li><strong id="b5206125518356"><a name="b5206125518356"></a><a name="b5206125518356"></a>xxhdpi</strong>: extra extra high-density screen (~480 dpi) (3.0 x Reference density)</li><li><strong id="b11485359103511"><a name="b11485359103511"></a><a name="b11485359103511"></a>xxxhdpi</strong>: extra extra extra high-density screen (~640 dpi) (4.0 x Reference density)</li></ul> - If a qualifier file contains resource qualifiers, their values must be consistent with the current device status so that the file can be used for matching the device status. For example, the res-hdpi.json qualifier file does not match the device density xhdpi.
</td>
</tr>
</tbody> ## Referencing Resources in the JS Module
</table>
You can use the $r syntax in the application development files .hml and .js to format the JSON resources in the resources directory of the JS module and obtain the corresponding resources.
## **Rules for Matching Qualifiers Files and Device Resources**<a name="section59927387241"></a>
| Attribute | Type | Description |
- Qualifiers are matched with the device resources in the following priorities: MCC and MNC \> screen orientation \> dark mode \> device type \> screen density. If no matching resource qualifier file is found, the default resource qualifier file is used. | -------- | -------- | -------- |
- If a qualifier file contains resource qualifiers, their values must be consistent with the current device status so that the file can be used for matching the device status. For example, the **res-hdpi.json** qualifier file does not match the device density **xhdpi**. | $r | (key: string) => string | Obtains the resource content that matches the specific qualifiers, for example, this.$r('strings.hello loaded).<br/>Parameter description:<br/>- key: key value defined in the resource qualifier file, for example, strings.hello.<br/> |
## Referencing Resources in the JS Module<a name="section7516798256"></a> Example of res-defaults.json:<br/>
You can use the $r syntax in the application development files **.hml** and **.js** to format the JSON resources in the **resources** directory of the JS module and obtain the corresponding resources. ```
{
<a name="table1595144416585"></a>
<table><thead align="left"><tr id="row1295119445588"><th class="cellrowborder" valign="top" width="11.41114111411141%" id="mcps1.1.4.1.1"><p id="p18951844195815"><a name="p18951844195815"></a><a name="p18951844195815"></a>Attribute</p>
</th>
<th class="cellrowborder" valign="top" width="23.17231723172317%" id="mcps1.1.4.1.2"><p id="p16951044135813"><a name="p16951044135813"></a><a name="p16951044135813"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="65.41654165416541%" id="mcps1.1.4.1.3"><p id="p1795154417586"><a name="p1795154417586"></a><a name="p1795154417586"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row8951164435812"><td class="cellrowborder" valign="top" width="11.41114111411141%" headers="mcps1.1.4.1.1 "><p id="p195124495814"><a name="p195124495814"></a><a name="p195124495814"></a>$r</p>
</td>
<td class="cellrowborder" valign="top" width="23.17231723172317%" headers="mcps1.1.4.1.2 "><p id="p3952164418589"><a name="p3952164418589"></a><a name="p3952164418589"></a>(key: string) =&gt; string</p>
</td>
<td class="cellrowborder" valign="top" width="65.41654165416541%" headers="mcps1.1.4.1.3 "><p id="p204636815564"><a name="p204636815564"></a><a name="p204636815564"></a>Obtains the resource content that matches the specific qualifiers, for example, <strong id="b2031311443445"><a name="b2031311443445"></a><a name="b2031311443445"></a>this.$r('strings.hello loaded)</strong>.</p>
<p id="p1146311815615"><a name="p1146311815615"></a><a name="p1146311815615"></a>Parameter description:</p>
<a name="ul18463178185617"></a><a name="ul18463178185617"></a><ul id="ul18463178185617"><li><strong id="b19598205334413"><a name="b19598205334413"></a><a name="b19598205334413"></a>key</strong>: key value defined in the resource qualifier file, for example, <strong id="b2956165194511"><a name="b2956165194511"></a><a name="b2956165194511"></a>strings.hello</strong>.</li></ul>
<p id="p174645835614"><a name="p174645835614"></a><a name="p174645835614"></a><strong id="b788814173455"><a name="b788814173455"></a><a name="b788814173455"></a>Example of res-defaults.json:</strong></p>
<pre class="screen" id="screen8464178165613"><a name="screen8464178165613"></a><a name="screen8464178165613"></a>{
strings: { strings: {
hello: 'hello world' hello: 'hello world'
} }
}</pre> }
</td> ```
</tr>
</tbody>
</table>
## Example<a name="section9710101017318"></a> ## Example
resources/res-dark.json: resources/res-dark.json:
``` ```
{ {
"image": { "image": {
...@@ -84,6 +71,7 @@ resources/res-dark.json: ...@@ -84,6 +71,7 @@ resources/res-dark.json:
resources/res-defaults.json: resources/res-defaults.json:
``` ```
{ {
"image": { "image": {
...@@ -95,6 +83,7 @@ resources/res-defaults.json: ...@@ -95,6 +83,7 @@ resources/res-defaults.json:
} }
``` ```
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div style="background-color: {{ $r('colors.background') }}"> <div style="background-color: {{ $r('colors.background') }}">
...@@ -102,6 +91,5 @@ resources/res-defaults.json: ...@@ -102,6 +91,5 @@ resources/res-defaults.json:
</div> </div>
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>The resource qualifier file does not support color enumeration. > The resource qualifier file does not support color enumeration.
# CSS<a name="EN-US_TOPIC_0000001127125112"></a> # CSS
Cascading Style Sheets \(CSS\) is a language used to describe the HML page structure. All HML components have default styles. You can customize styles for these components using CSS to design various pages.
## Size Unit<a name="section81638230913"></a> Cascading Style Sheets (CSS) is a language used to describe the HML page structure. All HML components have default styles. You can customize styles for these components using CSS to design various pages.
1. Logical px set by **<length\>**: ## Size Unit
1. The default logical screen width is 720 px \(for details, see the **"window"** section in [config.json](js-framework-js-tag.md)\). Your page will be scaled to fit the actual width of the screen. For example, on a screen with the actual width of 1440 physical px, 100 px is displayed on 200 physical px, with all sizes doubled from 720 px to 1440 px.
2. If you set **autoDesignWidth** to **true** \(for details, see the **"window"** section in [config.json](js-framework-js-tag.md)\), the logical px are scaled based on the screen density. For example, if the screen density is 3x, 100 px will be rendered on 300 physical px. This approach is recommended when your application needs to adapt to multiple devices.
2. Percentage set by **<percentage\>**: The component size is represented by its percentage of the parent component size. For example, if the width **<percentage\>** of a component is set to **50%**, the width of the component is half of its parent component's width. 1. Logical px set by &lt;length&gt;:
1. The default logical screen width is 720 px (for details, see the "window" section in [config.json](js-framework-js-tag.md)). Your page will be scaled to fit the actual width of the screen. For example, on a screen with the actual width of 1440 physical px, 100 px is displayed on 200 physical px, with all sizes doubled from 720 px to 1440 px.
2. If you set autoDesignWidth to true (for details, see the "window" section in [config.json](js-framework-js-tag.md)), the logical px are scaled based on the screen density. For example, if the screen density is 3x, 100 px will be rendered on 300 physical px. This approach is recommended when your application needs to adapt to multiple devices.
## Style Import<a name="section890312411592"></a> 2. Percentage set by &lt;percentage&gt;: The component size is represented by its percentage of the parent component size. For example, if the width &lt;percentage&gt; of a component is set to 50%, the width of the component is half of its parent component's width.
CSS files can be imported using the **@import** statement. This facilitates module management and code reuse.
## Style Declaration<a name="section197695604215"></a> ## Style Import
The **.css** file with the same name as the **.hml** file in each page directory describes the styles of components on the HML page, determining how the components will be displayed. CSS files can be imported using the @import statement. This facilitates module management and code reuse.
1. Internal style: The **style** and **class** attributes can be used to specify the component style. Example:
## Style Declaration
The .css file with the same name as the .hml file in each page directory describes the styles of components on the HML page, determining how the components will be displayed.
1. Internal style: The style and class attributes can be used to specify the component style. Example:
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -27,6 +30,7 @@ The **.css** file with the same name as the **.hml** file in each page direc ...@@ -27,6 +30,7 @@ The **.css** file with the same name as the **.hml** file in each page direc
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -34,7 +38,7 @@ The **.css** file with the same name as the **.hml** file in each page direc ...@@ -34,7 +38,7 @@ The **.css** file with the same name as the **.hml** file in each page direc
} }
``` ```
2. External style files: You need to import the files. For example, create a **style.css** file in the **common** directory and import the file at the beginning of **index.css**. 2. External style files: You need to import the files. For example, create a style.css file in the common directory and import the file at the beginning of index.css.
``` ```
/* style.css */ /* style.css */
...@@ -43,6 +47,7 @@ The **.css** file with the same name as the **.hml** file in each page direc ...@@ -43,6 +47,7 @@ The **.css** file with the same name as the **.hml** file in each page direc
} }
``` ```
``` ```
/* index.css */ /* index.css */
@import '../../common/style.css'; @import '../../common/style.css';
...@@ -52,59 +57,21 @@ The **.css** file with the same name as the **.hml** file in each page direc ...@@ -52,59 +57,21 @@ The **.css** file with the same name as the **.hml** file in each page direc
``` ```
## Selectors<a name="section381741144310"></a> ## Selectors
A CSS selector is used to select elements for which styles need to be added to. The following table lists the supported selectors. A CSS selector is used to select elements for which styles need to be added to. The following table lists the supported selectors.
<a name="table8917183413489"></a> | Selector | Example | Description |
<table><thead align="left"><tr id="row1291753412489"><th class="cellrowborder" valign="top" width="15.341534153415342%" id="mcps1.1.4.1.1"><p id="p291763474818"><a name="p291763474818"></a><a name="p291763474818"></a>Selector</p> | -------- | -------- | -------- |
</th> | .class | .container | Selects all components whose class is container. |
<th class="cellrowborder" valign="top" width="24.852485248524854%" id="mcps1.1.4.1.2"><p id="p1491783412488"><a name="p1491783412488"></a><a name="p1491783412488"></a>Example</p> | \#id | \#titleId | Selects all components whose id is titleId. |
</th> | tag | text | Selects all &lt;text&gt; components. |
<th class="cellrowborder" valign="top" width="59.805980598059804%" id="mcps1.1.4.1.3"><p id="p10917173404818"><a name="p10917173404818"></a><a name="p10917173404818"></a>Description</p> | , | .title, .content | Selects all components whose class is title or content. |
</th> | \#id .class tag | \#containerId .content text | Selects all grandchild &lt;text&gt; components whose grandparent components are identified as containerId and whose parent components are of the content class. To select child components, use > to replace the space between \#id and .class, for example, \#containerId>.content. |
</tr>
</thead>
<tbody><tr id="row2091743484810"><td class="cellrowborder" valign="top" width="15.341534153415342%" headers="mcps1.1.4.1.1 "><p id="p1891783411483"><a name="p1891783411483"></a><a name="p1891783411483"></a>.class</p>
</td>
<td class="cellrowborder" valign="top" width="24.852485248524854%" headers="mcps1.1.4.1.2 "><p id="p169174348484"><a name="p169174348484"></a><a name="p169174348484"></a>.container</p>
</td>
<td class="cellrowborder" valign="top" width="59.805980598059804%" headers="mcps1.1.4.1.3 "><p id="p991733474814"><a name="p991733474814"></a><a name="p991733474814"></a>Selects all components whose <strong id="b266804373915"><a name="b266804373915"></a><a name="b266804373915"></a>class</strong> is <strong id="b13862113914395"><a name="b13862113914395"></a><a name="b13862113914395"></a>container</strong>.</p>
</td>
</tr>
<tr id="row189178343481"><td class="cellrowborder" valign="top" width="15.341534153415342%" headers="mcps1.1.4.1.1 "><p id="p5917634124817"><a name="p5917634124817"></a><a name="p5917634124817"></a>#id</p>
</td>
<td class="cellrowborder" valign="top" width="24.852485248524854%" headers="mcps1.1.4.1.2 "><p id="p89231120496"><a name="p89231120496"></a><a name="p89231120496"></a>#titleId</p>
</td>
<td class="cellrowborder" valign="top" width="59.805980598059804%" headers="mcps1.1.4.1.3 "><p id="p132391416144917"><a name="p132391416144917"></a><a name="p132391416144917"></a>Selects all components whose <strong id="b97491740201315"><a name="b97491740201315"></a><a name="b97491740201315"></a>id</strong> is <strong id="b620774121515"><a name="b620774121515"></a><a name="b620774121515"></a>titleId</strong>.</p>
</td>
</tr>
<tr id="row12917934154811"><td class="cellrowborder" valign="top" width="15.341534153415342%" headers="mcps1.1.4.1.1 "><p id="p1041721913499"><a name="p1041721913499"></a><a name="p1041721913499"></a>tag</p>
</td>
<td class="cellrowborder" valign="top" width="24.852485248524854%" headers="mcps1.1.4.1.2 "><p id="p4917203424816"><a name="p4917203424816"></a><a name="p4917203424816"></a>text</p>
</td>
<td class="cellrowborder" valign="top" width="59.805980598059804%" headers="mcps1.1.4.1.3 "><p id="p174847365491"><a name="p174847365491"></a><a name="p174847365491"></a>Selects all <strong id="b647149104015"><a name="b647149104015"></a><a name="b647149104015"></a>&lt;text&gt;</strong> components.</p>
</td>
</tr>
<tr id="row99179340488"><td class="cellrowborder" valign="top" width="15.341534153415342%" headers="mcps1.1.4.1.1 "><p id="p19918123424819"><a name="p19918123424819"></a><a name="p19918123424819"></a>,</p>
</td>
<td class="cellrowborder" valign="top" width="24.852485248524854%" headers="mcps1.1.4.1.2 "><p id="p7918734154817"><a name="p7918734154817"></a><a name="p7918734154817"></a>.title, .content</p>
</td>
<td class="cellrowborder" valign="top" width="59.805980598059804%" headers="mcps1.1.4.1.3 "><p id="p9240140154916"><a name="p9240140154916"></a><a name="p9240140154916"></a>Selects all components whose <strong id="b1792517381411"><a name="b1792517381411"></a><a name="b1792517381411"></a>class</strong> is <strong id="b123172282411"><a name="b123172282411"></a><a name="b123172282411"></a>title</strong> or <strong id="b13169142616410"><a name="b13169142616410"></a><a name="b13169142616410"></a>content</strong>.</p>
</td>
</tr>
<tr id="row1091833418485"><td class="cellrowborder" valign="top" width="15.341534153415342%" headers="mcps1.1.4.1.1 "><p id="p27744448492"><a name="p27744448492"></a><a name="p27744448492"></a>#id .class tag</p>
</td>
<td class="cellrowborder" valign="top" width="24.852485248524854%" headers="mcps1.1.4.1.2 "><p id="p0402948154911"><a name="p0402948154911"></a><a name="p0402948154911"></a>#containerId .content text</p>
</td>
<td class="cellrowborder" valign="top" width="59.805980598059804%" headers="mcps1.1.4.1.3 "><p id="p19830323135016"><a name="p19830323135016"></a><a name="p19830323135016"></a>Selects all grandchild <strong id="b912043612213"><a name="b912043612213"></a><a name="b912043612213"></a>&lt;text&gt;</strong> components whose grandparent components are identified as <strong id="b8266185815595"><a name="b8266185815595"></a><a name="b8266185815595"></a>containerId</strong> and whose parent components are of the <strong id="b1533612295015"><a name="b1533612295015"></a><a name="b1533612295015"></a>content</strong> class. To select child components, use <strong id="b1323417618"><a name="b1323417618"></a><a name="b1323417618"></a>&gt;</strong> to replace the space between <strong id="b123221349918"><a name="b123221349918"></a><a name="b123221349918"></a>#id</strong> and <strong id="b9863851313"><a name="b9863851313"></a><a name="b9863851313"></a>.class</strong>, for example, <strong id="b32921881723"><a name="b32921881723"></a><a name="b32921881723"></a>#containerId&gt;.content</strong>.</p>
</td>
</tr>
</tbody>
</table>
The following is an example: The following is an example:
``` ```
<!-- Page layoutxxx.hml --> <!-- Page layoutxxx.hml -->
<div id="containerId" class="container"> <div id="containerId" class="container">
...@@ -115,6 +82,7 @@ The following is an example: ...@@ -115,6 +82,7 @@ The following is an example:
</div> </div>
``` ```
``` ```
/* Page style xxx.css */ /* Page style xxx.css */
/* Set the style for all <div> components. */ /* Set the style for all <div> components. */
...@@ -147,63 +115,34 @@ div { ...@@ -147,63 +115,34 @@ div {
The above style works as follows: The above style works as follows:
![](figures/sample_css.png) ![en-us_image_0000001267607889](figures/en-us_image_0000001267607889.png)
In the preceding example, **.container text** sets title and content to blue, and **.container \> text** sets title to red. The two styles have the same priority, but **.container \> text** declares the style later and overwrites the former style. \(For details about the priority, see [Selector Specificity](#section1460102134415).\) In the preceding example, .container text sets title and content to blue, and .container > text sets title to red. The two styles have the same priority, but .container > text declares the style later and overwrites the former style. (For details about the priority, see [Selector Specificity](#selector-specificity).)
## Selector Specificity<a name="section1460102134415"></a> ## Selector Specificity
The specificity rule of the selectors complies with the W3C rule, which is only available for inline styles, **id**, **class**, **tag**, grandchild components, and child components. \(Inline styles are those declared in the **style** attribute.\) The specificity rule of the selectors complies with the W3C rule, which is only available for inline styles, id, class, tag, grandchild components, and child components. (Inline styles are those declared in the style attribute.)
When multiple selectors point to the same element, their priorities are as follows \(in descending order\): inline style \> **id** \> **class** \> **tag**. When multiple selectors point to the same element, their priorities are as follows (in descending order): inline style > id > class > tag.
## Pseudo-classes<a name="section633010213458"></a>
## Pseudo-classes
A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element\(s\). For example, **:disabled** can be used to select the element whose **disabled** attribute is **true**.
A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element(s). For example, :disabled can be used to select the element whose disabled attribute is true.
In addition to a single pseudo-class, a combination of pseudo-classes is supported. For example, **:focus:checked** selects the element whose **focus** and **checked** attributes are both set to **true**. The following table lists the supported single pseudo-class in descending order of priority.
In addition to a single pseudo-class, a combination of pseudo-classes is supported. For example, :focus:checked selects the element whose focus and checked attributes are both set to true. The following table lists the supported single pseudo-class in descending order of priority.
<a name="table584491515455"></a>
<table><thead align="left"><tr id="row3844171516452"><th class="cellrowborder" valign="top" width="11.42114211421142%" id="mcps1.1.4.1.1"><p id="p3844151594510"><a name="p3844151594510"></a><a name="p3844151594510"></a>Pseudo-class</p> | Pseudo-class | Available Components | Description |
</th> | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="26.162616261626166%" id="mcps1.1.4.1.2"><p id="p11844131512458"><a name="p11844131512458"></a><a name="p11844131512458"></a>Available Components</p> | :disabled | Components that support the disabled attribute | Selects the element whose disabled attribute is changed to true (unavailable for animation attributes). |
</th> | :focus | Components that support the focusable attribute | Selects the element that takes focus (unavailable for animation attributes). |
<th class="cellrowborder" valign="top" width="62.41624162416242%" id="mcps1.1.4.1.3"><p id="p78441615184511"><a name="p78441615184511"></a><a name="p78441615184511"></a>Description</p> | :active | Components that support the click event<br/> | Selects the element activated by a user. For example, a pressed button or a selected tab-bar (unavailable for animation attributes). |
</th> | :waiting | button | Selects the element whose waiting attribute is true (unavailable for animation attributes). |
</tr> | :checked | input[type="checkbox", type="radio"], and switch | Selects the element whose checked attribute is true (unavailable for animation attributes). |
</thead> | :hover<sup>6+</sup> | Components that support the mouseover event | Selects the element that the cursor is on. |
<tbody><tr id="row104936528343"><td class="cellrowborder" valign="top" width="11.42114211421142%" headers="mcps1.1.4.1.1 "><p id="p2235059193413"><a name="p2235059193413"></a><a name="p2235059193413"></a>:disabled</p>
</td> The following is an example for you to use the :active pseudo-class to control the style when a user presses the button.
<td class="cellrowborder" valign="top" width="26.162616261626166%" headers="mcps1.1.4.1.2 "><p id="p1323545943417"><a name="p1323545943417"></a><a name="p1323545943417"></a>Components that support the <strong id="b774812224211"><a name="b774812224211"></a><a name="b774812224211"></a>disabled</strong> attribute</p>
</td>
<td class="cellrowborder" valign="top" width="62.41624162416242%" headers="mcps1.1.4.1.3 "><p id="p10235155912344"><a name="p10235155912344"></a><a name="p10235155912344"></a>Selects the element whose <strong id="b661616306815"><a name="b661616306815"></a><a name="b661616306815"></a>disabled</strong> attribute is changed to <strong id="b9301136081"><a name="b9301136081"></a><a name="b9301136081"></a>true</strong> (unavailable for animation attributes).</p>
</td>
</tr>
<tr id="row0844121554510"><td class="cellrowborder" valign="top" width="11.42114211421142%" headers="mcps1.1.4.1.1 "><p id="p138441015144512"><a name="p138441015144512"></a><a name="p138441015144512"></a>:active</p>
</td>
<td class="cellrowborder" valign="top" width="26.162616261626166%" headers="mcps1.1.4.1.2 "><p id="p1184441511457"><a name="p1184441511457"></a><a name="p1184441511457"></a><span id="ph32264934610"><a name="ph32264934610"></a><a name="ph32264934610"></a>Components that support the click event</span></p>
</td>
<td class="cellrowborder" valign="top" width="62.41624162416242%" headers="mcps1.1.4.1.3 "><p id="p1384471516454"><a name="p1384471516454"></a><a name="p1384471516454"></a>Selects the element activated by a user. For example, a pressed button<span id="ph1265519710112"><a name="ph1265519710112"></a><a name="ph1265519710112"></a> or a selected <strong id="b1655321419203"><a name="b1655321419203"></a><a name="b1655321419203"></a>tab-bar</strong> (unavailable for animation attributes)</span>. </p>
</td>
</tr>
<tr id="row12925340193519"><td class="cellrowborder" valign="top" width="11.42114211421142%" headers="mcps1.1.4.1.1 "><p id="p134731642153511"><a name="p134731642153511"></a><a name="p134731642153511"></a>:waiting</p>
</td>
<td class="cellrowborder" valign="top" width="26.162616261626166%" headers="mcps1.1.4.1.2 "><p id="p114732420358"><a name="p114732420358"></a><a name="p114732420358"></a>button</p>
</td>
<td class="cellrowborder" valign="top" width="62.41624162416242%" headers="mcps1.1.4.1.3 "><p id="p2473742143511"><a name="p2473742143511"></a><a name="p2473742143511"></a>Selects the element whose <strong id="b194051157192412"><a name="b194051157192412"></a><a name="b194051157192412"></a>waiting</strong> attribute is <strong id="b1621716112515"><a name="b1621716112515"></a><a name="b1621716112515"></a>true</strong><span id="ph3323185819110"><a name="ph3323185819110"></a><a name="ph3323185819110"></a> (unavailable for animation attributes)</span>.</p>
</td>
</tr>
<tr id="row1884431514452"><td class="cellrowborder" valign="top" width="11.42114211421142%" headers="mcps1.1.4.1.1 "><p id="p7844161512452"><a name="p7844161512452"></a><a name="p7844161512452"></a>:checked</p>
</td>
<td class="cellrowborder" valign="top" width="26.162616261626166%" headers="mcps1.1.4.1.2 "><p id="p198451215174516"><a name="p198451215174516"></a><a name="p198451215174516"></a>input[type="checkbox", type="radio"]<span id="ph55837371112"><a name="ph55837371112"></a><a name="ph55837371112"></a>, and switch</span></p>
</td>
<td class="cellrowborder" valign="top" width="62.41624162416242%" headers="mcps1.1.4.1.3 "><p id="p9845415164512"><a name="p9845415164512"></a><a name="p9845415164512"></a>Selects the element whose <strong id="b23456295288"><a name="b23456295288"></a><a name="b23456295288"></a>checked</strong> attribute is <strong id="b734692962814"><a name="b734692962814"></a><a name="b734692962814"></a>true</strong><span id="ph879324710523"><a name="ph879324710523"></a><a name="ph879324710523"></a> (unavailable for animation attributes)</span>. </p>
</td>
</tr>
</tbody>
</table>
The following is an example for you to use the **:active** pseudo-class to control the style when a user presses the button.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -212,6 +151,7 @@ The following is an example for you to use the **:active** pseudo-class to con ...@@ -212,6 +151,7 @@ The following is an example for you to use the **:active** pseudo-class to con
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.button:active { .button:active {
...@@ -219,14 +159,15 @@ The following is an example for you to use the **:active** pseudo-class to con ...@@ -219,14 +159,15 @@ The following is an example for you to use the **:active** pseudo-class to con
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>Pseudo-classes are not supported for the **<popup\>** component and its child components, including, **<dialog\>**, **<menu\>**, **<option\>**, and **<picker\>**. > Pseudo-classes are not supported for the <popup> component and its child components, including, <dialog>, <menu>, <option>, and <picker>.
## Precompiled Styles<a name="section1690162216454"></a> ## Precompiled Styles
Precompilation is a program that uses specific syntax to generate CSS files. It provides variables and calculation, helping you define component styles more conveniently. Currently, Less, Sass, and Scss are supported. To use precompiled styles, change the suffix of the original **.css** file. For example, change **index.css** to **index.less**, **index.sass**, or **index.scss**. Precompilation is a program that uses specific syntax to generate CSS files. It provides variables and calculation, helping you define component styles more conveniently. Currently, Less, Sass, and Scss are supported. To use precompiled styles, change the suffix of the original .css file. For example, change index.css to index.less, index.sass, or index.scss.
- The following **index.less** file is changed from **index.css**. - The following index.less file is changed from index.css.
``` ```
/* index.less */ /* index.less */
...@@ -237,8 +178,7 @@ Precompilation is a program that uses specific syntax to generate CSS files. It ...@@ -237,8 +178,7 @@ Precompilation is a program that uses specific syntax to generate CSS files. It
} }
``` ```
- Reference a precompiled style file. For example, if the style.scss file is located in the common directory, change the original index.css file to index.scss and import style.scss.
- Reference a precompiled style file. For example, if the **style.scss** file is located in the **common** directory, change the original **index.css** file to **index.scss** and import **style.scss**.
``` ```
/* style.scss */ /* style.scss */
...@@ -246,7 +186,8 @@ Precompilation is a program that uses specific syntax to generate CSS files. It ...@@ -246,7 +186,8 @@ Precompilation is a program that uses specific syntax to generate CSS files. It
$colorBackground: #000000; $colorBackground: #000000;
``` ```
Reference the precompiled style file in **index.scss**: Reference the precompiled style file in index.scss:
``` ```
/* index.scss */ /* index.scss */
...@@ -257,21 +198,28 @@ Precompilation is a program that uses specific syntax to generate CSS files. It ...@@ -257,21 +198,28 @@ Precompilation is a program that uses specific syntax to generate CSS files. It
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Place precompiled style files in the **common** directory.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> Place precompiled style files in the common directory.
## CSS Style Inheritance<sup>6+</sup><a name="section11758912154910"></a> ## CSS Style Inheritance<sup>6+</sup>
CSS style inheritance enables a child node to inherit the style of its parent node. The inherited style has the lowest priority when multiple style selectors are involved. Currently, the following styles can be inherited: CSS style inheritance enables a child node to inherit the style of its parent node. The inherited style has the lowest priority when multiple style selectors are involved. Currently, the following styles can be inherited:
- font-family - font-family
- font-weight - font-weight
- font-size - font-size
- font-style - font-style
- text-align - text-align
- line-height - line-height
- letter-spacing - letter-spacing
- color - color
- visibility
- visibility
# HML<a name="EN-US_TOPIC_0000001127284830"></a> # HML
The OpenHarmony Markup Language \(HML\) 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 logic control, data binding, event binding, loop rendering, and conditional rendering.
## HML Page Structure<a name="section1062764791514"></a> The OpenHarmony Markup Language (HML) 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 logic control, data binding, event binding, loop rendering, and conditional rendering.
## HML Page Structure
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -14,7 +17,9 @@ The OpenHarmony Markup Language \(HML\) is an HTML-like language that allows you ...@@ -14,7 +17,9 @@ The OpenHarmony Markup Language \(HML\) is an HTML-like language that allows you
</div> </div>
``` ```
## Data Binding<a name="s8821c158917c48098219013e69129d1b"></a>
## Data Binding
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -23,6 +28,7 @@ The OpenHarmony Markup Language \(HML\) is an HTML-like language that allows you ...@@ -23,6 +28,7 @@ The OpenHarmony Markup Language \(HML\) is an HTML-like language that allows you
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -35,18 +41,21 @@ export default { ...@@ -35,18 +41,21 @@ export default {
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- To make the array data modification take effect, use the **splice** method to change array items. > - To make the array data modification take effect, use the splice method to change array items.
>- ECMAScript 6 \(ES6\) syntax is not supported in HML. >
> - ECMAScript 6 (ES6) syntax is not supported in HML.
## Common Event Binding<a name="section193010312423"></a>
Events are bound to components through **'on'** or **'@'**. When a component triggers an event, the corresponding event processing function in the **.js** file is executed. ## Common Event Binding
Events are bound to components through 'on' or '@'. When a component triggers an event, the corresponding event processing function in the .js file is executed.
Events can be written in the following formats: Events can be written in the following formats:
- **funcName**: name of the event callback, which is implemented by defining the corresponding function in the **.js** file. - funcName: name of the event callback, which is implemented by defining the corresponding function in the .js file.
- **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.
- 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.
- Example - Example
...@@ -65,6 +74,7 @@ Events can be written in the following formats: ...@@ -65,6 +74,7 @@ Events can be written in the following formats:
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -83,6 +93,7 @@ Events can be written in the following formats: ...@@ -83,6 +93,7 @@ Events can be written in the following formats:
}; };
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -117,16 +128,15 @@ Events can be written in the following formats: ...@@ -117,16 +128,15 @@ Events can be written in the following formats:
``` ```
## Bubbling Event Binding<sup>5+</sup><a name="section368561455815"></a> ## Bubbling Event Binding<sup>5+</sup>
Bubbling event binding covers the following: Bubbling event binding covers the following:
- Bind an event callback for event bubbling: **on:\{event\}.bubble**. **on:\{event\}** is equivalent to **on:\{event\}.bubble**. - Bind an event callback for event bubbling: on:{event}.bubble. on:{event} is equivalent to on:{event}.bubble.
- Bind an event callback, but stop the event from bubbling upwards: **grab:\{event\}.bubble**. **grab:\{event\}** is equivalent to **grab:\{event\}.bubble**.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>For details about bubbling events, see [Universal Events](../reference/arkui-js/js-components-common-events.md).
- Bind an event callback, but stop the event from bubbling upwards: grab:{event}.bubble. grab:{event} is equivalent to grab:{event}.bubble.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> For details about bubbling events, see [Universal Events](../reference/arkui-js/js-components-common-events.md)
- Example - Example
...@@ -148,6 +158,7 @@ Bubbling event binding covers the following: ...@@ -148,6 +158,7 @@ Bubbling event binding covers the following:
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -160,31 +171,31 @@ Bubbling event binding covers the following: ...@@ -160,31 +171,31 @@ Bubbling event binding covers the following:
} }
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> Events bound using a traditional statement (such as onclick) will bubble only when the API version in use is 6 or later.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Capturing Event Binding<sup>5+</sup>
>Events bound using a traditional statement \(such as **onclick**\) will bubble only when the API version in use is 6 or later.
## Capturing Event Binding<sup>5+</sup><a name="section5527539989"></a>
Touch events can be captured. In the capture phase, which precedes the bubbling phase, an event starts from the parent component to the child component. Touch events can be captured. In the capture phase, which precedes the bubbling phase, an event starts from the parent component to the child component.
Event capturing binding includes: Event capturing binding includes:
- Bind an event callback for event capturing: **on:\{event\}.capture**. - Bind an event callback for event capturing: on:{event}.capture.
- Bind an event callback, but stop the event from being captured during downward transfer: **grab:\{event\}.capture**.
- Bind an event callback, but stop the event from being captured during downward transfer: grab:{event}.capture.
- Example - Example
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div> <div>
<!-- Bind an event callback for event capturing.5+ --> <!-- Bind an event callback for event capturing.5+ --> <div on:touchstart.capture="touchstartfunc"></div>
<div on:touchstart.capture="touchstartfunc"></div>
<!-- Bind an event callback, but stop the event from being captured during downward transfer.5+ --> <!-- Bind an event callback, but stop the event from being captured during downward transfer.5+ -->
<div grab:touchstart.capture="touchstartfunc"></div> <div grab:touchstart.capture="touchstartfunc"></div>
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -195,7 +206,8 @@ Event capturing binding includes: ...@@ -195,7 +206,8 @@ Event capturing binding includes:
``` ```
## Loop Rendering<a name="sb777d6d807fa43fea9be400b2600425b"></a> ## Loop Rendering
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -216,6 +228,7 @@ Event capturing binding includes: ...@@ -216,6 +228,7 @@ Event capturing binding includes:
</div> </div>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -235,24 +248,30 @@ export default { ...@@ -235,24 +248,30 @@ export default {
} }
``` ```
The **tid** attribute accelerates the **for** loop and improves the re-rendering efficiency when data in a loop changes. The tid attribute accelerates the for loop and improves the re-rendering efficiency when data in a loop changes.
The tid attribute 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:
- for="array": array is an array object, whose element variable is $item by default.
The **tid** attribute 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. - for="v in array": v is a custom element variable, whose index is $idx by default.
The **for** loop supports the following statements: - 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.
- for="array": **array** is an array object, whose element variable is **$item** by default. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
- for="v in array": **v** is a custom element variable, whose index is **$idx** by default. > - Each element in the array must have the data attribute specified by tid. Otherwise, an exception may occur.
- 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. >
> - 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.
>
> - The tid field does not support expressions.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- Each element in the array must have the data attribute specified by **tid**. Otherwise, an exception may occur.
>- 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.
>- The **tid** field does not support expressions.
## Conditional Rendering<a name="sf7f6eab2105a4030a1f34149417d6fc5"></a> ## Conditional Rendering
There 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:
There 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:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -265,6 +284,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or ** ...@@ -265,6 +284,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or **
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
...@@ -278,6 +298,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or ** ...@@ -278,6 +298,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or **
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -294,7 +315,8 @@ export default { ...@@ -294,7 +315,8 @@ export default {
} }
``` ```
In the optimized rendering \(**show**\), if **show** is **true**, the node is rendered properly; if it is **false**, the display style will be **none**. In the optimized rendering (show), if show is true, the node is rendered properly; if it is false, the display style will be none.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -304,6 +326,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is ...@@ -304,6 +326,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
...@@ -317,6 +340,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is ...@@ -317,6 +340,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -329,12 +353,13 @@ export default { ...@@ -329,12 +353,13 @@ export default {
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>Do not use **for** and **if** attributes at the same time in an element. > Do not use for and if attributes at the same time in an element.
## Logic Control Block<a name="s185169def14340fcbb12c3375cb0f0bb"></a> ## Logic Control Block
<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.
**<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.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -352,6 +377,7 @@ export default { ...@@ -352,6 +377,7 @@ export default {
</list> </list>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -364,9 +390,10 @@ export default { ...@@ -364,9 +390,10 @@ export default {
} }
``` ```
## Template Reference<a name="section1388145672114"></a> ## Template Reference
HML supports using elements to reference template files. For details, see Custom Components.
HML supports using elements to reference template files. For details, see [Custom Components](../reference/arkui-js/js-components-custom.md).
``` ```
<!-- template.hml --> <!-- template.hml -->
...@@ -376,6 +403,7 @@ HML supports using elements to reference template files. For details, see [Cust ...@@ -376,6 +403,7 @@ HML supports using elements to reference template files. For details, see [Cust
</div> </div>
``` ```
``` ```
<!-- index.hml --> <!-- index.hml -->
<element name='comp' src='../../common/template.hml'></element> <element name='comp' src='../../common/template.hml'></element>
...@@ -383,4 +411,3 @@ HML supports using elements to reference template files. For details, see [Cust ...@@ -383,4 +411,3 @@ HML supports using elements to reference template files. For details, see [Cust
<comp name="Tony" age="18"></comp> <comp name="Tony" age="18"></comp>
</div> </div>
``` ```
# JavaScript<a name="EN-US_TOPIC_0000001173164729"></a> # JavaScript
You can use a **.js** file to define the service logic of an HML page. The JS UI framework supports the JavaScript language that conforms to the ECMAScript specification. With dynamic typing, JavaScript can make your application more expressive with a flexible design. The following describes the JavaScript compilation and running.
## Syntax<a name="s6ca2e99746664509961f65b82d11ab58"></a> You 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.
The ES6 syntax is supported.
- **Module declaration** ## Syntax
The ES6 syntax is supported.
- Module declaration
Import functionality modules. Import functionality modules.
``` ```
import router from '@system.router'; import router from '@system.router';
``` ```
- **Code reference** - Code reference
Import JavaScript code. Import JavaScript code.
``` ```
import utils from '../../common/utils.js'; import utils from '../../common/utils.js';
``` ```
## Objects<a name="s7493791622a248fbb2e03703149bb3b5"></a> ## Objects
- **Application Object** - Application Object
| Attribute | Type | Description |
<a name="tc5261f21b7014f6cbe17d3ef51b9e1a9"></a> | -------- | -------- | -------- |
<table><thead align="left"><tr id="r03f71ea1fd1245fd80e907a22a315e99"><th class="cellrowborder" valign="top" width="8.63%" id="mcps1.1.4.1.1"><p id="ae816119c3e0143c892512012c7927037"><a name="ae816119c3e0143c892512012c7927037"></a><a name="ae816119c3e0143c892512012c7927037"></a>Attribute</p> | $def | Object | Object that is exposed in the app.js file and obtained by this.$app.$def.<br/>> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:<br/>> Application objects do not support data binding. Data update should be triggered on the UI. |
</th>
<th class="cellrowborder" valign="top" width="9.370000000000001%" id="mcps1.1.4.1.2"><p id="ab72e901bb3ef4657b303513b8fa5ec1f"><a name="ab72e901bb3ef4657b303513b8fa5ec1f"></a><a name="ab72e901bb3ef4657b303513b8fa5ec1f"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="82%" id="mcps1.1.4.1.3"><p id="ae95f3df496fc41939ac6c1cf74aef9d8"><a name="ae95f3df496fc41939ac6c1cf74aef9d8"></a><a name="ae95f3df496fc41939ac6c1cf74aef9d8"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="r170881741fb347fa9bc5ac3a33382a9b"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="a9a70780b9fd8468d98a7c107ee67d8d8"><a name="a9a70780b9fd8468d98a7c107ee67d8d8"></a><a name="a9a70780b9fd8468d98a7c107ee67d8d8"></a>$def</p>
</td>
<td class="cellrowborder" valign="top" width="9.370000000000001%" headers="mcps1.1.4.1.2 "><p id="ace202d9f2dd547c8ab8693954af5d616"><a name="ace202d9f2dd547c8ab8693954af5d616"></a><a name="ace202d9f2dd547c8ab8693954af5d616"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="82%" headers="mcps1.1.4.1.3 "><p id="a08a4d55b01864b2fa866f6431cd322de"><a name="a08a4d55b01864b2fa866f6431cd322de"></a><a name="a08a4d55b01864b2fa866f6431cd322de"></a>Object that is exposed in the <strong id="b1245054215141"><a name="b1245054215141"></a><a name="b1245054215141"></a>app.js</strong> file and obtained by <strong id="b466541113154"><a name="b466541113154"></a><a name="b466541113154"></a>this.$app.$def</strong>.</p>
<div class="note" id="note23038122918"><a name="note23038122918"></a><a name="note23038122918"></a><span class="notetitle"> NOTE: </span><div class="notebody"><p id="p73038121790"><a name="p73038121790"></a><a name="p73038121790"></a>Application objects do not support data binding. Data update should be triggered on the UI.</p>
</div></div>
</td>
</tr>
</tbody>
</table>
Example Code Example Code
``` ```
// app.js // app.js
export default { export default {
onCreate() { onCreate() {
console.info('Application onCreate'); console.info('AceApplication onCreate');
}, },
onDestroy() { onDestroy() {
console.info('Application onDestroy'); console.info('AceApplication onDestroy');
}, },
globalData: { globalData: {
appData: 'appData', appData: 'appData',
...@@ -70,6 +55,7 @@ The ES6 syntax is supported. ...@@ -70,6 +55,7 @@ The ES6 syntax is supported.
}; };
``` ```
``` ```
// index.js // index.js
export default { export default {
...@@ -90,101 +76,29 @@ The ES6 syntax is supported. ...@@ -90,101 +76,29 @@ The ES6 syntax is supported.
} }
``` ```
- **Page objects** - Page objects
| Attribute | Type | Description |
<a name="table8514281151"></a> | -------- | -------- | -------- |
<table><thead align="left"><tr id="row2511928359"><th class="cellrowborder" valign="top" width="8.63%" id="mcps1.1.4.1.1"><p id="p1951028754"><a name="p1951028754"></a><a name="p1951028754"></a>Attribute</p> | 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. |
</th> | $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). |
<th class="cellrowborder" valign="top" width="10.71%" id="mcps1.1.4.1.2"><p id="p1351228252"><a name="p1351228252"></a><a name="p1351228252"></a>Type</p> | private | Object | Data model of the page. Private data attribute can be modified only on the current page. |
</th> | public | Object | Data model of the page. Behaviors of public data attributes are the same as those of the data attribute. |
<th class="cellrowborder" valign="top" width="80.66%" id="mcps1.1.4.1.3"><p id="p651112815519"><a name="p651112815519"></a><a name="p651112815519"></a>Description</p> | 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 [Custom Component](../reference/arkui-js/js-components-custom-props.md). |
</th> | 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 [Custom Component](../reference/arkui-js/js-components-custom-props.md). |
</tr>
</thead> ## Functions
<tbody><tr id="row1651228855"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p115421323762"><a name="p115421323762"></a><a name="p115421323762"></a>data</p>
</td> - Data functions
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p05120283516"><a name="p05120283516"></a><a name="p05120283516"></a>Object/Function</p> | Function | Parameter | Description |
</td> | -------- | -------- | -------- |
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p61056578507"><a name="p61056578507"></a><a name="p61056578507"></a>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 (<strong id="b430716571284"><a name="b430716571284"></a><a name="b430716571284"></a>for</strong>, <strong id="b1341785992814"><a name="b1341785992814"></a><a name="b1341785992814"></a>if</strong>, <strong id="b11287152152914"><a name="b11287152152914"></a><a name="b11287152152914"></a>show</strong>, and <strong id="b15341857297"><a name="b15341857297"></a><a name="b15341857297"></a>tid</strong>).</p> | $set | key: string, value: any | Adds an attribute or modifies an existing attribute.<br/>Usage:<br/>this.$set('_key_',_value_): Add an attribute. |
<p id="p95116281350"><a name="p95116281350"></a><a name="p95116281350"></a>Do not use this attribute and <strong id="b166710411103"><a name="b166710411103"></a><a name="b166710411103"></a>private</strong> or <strong id="b3689175611101"><a name="b3689175611101"></a><a name="b3689175611101"></a>public</strong> at the same time.</p> | $delete | key: string | Deletes an attribute.<br/>Usage:<br/>this.$delete('_key_'): Delete an attribute. |
</td>
</tr>
<tr id="row2991343201512"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p1873818536545"><a name="p1873818536545"></a><a name="p1873818536545"></a>$refs</p>
</td>
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p1073815318541"><a name="p1073815318541"></a><a name="p1073815318541"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p7879941512"><a name="p7879941512"></a><a name="p7879941512"></a>DOM elements or child component instances that have registered the <strong id="b230018334315"><a name="b230018334315"></a><a name="b230018334315"></a>ref</strong> attribute. For example code, see <a href="#section1560185062215">Obtaining a DOM element</a>.</p>
</td>
</tr>
<tr id="row340610191094"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p240712191998"><a name="p240712191998"></a><a name="p240712191998"></a>private</p>
</td>
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p1840710194916"><a name="p1840710194916"></a><a name="p1840710194916"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p17407161911917"><a name="p17407161911917"></a><a name="p17407161911917"></a>Data model of the page. Private data attribute can be modified only on the current page.</p>
</td>
</tr>
<tr id="row594316386514"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p99441138554"><a name="p99441138554"></a><a name="p99441138554"></a>public</p>
</td>
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p994419381151"><a name="p994419381151"></a><a name="p994419381151"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p2094418381153"><a name="p2094418381153"></a><a name="p2094418381153"></a>Data model of the page. Behaviors of public data attributes are the same as those of the <strong id="b17852928193814"><a name="b17852928193814"></a><a name="b17852928193814"></a>data</strong> attribute.</p>
</td>
</tr>
<tr id="row638815278598"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p139903755910"><a name="p139903755910"></a><a name="p139903755910"></a>props</p>
</td>
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p4258153555911"><a name="p4258153555911"></a><a name="p4258153555911"></a>Array/Object</p>
</td>
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p12388227105918"><a name="p12388227105918"></a><a name="p12388227105918"></a>Used for communication between components. This attribute can be transferred to components via <strong id="b1374684104018"><a name="b1374684104018"></a><a name="b1374684104018"></a>&lt;tag xxxx='value'&gt;</strong>. A <strong id="b967863454012"><a name="b967863454012"></a><a name="b967863454012"></a>props</strong> name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (<strong id="b36181719414"><a name="b36181719414"></a><a name="b36181719414"></a>for</strong>, <strong id="b18297336418"><a name="b18297336418"></a><a name="b18297336418"></a>if</strong>, <strong id="b350916444117"><a name="b350916444117"></a><a name="b350916444117"></a>show</strong>, and <strong id="b123692654113"><a name="b123692654113"></a><a name="b123692654113"></a>tid</strong>). Currently, <strong id="b1660371715416"><a name="b1660371715416"></a><a name="b1660371715416"></a>props</strong> does not support functions. For details, see <a href="../nottoctopics/en-us_topic_0000001173164675.md">Custom Components</a>.</p>
</td>
</tr>
<tr id="row14421201293417"><td class="cellrowborder" valign="top" width="8.63%" headers="mcps1.1.4.1.1 "><p id="p144221012173416"><a name="p144221012173416"></a><a name="p144221012173416"></a>computed</p>
</td>
<td class="cellrowborder" valign="top" width="10.71%" headers="mcps1.1.4.1.2 "><p id="p164221412163412"><a name="p164221412163412"></a><a name="p164221412163412"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="80.66%" headers="mcps1.1.4.1.3 "><p id="p6422712153413"><a name="p6422712153413"></a><a name="p6422712153413"></a>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 <a href="../nottoctopics/en-us_topic_0000001173164675.md">Custom Components</a>.</p>
</td>
</tr>
</tbody>
</table>
## Functions<a name="s4e1ff24ec78e41948502d8977d24e44c"></a>
- **Data functions**
<a name="td998a97f34c44c86876d2e1aee646bc6"></a>
<table><thead align="left"><tr id="r41906fbf818041e089ab60c9d410de72"><th class="cellrowborder" valign="top" width="11.361136113611362%" id="mcps1.1.4.1.1"><p id="a44385457c0224b7aa0af4b8aaa5fec41"><a name="a44385457c0224b7aa0af4b8aaa5fec41"></a><a name="a44385457c0224b7aa0af4b8aaa5fec41"></a>Function</p>
</th>
<th class="cellrowborder" valign="top" width="16.53165316531653%" id="mcps1.1.4.1.2"><p id="a21e0645662414f9893af7ff3a6e24e92"><a name="a21e0645662414f9893af7ff3a6e24e92"></a><a name="a21e0645662414f9893af7ff3a6e24e92"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="72.10721072107211%" id="mcps1.1.4.1.3"><p id="add5a5e57df3a4d47a09a8f3ef2a28088"><a name="add5a5e57df3a4d47a09a8f3ef2a28088"></a><a name="add5a5e57df3a4d47a09a8f3ef2a28088"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="rcba2037b58704ed9bef75b912b96eb80"><td class="cellrowborder" valign="top" width="11.361136113611362%" headers="mcps1.1.4.1.1 "><p id="a75bccc07529343469aad71db98e70b1a"><a name="a75bccc07529343469aad71db98e70b1a"></a><a name="a75bccc07529343469aad71db98e70b1a"></a>$set</p>
</td>
<td class="cellrowborder" valign="top" width="16.53165316531653%" headers="mcps1.1.4.1.2 "><p id="a53419b7e4fde4993b3ab35ad3312c4da"><a name="a53419b7e4fde4993b3ab35ad3312c4da"></a><a name="a53419b7e4fde4993b3ab35ad3312c4da"></a>key: string, value: any</p>
</td>
<td class="cellrowborder" valign="top" width="72.10721072107211%" headers="mcps1.1.4.1.3 "><p id="p84781851442"><a name="p84781851442"></a><a name="p84781851442"></a>Adds an attribute or modifies an existing attribute.</p>
<p id="ae55e2b1d9401454c8555cbb419068829"><a name="ae55e2b1d9401454c8555cbb419068829"></a><a name="ae55e2b1d9401454c8555cbb419068829"></a>Usage:</p>
<p id="a266dfd3b1b384811b4e7d9a39350e3bc"><a name="a266dfd3b1b384811b4e7d9a39350e3bc"></a><a name="a266dfd3b1b384811b4e7d9a39350e3bc"></a><strong id="b102214303161"><a name="b102214303161"></a><a name="b102214303161"></a>this.$set('</strong><em id="i153502112176"><a name="i153502112176"></a><a name="i153502112176"></a>key</em><strong id="b4382163315169"><a name="b4382163315169"></a><a name="b4382163315169"></a>',</strong><em id="i1278985981612"><a name="i1278985981612"></a><a name="i1278985981612"></a>value</em><strong id="b14689536171618"><a name="b14689536171618"></a><a name="b14689536171618"></a>)</strong>: Add an attribute.</p>
</td>
</tr>
<tr id="r189d027189d842a1baf1a5d91a9af901"><td class="cellrowborder" valign="top" width="11.361136113611362%" headers="mcps1.1.4.1.1 "><p id="a4ee9a900fc454f66a628f210f2e50548"><a name="a4ee9a900fc454f66a628f210f2e50548"></a><a name="a4ee9a900fc454f66a628f210f2e50548"></a>$delete</p>
</td>
<td class="cellrowborder" valign="top" width="16.53165316531653%" headers="mcps1.1.4.1.2 "><p id="a2e9d28b0f19d4cabbcc1b464bbd9993a"><a name="a2e9d28b0f19d4cabbcc1b464bbd9993a"></a><a name="a2e9d28b0f19d4cabbcc1b464bbd9993a"></a>key: string</p>
</td>
<td class="cellrowborder" valign="top" width="72.10721072107211%" headers="mcps1.1.4.1.3 "><p id="p18897453134313"><a name="p18897453134313"></a><a name="p18897453134313"></a>Deletes an attribute.</p>
<p id="a1e9c2271da5e4cd89dcd6b73c1b3b69d"><a name="a1e9c2271da5e4cd89dcd6b73c1b3b69d"></a><a name="a1e9c2271da5e4cd89dcd6b73c1b3b69d"></a>Usage:</p>
<p id="a628cc2f32b9247b091f5d37ab0a58fdb"><a name="a628cc2f32b9247b091f5d37ab0a58fdb"></a><a name="a628cc2f32b9247b091f5d37ab0a58fdb"></a><strong id="b14701107171715"><a name="b14701107171715"></a><a name="b14701107171715"></a>this.$delete('</strong><em id="i2460141971715"><a name="i2460141971715"></a><a name="i2460141971715"></a>key</em><strong id="b121011116141712"><a name="b121011116141712"></a><a name="b121011116141712"></a>')</strong>: Delete an attribute.</p>
</td>
</tr>
</tbody>
</table>
Example Code Example Code
``` ```
// index.js
export default { export default {
data: { data: {
keyMap: { keyMap: {
...@@ -202,178 +116,47 @@ The ES6 syntax is supported. ...@@ -202,178 +116,47 @@ The ES6 syntax is supported.
} }
``` ```
- **Public functions** - Public functions
| Function | Parameter | Description |
<a name="te12ef71dd85347738d3670aaa9934476"></a> | -------- | -------- | -------- |
<table><thead align="left"><tr id="r7c071c236183461dbd8e78bce0073401"><th class="cellrowborder" valign="top" width="13.469999999999999%" id="mcps1.1.4.1.1"><p id="a4abb4994ac12403f88c36b8b34a739ec"><a name="a4abb4994ac12403f88c36b8b34a739ec"></a><a name="a4abb4994ac12403f88c36b8b34a739ec"></a>Function</p> | $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. |
</th> | $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. |
<th class="cellrowborder" valign="top" width="18.91%" id="mcps1.1.4.1.2"><p id="aeac2f3bdee564731ace449ab67008c2c"><a name="aeac2f3bdee564731ace449ab67008c2c"></a><a name="aeac2f3bdee564731ace449ab67008c2c"></a>Parameter</p> | $root | N/A | Obtains the root ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). |
</th> | $parent | N/A | Obtains the parent ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). |
<th class="cellrowborder" valign="top" width="67.62%" id="mcps1.1.4.1.3"><p id="af669c9f192954747ba61f011dcb6b1c7"><a name="af669c9f192954747ba61f011dcb6b1c7"></a><a name="af669c9f192954747ba61f011dcb6b1c7"></a>Description</p> | $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_. |
</th>
</tr> - Event function
</thead> | Function | Parameter | Description |
<tbody><tr id="r786add9633394d2f8d72020f28465c87"><td class="cellrowborder" valign="top" width="13.469999999999999%" headers="mcps1.1.4.1.1 "><p id="a6cce84705d514809ac0511d69f5605e1"><a name="a6cce84705d514809ac0511d69f5605e1"></a><a name="a6cce84705d514809ac0511d69f5605e1"></a>$element</p> | -------- | -------- | -------- |
</td> | $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 [Custom Component](../reference/arkui-js/js-components-custom-props.md)<br/>Usage:<br/>this.$watch('_key_',_callback_) |
<td class="cellrowborder" valign="top" width="18.91%" headers="mcps1.1.4.1.2 "><p id="ad13b3f17bec14af0859875ac75376e14"><a name="ad13b3f17bec14af0859875ac75376e14"></a><a name="ad13b3f17bec14af0859875ac75376e14"></a>id: string</p>
</td> - Page function
<td class="cellrowborder" valign="top" width="67.62%" headers="mcps1.1.4.1.3 "><p id="p103681425164412"><a name="p103681425164412"></a><a name="p103681425164412"></a>Obtains the component with a specified ID. If no ID is specified, the root component is returned. For example code, see <a href="#section1560185062215">Obtaining a DOM element</a>.</p> | Function | Parameter | Description |
<p id="a49e65fad6f094d049706c2514e8a47a9"><a name="a49e65fad6f094d049706c2514e8a47a9"></a><a name="a49e65fad6f094d049706c2514e8a47a9"></a>Usage:</p> | -------- | -------- | -------- |
<p id="a7e59962ba3154456be9a71581364ce92"><a name="a7e59962ba3154456be9a71581364ce92"></a><a name="a7e59962ba3154456be9a71581364ce92"></a><strong id="b1778371312186"><a name="b1778371312186"></a><a name="b1778371312186"></a>&lt;div id='</strong><em id="i9616171712187"><a name="i9616171712187"></a><a name="i9616171712187"></a>xxx</em><strong id="b18768154181"><a name="b18768154181"></a><a name="b18768154181"></a>'&gt;&lt;/div&gt;</strong></p> | 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. |
<a name="u338f4836774844dcbeba6ee5218a1151"></a><a name="u338f4836774844dcbeba6ee5218a1151"></a><ul id="u338f4836774844dcbeba6ee5218a1151"><li><strong id="b05751419837"><a name="b05751419837"></a><a name="b05751419837"></a>this.$element('</strong><em id="i189720245314"><a name="i189720245314"></a><a name="i189720245314"></a>xxx</em><strong id="b2658122119319"><a name="b2658122119319"></a><a name="b2658122119319"></a>')</strong>: Obtain the component whose ID is <em id="i195201110185318"><a name="i195201110185318"></a><a name="i195201110185318"></a>xxx</em>.</li><li><strong id="b1029113281236"><a name="b1029113281236"></a><a name="b1029113281236"></a>this.$element()</strong>: Obtain the root component.</li></ul>
</td> Table1 ScrollPageParam<sup>6+</sup>
</tr>
<tr id="row1276482485914"><td class="cellrowborder" valign="top" width="13.469999999999999%" headers="mcps1.1.4.1.1 "><p id="p476514248597"><a name="p476514248597"></a><a name="p476514248597"></a>$rootElement</p> | Name | Type | Default Value | Description |
</td> | -------- | -------- | -------- | -------- |
<td class="cellrowborder" valign="top" width="18.91%" headers="mcps1.1.4.1.2 "><p id="p107653240596"><a name="p107653240596"></a><a name="p107653240596"></a>None</p> | position | number | - | Position to scroll to. |
</td> | id | string | - | ID of the element to be scrolled to. |
<td class="cellrowborder" valign="top" width="67.62%" headers="mcps1.1.4.1.3 "><p id="p137655241599"><a name="p137655241599"></a><a name="p137655241599"></a>Obtains the root element.</p> | duration | number | 300 | Scrolling duration, in milliseconds. |
<p id="p0499149904"><a name="p0499149904"></a><a name="p0499149904"></a>Usage: this.$rootElement().scrollTo({ duration: 500, position: 300 }), which scrolls the page by 300 px within 500 ms.</p> | timingFunction | string | ease | Animation curve for scrolling. Available option:<br/>[Animation Styles](../reference/arkui-js/js-components-common-animation.md) |
</td> | complete | () => void | - | Callback to be invoked when the scrolling is complete. |
</tr>
<tr id="re1d5191790fb423282a8c381b317e0e6"><td class="cellrowborder" valign="top" width="13.469999999999999%" headers="mcps1.1.4.1.1 "><p id="a87cad2551d564814a85a0459673a967c"><a name="a87cad2551d564814a85a0459673a967c"></a><a name="a87cad2551d564814a85a0459673a967c"></a>$root</p>
</td>
<td class="cellrowborder" valign="top" width="18.91%" headers="mcps1.1.4.1.2 "><p id="aad1f4153e71544fb8b4e25d08e3787ca"><a name="aad1f4153e71544fb8b4e25d08e3787ca"></a><a name="aad1f4153e71544fb8b4e25d08e3787ca"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="67.62%" headers="mcps1.1.4.1.3 "><p id="aff829908cf8d49948c1e736e4a88e3ac"><a name="aff829908cf8d49948c1e736e4a88e3ac"></a><a name="aff829908cf8d49948c1e736e4a88e3ac"></a>Obtains the root <strong id="b4935191919418"><a name="b4935191919418"></a><a name="b4935191919418"></a>ViewModel</strong> instance. For example code, see <a href="#section13798143717421">Obtaining the ViewModel</a>.</p>
</td>
</tr>
<tr id="rd577efbcfc104ac2b5bed88fc9dd0cfb"><td class="cellrowborder" valign="top" width="13.469999999999999%" headers="mcps1.1.4.1.1 "><p id="a680ff354c19f4d67a88b6eb45203b6d4"><a name="a680ff354c19f4d67a88b6eb45203b6d4"></a><a name="a680ff354c19f4d67a88b6eb45203b6d4"></a>$parent</p>
</td>
<td class="cellrowborder" valign="top" width="18.91%" headers="mcps1.1.4.1.2 "><p id="aae2cc49b962347fba8f7dc43a1a6e072"><a name="aae2cc49b962347fba8f7dc43a1a6e072"></a><a name="aae2cc49b962347fba8f7dc43a1a6e072"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="67.62%" headers="mcps1.1.4.1.3 "><p id="af3075c6896404f13a5c93929aa713125"><a name="af3075c6896404f13a5c93929aa713125"></a><a name="af3075c6896404f13a5c93929aa713125"></a>Obtains the parent <strong id="b11983132316413"><a name="b11983132316413"></a><a name="b11983132316413"></a>ViewModel</strong> instance. For example code, see <a href="#section13798143717421">Obtaining the ViewModel</a>.</p>
</td>
</tr>
<tr id="rb96318b2fb9e4e8ea74dfb280e8fb804"><td class="cellrowborder" valign="top" width="13.469999999999999%" headers="mcps1.1.4.1.1 "><p id="a31ac11bf6d6b477cbc1fb446d5207d0d"><a name="a31ac11bf6d6b477cbc1fb446d5207d0d"></a><a name="a31ac11bf6d6b477cbc1fb446d5207d0d"></a>$child</p>
</td>
<td class="cellrowborder" valign="top" width="18.91%" headers="mcps1.1.4.1.2 "><p id="a7ea3339724db43a0b0ba574ac621f83e"><a name="a7ea3339724db43a0b0ba574ac621f83e"></a><a name="a7ea3339724db43a0b0ba574ac621f83e"></a>id: string</p>
</td>
<td class="cellrowborder" valign="top" width="67.62%" headers="mcps1.1.4.1.3 "><p id="p999210407446"><a name="p999210407446"></a><a name="p999210407446"></a>Obtains the <strong id="b39768121254"><a name="b39768121254"></a><a name="b39768121254"></a>ViewModel</strong> instance of a custom child component with a specified ID. For example code, see <a href="#section13798143717421">Obtaining the ViewModel</a>.</p>
<p id="p112537114516"><a name="p112537114516"></a><a name="p112537114516"></a>Usage:</p>
<p id="a39f9c0db073641e5bcbcfc824769ae61"><a name="a39f9c0db073641e5bcbcfc824769ae61"></a><a name="a39f9c0db073641e5bcbcfc824769ae61"></a><strong id="b1130414126616"><a name="b1130414126616"></a><a name="b1130414126616"></a>this.$child('</strong><em id="i19634170616"><a name="i19634170616"></a><a name="i19634170616"></a>xxx</em><strong id="b64849141767"><a name="b64849141767"></a><a name="b64849141767"></a>')</strong>: Obtain the <strong id="b378518252611"><a name="b378518252611"></a><a name="b378518252611"></a>ViewModel</strong> instance of a custom child component whose ID is <em id="i1521313124719"><a name="i1521313124719"></a><a name="i1521313124719"></a>xxx</em>.</p>
</td>
</tr>
</tbody>
</table>
- **Event function**
<a name="table106771249184219"></a>
<table><thead align="left"><tr id="row66781249104214"><th class="cellrowborder" valign="top" width="13.28%" id="mcps1.1.4.1.1"><p id="p15678249144218"><a name="p15678249144218"></a><a name="p15678249144218"></a>Function</p>
</th>
<th class="cellrowborder" valign="top" width="35.29%" id="mcps1.1.4.1.2"><p id="p17678049114213"><a name="p17678049114213"></a><a name="p17678049114213"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="51.43%" id="mcps1.1.4.1.3"><p id="p26786495424"><a name="p26786495424"></a><a name="p26786495424"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row267864944212"><td class="cellrowborder" valign="top" width="13.28%" headers="mcps1.1.4.1.1 "><p id="p067834919421"><a name="p067834919421"></a><a name="p067834919421"></a>$watch</p>
</td>
<td class="cellrowborder" valign="top" width="35.29%" headers="mcps1.1.4.1.2 "><p id="p11678194920424"><a name="p11678194920424"></a><a name="p11678194920424"></a>data: string, callback: string | Function</p>
</td>
<td class="cellrowborder" valign="top" width="51.43%" headers="mcps1.1.4.1.3 "><p id="p1678104913426"><a name="p1678104913426"></a><a name="p1678104913426"></a>Listens for attribute changes. If the value of the <strong id="b102761759204314"><a name="b102761759204314"></a><a name="b102761759204314"></a>data</strong> attribute changes, the bound event is triggered. For details, see <a href="../nottoctopics/en-us_topic_0000001173164675.md">Custom Components</a>.</p>
<p id="p174621629124617"><a name="p174621629124617"></a><a name="p174621629124617"></a>Usage:</p>
<p id="p1173814312460"><a name="p1173814312460"></a><a name="p1173814312460"></a><strong id="b26791338201017"><a name="b26791338201017"></a><a name="b26791338201017"></a>this.$watch('</strong><em id="i1751741018116"><a name="i1751741018116"></a><a name="i1751741018116"></a>key</em><strong id="b111878516117"><a name="b111878516117"></a><a name="b111878516117"></a>',</strong> <em id="i38794851120"><a name="i38794851120"></a><a name="i38794851120"></a>callback</em><strong id="b13989360116"><a name="b13989360116"></a><a name="b13989360116"></a>)</strong></p>
</td>
</tr>
</tbody>
</table>
- **Page function**
<a name="table4927155523714"></a>
<table><thead align="left"><tr id="row4927255113714"><th class="cellrowborder" valign="top" width="13.28%" id="mcps1.1.4.1.1"><p id="p192765520376"><a name="p192765520376"></a><a name="p192765520376"></a>Function</p>
</th>
<th class="cellrowborder" valign="top" width="35.29%" id="mcps1.1.4.1.2"><p id="p1192715550377"><a name="p1192715550377"></a><a name="p1192715550377"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="51.43%" id="mcps1.1.4.1.3"><p id="p49275555370"><a name="p49275555370"></a><a name="p49275555370"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1692716552379"><td class="cellrowborder" valign="top" width="13.28%" headers="mcps1.1.4.1.1 "><p id="p199274556371"><a name="p199274556371"></a><a name="p199274556371"></a>scrollTo<sup id="sup17224503390"><a name="sup17224503390"></a><a name="sup17224503390"></a>6+</sup></p>
</td>
<td class="cellrowborder" valign="top" width="35.29%" headers="mcps1.1.4.1.2 "><p id="p792745512375"><a name="p792745512375"></a><a name="p792745512375"></a>scrollPageParam: <a href="#table131981833173916">ScrollPageParam</a></p>
</td>
<td class="cellrowborder" valign="top" width="51.43%" headers="mcps1.1.4.1.3 "><p id="p1292735517377"><a name="p1292735517377"></a><a name="p1292735517377"></a>Scrolls the page to the target position. You can specify the position using the ID selector or scrolling distance.</p>
</td>
</tr>
</tbody>
</table>
**Table 1** ScrollPageParam<sup>6+</sup>
<a name="table131981833173916"></a>
<table><thead align="left"><tr id="row31992331399"><th class="cellrowborder" valign="top" width="30.826917308269174%" id="mcps1.2.5.1.1"><p id="p16199113383917"><a name="p16199113383917"></a><a name="p16199113383917"></a>Name</p>
</th>
<th class="cellrowborder" valign="top" width="25.45745425457454%" id="mcps1.2.5.1.2"><p id="p519953314398"><a name="p519953314398"></a><a name="p519953314398"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="12.88871112888711%" id="mcps1.2.5.1.3"><p id="p556391215143"><a name="p556391215143"></a><a name="p556391215143"></a>Default Value</p>
</th>
<th class="cellrowborder" valign="top" width="30.826917308269174%" id="mcps1.2.5.1.4"><p id="p19199163393916"><a name="p19199163393916"></a><a name="p19199163393916"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row12199173303914"><td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.1 "><p id="p8199203363916"><a name="p8199203363916"></a><a name="p8199203363916"></a>position</p>
</td>
<td class="cellrowborder" valign="top" width="25.45745425457454%" headers="mcps1.2.5.1.2 "><p id="p11991833133916"><a name="p11991833133916"></a><a name="p11991833133916"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="12.88871112888711%" headers="mcps1.2.5.1.3 "><p id="p115641312111410"><a name="p115641312111410"></a><a name="p115641312111410"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.4 "><p id="p1319943319395"><a name="p1319943319395"></a><a name="p1319943319395"></a>Position to scroll to.</p>
</td>
</tr>
<tr id="row161991633143919"><td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.1 "><p id="p41991333163919"><a name="p41991333163919"></a><a name="p41991333163919"></a>id</p>
</td>
<td class="cellrowborder" valign="top" width="25.45745425457454%" headers="mcps1.2.5.1.2 "><p id="p1619918334392"><a name="p1619918334392"></a><a name="p1619918334392"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="12.88871112888711%" headers="mcps1.2.5.1.3 "><p id="p756451219146"><a name="p756451219146"></a><a name="p756451219146"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.4 "><p id="p1419943363915"><a name="p1419943363915"></a><a name="p1419943363915"></a>ID of the element to be scrolled to.</p>
</td>
</tr>
<tr id="row191992033183919"><td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.1 "><p id="p1919993316390"><a name="p1919993316390"></a><a name="p1919993316390"></a>duration</p>
</td>
<td class="cellrowborder" valign="top" width="25.45745425457454%" headers="mcps1.2.5.1.2 "><p id="p9199183363916"><a name="p9199183363916"></a><a name="p9199183363916"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="12.88871112888711%" headers="mcps1.2.5.1.3 "><p id="p5564181218144"><a name="p5564181218144"></a><a name="p5564181218144"></a>300</p>
</td>
<td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.4 "><p id="p3199233133920"><a name="p3199233133920"></a><a name="p3199233133920"></a>Scrolling duration, in milliseconds.</p>
</td>
</tr>
<tr id="row2019933315396"><td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.1 "><p id="p13199733133915"><a name="p13199733133915"></a><a name="p13199733133915"></a>timingFunction</p>
</td>
<td class="cellrowborder" valign="top" width="25.45745425457454%" headers="mcps1.2.5.1.2 "><p id="p0199173373919"><a name="p0199173373919"></a><a name="p0199173373919"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="12.88871112888711%" headers="mcps1.2.5.1.3 "><p id="p10564171212141"><a name="p10564171212141"></a><a name="p10564171212141"></a>ease</p>
</td>
<td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.4 "><p id="p1919903313394"><a name="p1919903313394"></a><a name="p1919903313394"></a>Animation curve for scrolling. Available option:</p>
<p id="p158650537712"><a name="p158650537712"></a><a name="p158650537712"></a><a href="../nottoctopics/en-us_topic_0000001173164765.md">animation-timing-function</a></p>
</td>
</tr>
<tr id="row110635616428"><td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.1 "><p id="p6107856124211"><a name="p6107856124211"></a><a name="p6107856124211"></a>complete</p>
</td>
<td class="cellrowborder" valign="top" width="25.45745425457454%" headers="mcps1.2.5.1.2 "><p id="p20107195674214"><a name="p20107195674214"></a><a name="p20107195674214"></a>() =&gt; void</p>
</td>
<td class="cellrowborder" valign="top" width="12.88871112888711%" headers="mcps1.2.5.1.3 "><p id="p20564151211419"><a name="p20564151211419"></a><a name="p20564151211419"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="30.826917308269174%" headers="mcps1.2.5.1.4 "><p id="p1107155694210"><a name="p1107155694210"></a><a name="p1107155694210"></a>Callback to be invoked when the scrolling is complete.</p>
</td>
</tr>
</tbody>
</table>
Example: Example:
``` ```
this.$rootElement.scrollTo({position: 0}) this.$rootElement.scrollTo({position: 0})
this.$rootElement.scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void}) this.$rootElement.scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void})
``` ```
## Obtaining a DOM Element<a name="section1560185062215"></a> ## Obtaining a DOM Element
1. Use **$refs** to obtain a DOM element. 1. Use $refs to obtain a DOM element.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -382,6 +165,7 @@ The ES6 syntax is supported. ...@@ -382,6 +165,7 @@ The ES6 syntax is supported.
</div> </div>
``` ```
``` ```
// index.js // index.js
export default { export default {
...@@ -406,7 +190,7 @@ The ES6 syntax is supported. ...@@ -406,7 +190,7 @@ The ES6 syntax is supported.
}; };
``` ```
2. Call **$element** to obtain a DOM element. 2. Call $element to obtain a DOM element.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -415,6 +199,7 @@ The ES6 syntax is supported. ...@@ -415,6 +199,7 @@ The ES6 syntax is supported.
</div> </div>
``` ```
``` ```
// index.js // index.js
export default { export default {
...@@ -439,11 +224,11 @@ The ES6 syntax is supported. ...@@ -439,11 +224,11 @@ The ES6 syntax is supported.
}; };
``` ```
## Obtaining the ViewModel
## Obtaining the ViewModel<a name="section13798143717421"></a>
The following shows files of the root page: The following shows files of the root page:
``` ```
<!-- root.hml --> <!-- root.hml -->
<element name='parentComp' src='../../common/component/parent/parent.hml'></element> <element name='parentComp' src='../../common/component/parent/parent.hml'></element>
...@@ -455,6 +240,7 @@ The following shows files of the root page: ...@@ -455,6 +240,7 @@ The following shows files of the root page:
</div> </div>
``` ```
``` ```
// root.js // root.js
export default { export default {
...@@ -466,6 +252,7 @@ export default { ...@@ -466,6 +252,7 @@ export default {
Customize the parent component. Customize the parent component.
``` ```
<!-- parent.hml --> <!-- parent.hml -->
<element name='childComp' src='../child/child.hml'></element> <element name='childComp' src='../child/child.hml'></element>
...@@ -476,6 +263,7 @@ Customize the parent component. ...@@ -476,6 +263,7 @@ Customize the parent component.
</div> </div>
``` ```
``` ```
// parent.js // parent.js
export default { export default {
...@@ -495,6 +283,7 @@ export default { ...@@ -495,6 +283,7 @@ export default {
Customize the child component. Customize the child component.
``` ```
<!-- child.hml --> <!-- child.hml -->
<div class="item" onclick="textClicked"> <div class="item" onclick="textClicked">
...@@ -503,6 +292,7 @@ Customize the child component. ...@@ -503,6 +292,7 @@ Customize the child component.
</div> </div>
``` ```
``` ```
// child.js // child.js
export default { export default {
...@@ -519,4 +309,3 @@ export default { ...@@ -519,4 +309,3 @@ export default {
}, },
} }
``` ```
# Syntax<a name="EN-US_TOPIC_0000001173324683"></a>
- **[HML](js-framework-syntax-hml.md)**
- **[CSS](js-framework-syntax-css.md)**
- **[JavaScript](js-framework-syntax-js.md)**
# Framework<a name="EN-US_TOPIC_0000001127284916"></a>
- **[File Organization](js-framework-file.md)**
- **["js" Tag](js-framework-js-tag.md)**
- **[app.js](js-framework-js-file.md)**
- **[Syntax](js-framework-syntax.md)**
- **[Lifecycle](js-framework-lifecycle.md)**
- **[Resource Limitations and Access](js-framework-resource-restriction.md)**
- **[Multi-Language Capability](js-framework-multiple-languages.md)**
# About @Component<a name="EN-US_TOPIC_0000001157388845"></a>
- **[build Function](ts-function-build.md)**
- **[Custom Component Initialization](ts-custom-component-initialization.md)**
- **[Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md)**
- **[Example: Component Creation and Re-Initialization](ts-component-creation-re-initialization.md)**
...@@ -3,35 +3,35 @@ ...@@ -3,35 +3,35 @@
## Resource Definition ## Resource Definition
Application resources are defined by in the project's **resources** directory, which is organized as follows: Application resources are defined by in the project's resources directory, which is organized as follows:
- Level-1: **base** sub-directory, qualifiers sub-directories, and **rawfile** sub-directory - Level-1: base sub-directory, qualifiers sub-directories, and rawfile sub-directory
- The **base** sub-directory is a default directory. If no qualifiers sub-directories in the **resources** directory of the application match the device status, the resource file in the **base** sub-directory will be automatically referenced. - The base sub-directory is a default directory. If no qualifiers sub-directories in the resources directory of the application match the device status, the resource file in the base sub-directory will be automatically referenced.
- You need to create qualifiers sub-directories on your own. The name of a qualifiers sub-directory consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the mobile country code (MCC), mobile network code (MNC), language, script, country or region, screen orientation, device type, color mode, and screen density. The qualifiers are separated using underscores (_) or hyphens (-). - You need to create qualifiers sub-directories on your own. The name of a qualifiers sub-directory consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the mobile country code (MCC), mobile network code (MNC), language, script, country or region, screen orientation, device type, color mode, and screen density. The qualifiers are separated using underscores (_) or hyphens (-).
- When the resources in the **rawfile** sub-directory are referenced, resource files will not be matched based on the device status. You can directly store resource files in the **rawfile** sub-directory. - When the resources in the rawfile sub-directory are referenced, resource files will not be matched based on the device status. You can directly store resource files in the rawfile sub-directory.
- Level-2: resource sub-directories - Level-2: resource sub-directories
- Resource sub-directories store basic elements such as character strings, colors, and floating point numbers, and resource files such as media files. - Resource sub-directories store basic elements such as character strings, colors, and floating point numbers, and resource files such as media files.
- Supported files and resource types are listed in the table below: - Supported files and resource types are listed in the table below:
| File&nbsp;Name | Resource&nbsp;Type | | File Name | Resource Type |
| -------- | -------- | | -------- | -------- |
| color.json | Color&nbsp;resource. | | color.json | Color resource. |
| float.json | Resources&nbsp;such&nbsp;as&nbsp;spacing,&nbsp;rounded&nbsp;corners,&nbsp;and&nbsp;fonts. | | float.json | Resources such as spacing, rounded corners, and fonts. |
| string.json | String&nbsp;resource. | | string.json | String resource. |
| plural.json | String&nbsp;resource. | | plural.json | String resource. |
| media&nbsp;directory | Image&nbsp;resource. | | media directory | Image resource. |
## Referencing Resources ## Referencing Resources
To reference an application resource in a project, use the **"$r('app.type.name')"** format. **app** indicates the resource defined in the **resources** directory of the application. **type** indicates the resource type (or the location where the resource is stored). The value can be **color**, **float**, **string**, **plural**, or **media**. **name** indicates the resource name, which you set when defining the resource. To reference an application resource in a project, use the "$r('app.type.name')" format. app indicates the resource defined in the resources directory of the application. type indicates the resource type (or the location where the resource is stored). The value can be color, float, string, plural, or media. name indicates the resource name, which you set when defining the resource.
When referencing resources in the **rawfile** sub-directory, use the **"$rawfile('filename')"** format. Currently, **$rawfile** allows only the **&lt;Image&gt;** component to reference image resources. In the format, **filename** indicates the relative path of a file in the **rawfile** directory, and the file name must contain the file name extension. Note that the relative path cannot start with a slash (/). When referencing resources in the rawfile sub-directory, use the "$rawfile('filename')" format. Currently, $rawfile allows only the <Image> component to reference image resources. In the format, filename indicates the relative path of a file in the rawfile directory, and the file name must contain the file name extension. **NOTE** that the relative path cannot start with a slash (/).
## Example ## Example
Some custom resources in the **base** sub-directory are as follows: Some custom resources in the base sub-directory are as follows:
``` ```
...@@ -49,7 +49,7 @@ Some custom resources in the **base** sub-directory are as follows: ...@@ -49,7 +49,7 @@ Some custom resources in the **base** sub-directory are as follows:
└─ newTest.png └─ newTest.png
``` ```
The content of the **color.json** file is as follows: The content of the color.json file is as follows:
``` ```
...@@ -67,7 +67,7 @@ The content of the **color.json** file is as follows: ...@@ -67,7 +67,7 @@ The content of the **color.json** file is as follows:
} }
``` ```
The content of the **float.json** file is as follows: The content of the float.json file is as follows:
``` ```
...@@ -85,7 +85,7 @@ The content of the **float.json** file is as follows: ...@@ -85,7 +85,7 @@ The content of the **float.json** file is as follows:
} }
``` ```
The content of the **string.json** file is as follows: The content of the string.json file is as follows:
``` ```
...@@ -107,7 +107,7 @@ The content of the **string.json** file is as follows: ...@@ -107,7 +107,7 @@ The content of the **string.json** file is as follows:
} }
``` ```
The content of the **plural.json** file is as follows: The content of the plural.json file is as follows:
``` ```
...@@ -130,7 +130,7 @@ The content of the **plural.json** file is as follows: ...@@ -130,7 +130,7 @@ The content of the **plural.json** file is as follows:
} }
``` ```
In the **ets** file, you can use the resources defined in the **resources** directory. In the ets file, you can use the resources defined in the resources directory.
``` ```
Text($r('app.string.string_hello')) Text($r('app.string.string_hello'))
......
# Environment<a name="EN-US_TOPIC_0000001129032930"></a> # Environment
Environment is a singleton object created by the framework when the application is started. It provides the AppStorage with a series of environment state attributes required by the application. These attributes describe the device environment where the application runs. Environment and its attributes are immutable, and all attribute values are of the simple type. The following example shows how to obtain the semantic environment from Environment:
**Environment** is a singleton object created by the framework when the application is started. It provides the **AppStorage** with a series of environment state attributes required by the application. These attributes describe the device environment where the application runs. **Environment** and its attributes are immutable, and all attribute values are of the simple type.
The following example shows how to obtain the voice environment from **Environment**:
``` ```
Environment.EnvProp("accessibilityEnabled", "default"); Environment.EnvProp("accessibilityEnabled", "default");
var enable = AppStorageGet("accessibilityEnabled"); var enable = AppStorage.Get("accessibilityEnabled");
``` ```
**accessibilityEnabled** is the default system variable identifier provided by **Environment**. You need to bind the corresponding system attribute to the **AppStorage**. Then, you can use the methods or decorators in the **AppStorage** to access the corresponding system attribute data.
## Environment APIs<a name="section12843192134"></a> accessibilityEnabled is the default system variable identifier provided by Environment. You need to bind the corresponding system attribute to the AppStorage. Then, you can use the methods or decorators in the AppStorage to access the corresponding system attribute data.
## Environment APIs
<a name="table384419171310"></a> | key | Parameter | Return Value | Description |
<table><thead align="left"><tr id="row284141915136"><th class="cellrowborder" valign="top" width="14.26%" id="mcps1.1.5.1.1"><p id="p1784419191310"><a name="p1784419191310"></a><a name="p1784419191310"></a><strong id="b88541913130"><a name="b88541913130"></a><a name="b88541913130"></a>key</strong></p> | -------- | -------- | -------- | -------- |
</th> | EnvProp | key: string,<br/>defaultValue: any | boolean | Binds this system attribute to the AppStorage. You are advised to use this API during application startup. If the attribute already exists in the AppStorage, false is returned. Do not use the variables in the AppStorage. Instead, call this method to bind environment variables. |
<th class="cellrowborder" valign="top" width="25.330000000000002%" id="mcps1.1.5.1.2"><p id="p168921384172"><a name="p168921384172"></a><a name="p168921384172"></a>Parameter</p> | EnvProps | keys: {<br/>key: string,<br/>defaultValue: any<br/>}[] | void | Associates this system item array with the AppStorage. |
</th> | Keys | Array&lt;string&gt; | number | Returns the associated system item array. |
<th class="cellrowborder" valign="top" width="8.82%" id="mcps1.1.5.1.3"><p id="p12851119141312"><a name="p12851119141312"></a><a name="p12851119141312"></a>Return Value</p>
</th>
<th class="cellrowborder" valign="top" width="51.59%" id="mcps1.1.5.1.4"><p id="p885719141315"><a name="p885719141315"></a><a name="p885719141315"></a><strong id="b7724111610402"><a name="b7724111610402"></a><a name="b7724111610402"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row6857197134"><td class="cellrowborder" valign="top" width="14.26%" headers="mcps1.1.5.1.1 "><p id="p1385101911130"><a name="p1385101911130"></a><a name="p1385101911130"></a>EnvProp</p>
</td>
<td class="cellrowborder" valign="top" width="25.330000000000002%" headers="mcps1.1.5.1.2 "><p id="p5663204012204"><a name="p5663204012204"></a><a name="p5663204012204"></a>key : string</p>
<p id="p566354016203"><a name="p566354016203"></a><a name="p566354016203"></a>defaultValue: any</p>
</td>
<td class="cellrowborder" valign="top" width="8.82%" headers="mcps1.1.5.1.3 "><p id="p1585019161319"><a name="p1585019161319"></a><a name="p1585019161319"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="51.59%" headers="mcps1.1.5.1.4 "><p id="p385151931313"><a name="p385151931313"></a><a name="p385151931313"></a>Associates this system variable to the <strong id="b133309266408"><a name="b133309266408"></a><a name="b133309266408"></a>Appstorage</strong>. You are advised to use this API during application startup. If the attribute already exists in the <strong id="b1445964684012"><a name="b1445964684012"></a><a name="b1445964684012"></a>Appstorage</strong>, <strong id="b597684864017"><a name="b597684864017"></a><a name="b597684864017"></a>false</strong> is returned. Do not use the variables in the <strong id="b1363175314401"><a name="b1363175314401"></a><a name="b1363175314401"></a>AppStorage</strong>. Instead, call this method to bind environment variables.</p>
</td>
</tr>
<tr id="row685121921320"><td class="cellrowborder" valign="top" width="14.26%" headers="mcps1.1.5.1.1 "><p id="p89412247562"><a name="p89412247562"></a><a name="p89412247562"></a>EnvProps</p>
</td>
<td class="cellrowborder" valign="top" width="25.330000000000002%" headers="mcps1.1.5.1.2 "><p id="p16911327112814"><a name="p16911327112814"></a><a name="p16911327112814"></a>keys: {</p>
<p id="p260853217289"><a name="p260853217289"></a><a name="p260853217289"></a>key: string,</p>
<p id="p2084673414282"><a name="p2084673414282"></a><a name="p2084673414282"></a>defaultValue: any</p>
<p id="p1989210821720"><a name="p1989210821720"></a><a name="p1989210821720"></a>}[]</p>
</td>
<td class="cellrowborder" valign="top" width="8.82%" headers="mcps1.1.5.1.3 "><p id="p19487625142016"><a name="p19487625142016"></a><a name="p19487625142016"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="51.59%" headers="mcps1.1.5.1.4 "><p id="p2029419733518"><a name="p2029419733518"></a><a name="p2029419733518"></a>Associates this system item array with the <strong id="b18508171615413"><a name="b18508171615413"></a><a name="b18508171615413"></a>Appstorage</strong>.</p>
</td>
</tr>
<tr id="row198581961319"><td class="cellrowborder" valign="top" width="14.26%" headers="mcps1.1.5.1.1 "><p id="p1685319131316"><a name="p1685319131316"></a><a name="p1685319131316"></a>Keys</p>
</td>
<td class="cellrowborder" valign="top" width="25.330000000000002%" headers="mcps1.1.5.1.2 "><p id="p1282319383561"><a name="p1282319383561"></a><a name="p1282319383561"></a>Array&lt;string&gt;</p>
</td>
<td class="cellrowborder" valign="top" width="8.82%" headers="mcps1.1.5.1.3 "><p id="p128511951310"><a name="p128511951310"></a><a name="p128511951310"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="51.59%" headers="mcps1.1.5.1.4 "><p id="p138551931318"><a name="p138551931318"></a><a name="p138551931318"></a>Returns the associated system item array.</p>
</td>
</tr>
</tbody>
</table>
## Built-in Environment Variables<a name="section76906244255"></a>
<a name="table367mcpsimp"></a> ## Built-in Environment Variables
<table><thead align="left"><tr id="row373mcpsimp"><th class="cellrowborder" valign="top" width="15.42%" id="mcps1.1.4.1.1"><p id="p375mcpsimp"><a name="p375mcpsimp"></a><a name="p375mcpsimp"></a><strong id="b1320314815620"><a name="b1320314815620"></a><a name="b1320314815620"></a>key</strong></p>
</th>
<th class="cellrowborder" valign="top" width="12.83%" id="mcps1.1.4.1.2"><p id="p377mcpsimp"><a name="p377mcpsimp"></a><a name="p377mcpsimp"></a><strong id="b17897537411"><a name="b17897537411"></a><a name="b17897537411"></a>Type</strong></p>
</th>
<th class="cellrowborder" valign="top" width="71.75%" id="mcps1.1.4.1.3"><p id="p379mcpsimp"><a name="p379mcpsimp"></a><a name="p379mcpsimp"></a><strong id="b78735539419"><a name="b78735539419"></a><a name="b78735539419"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row380mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p7162853112520"><a name="p7162853112520"></a><a name="p7162853112520"></a>accessibilityEnabled</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p384mcpsimp"><a name="p384mcpsimp"></a><a name="p384mcpsimp"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p386mcpsimp"><a name="p386mcpsimp"></a><a name="p386mcpsimp"></a>Whether to enable accessibility.</p>
</td>
</tr>
<tr id="row387mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p389mcpsimp"><a name="p389mcpsimp"></a><a name="p389mcpsimp"></a>colorMode</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p391mcpsimp"><a name="p391mcpsimp"></a><a name="p391mcpsimp"></a>ColorMode</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p897319423383"><a name="p897319423383"></a><a name="p897319423383"></a>Color mode. The options are as follows:</p>
<a name="ul11210147183818"></a><a name="ul11210147183818"></a><ul id="ul11210147183818"><li><strong id="b66184249423"><a name="b66184249423"></a><a name="b66184249423"></a>ColorMode.LIGHT</strong>: light mode.</li><li><strong id="b624204315422"><a name="b624204315422"></a><a name="b624204315422"></a>ColorMode.DARK</strong>: dark mode.</li></ul>
</td>
</tr>
<tr id="row394mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p396mcpsimp"><a name="p396mcpsimp"></a><a name="p396mcpsimp"></a>fontScale</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p398mcpsimp"><a name="p398mcpsimp"></a><a name="p398mcpsimp"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p400mcpsimp"><a name="p400mcpsimp"></a><a name="p400mcpsimp"></a>Font scale. The value range is [0.85, 1.45].</p>
</td>
</tr>
<tr id="row401mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p778417357267"><a name="p778417357267"></a><a name="p778417357267"></a>fontWeightScale</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p405mcpsimp"><a name="p405mcpsimp"></a><a name="p405mcpsimp"></a>number</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p407mcpsimp"><a name="p407mcpsimp"></a><a name="p407mcpsimp"></a>Font weight scale. The value range is [0.6, 1.6].</p>
</td>
</tr>
<tr id="row408mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p410mcpsimp"><a name="p410mcpsimp"></a><a name="p410mcpsimp"></a>layoutDirection</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p412mcpsimp"><a name="p412mcpsimp"></a><a name="p412mcpsimp"></a>LayoutDirection</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p549615347406"><a name="p549615347406"></a><a name="p549615347406"></a>Layout direction. The options are as follows:</p>
<a name="ul370513428408"></a><a name="ul370513428408"></a><ul id="ul370513428408"><li><strong id="b10904132124313"><a name="b10904132124313"></a><a name="b10904132124313"></a>LayoutDirection.LTR</strong>: The direction is from left to right.</li><li><strong id="b66711929174317"><a name="b66711929174317"></a><a name="b66711929174317"></a>LayoutDirection.RTL</strong>: The direction is from right to left.</li></ul>
</td>
</tr>
<tr id="row415mcpsimp"><td class="cellrowborder" valign="top" width="15.42%" headers="mcps1.1.4.1.1 "><p id="p417mcpsimp"><a name="p417mcpsimp"></a><a name="p417mcpsimp"></a>languageCode</p>
</td>
<td class="cellrowborder" valign="top" width="12.83%" headers="mcps1.1.4.1.2 "><p id="p419mcpsimp"><a name="p419mcpsimp"></a><a name="p419mcpsimp"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="71.75%" headers="mcps1.1.4.1.3 "><p id="p421mcpsimp"><a name="p421mcpsimp"></a><a name="p421mcpsimp"></a>Current system language. The value is in lowercase, for example, <strong id="b1455024519431"><a name="b1455024519431"></a><a name="b1455024519431"></a>zh</strong>.</p>
</td>
</tr>
</tbody>
</table>
| key | Type | Description |
| -------- | -------- | -------- |
| accessibilityEnabled | boolean | Whether to enable accessibility. |
| colorMode | ColorMode | Color mode. The options are as follows:<br/>- ColorMode.LIGHT: light mode.<br/>- ColorMode.DARK: dark mode. |
| fontScale | number | Font scale. The value range is [0.85, 1.45]. |
| fontWeightScale | number | Font weight scale. The value range is [0.6, 1.6]. |
| layoutDirection | LayoutDirection | Layout direction. The options are as follows:<br/>- LayoutDirection.LTR: The direction is from left to right.<br/>- LayoutDirection.RTL: The direction is from right to left. |
| languageCode | string | Current system language. The value is in lowercase, for example, zh. |
# PersistentStorage<a name="EN-US_TOPIC_0000001175152427"></a> # PersistentStorage
**PersistentStorage** is used to manage persistent data of applications. This object can link the persistent data of a specific flag to the **AppStorage** and access the persistent data through the **AppStorage** APIs or access the variable of the corresponding key through the **@StorageLink** decorator.
## PersistentStorage APIs<a name="section959123213514"></a> ArkUI provides some static methods in the PersistentStorage class for managing persistent data of applications. Persistent data with specific tags can be linked to the AppStorage, and then the persistent data can be accessed through the AppStorage APIs. Alternatively, the @StorageLink decorator can be used to access the variable of the specific key.
| Name | Type | Return Value | Definition |
| -------- | -------- | -------- | -------- |
| PersistProp | key : string<br/>defaultValue: T | void | Changes the associated named attribute to persistent data in the AppStorage. The value overwriting sequence is as follows:<br/>- If the attribute exists in the AppStorage, use it to overwrite the value in Persistent.<br/>- If Persistent contains the specified attribute, use the attribute value in Persistent.<br/>- If the preceding conditions are not met, use defaultValue. The values null and undefined are not supported. |
| DeleteProp | key: string | void | Cancels two-way binding. The value of this attribute will be deleted from the persistent storage. |
| PersistProps | keys: {<br/>key: string,<br/>defaultValue: any<br/>}[] | void | Associates multiple named attribute bindings. |
| Keys | void | Array &lt;string&gt; | Returns the flags of all persistent attributes. |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - When using PersistProp, ensure that the input key exists in the AppStorage.
>
> - DeleteProp takes effect only for the data that has been linked during the current startup.
<a name="table311mcpsimp"></a>
<table><thead align="left"><tr id="row317mcpsimp"><th class="cellrowborder" valign="top" width="15.02%" id="mcps1.1.5.1.1"><p id="p319mcpsimp"><a name="p319mcpsimp"></a><a name="p319mcpsimp"></a>Name</p>
</th>
<th class="cellrowborder" valign="top" width="11.540000000000001%" id="mcps1.1.5.1.2"><p id="p321mcpsimp"><a name="p321mcpsimp"></a><a name="p321mcpsimp"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="9.5%" id="mcps1.1.5.1.3"><p id="p136621139145019"><a name="p136621139145019"></a><a name="p136621139145019"></a>Return Value</p>
</th>
<th class="cellrowborder" valign="top" width="63.94%" id="mcps1.1.5.1.4"><p id="p323mcpsimp"><a name="p323mcpsimp"></a><a name="p323mcpsimp"></a>Definition</p>
</th>
</tr>
</thead>
<tbody><tr id="row324mcpsimp"><td class="cellrowborder" valign="top" width="15.02%" headers="mcps1.1.5.1.1 "><p id="p326mcpsimp"><a name="p326mcpsimp"></a><a name="p326mcpsimp"></a>PersistProp</p>
</td>
<td class="cellrowborder" valign="top" width="11.540000000000001%" headers="mcps1.1.5.1.2 "><p id="p328mcpsimp"><a name="p328mcpsimp"></a><a name="p328mcpsimp"></a>key : string</p>
<p id="p269635419439"><a name="p269635419439"></a><a name="p269635419439"></a>defaultValue: T</p>
</td>
<td class="cellrowborder" valign="top" width="9.5%" headers="mcps1.1.5.1.3 "><p id="p266216399501"><a name="p266216399501"></a><a name="p266216399501"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="63.94%" headers="mcps1.1.5.1.4 "><p id="p115337540440"><a name="p115337540440"></a><a name="p115337540440"></a>Changes associated named attribute to persistent data in the <strong id="b798274517339"><a name="b798274517339"></a><a name="b798274517339"></a>AppStorage</strong>. Value overwriting sequence:</p>
<p id="p1097811294611"><a name="p1097811294611"></a><a name="p1097811294611"></a>If the attribute exists in the <strong id="b15266175917330"><a name="b15266175917330"></a><a name="b15266175917330"></a>AppStorage</strong>, overwrite its value with the attribute value in <strong id="b344612783413"><a name="b344612783413"></a><a name="b344612783413"></a>Persistent</strong>.</p>
<p id="p29609684715"><a name="p29609684715"></a><a name="p29609684715"></a>If <strong id="b12915121853416"><a name="b12915121853416"></a><a name="b12915121853416"></a>Persistent</strong> contains the specified attribute, use the attribute value in <strong id="b1578284213414"><a name="b1578284213414"></a><a name="b1578284213414"></a>Persistent</strong>.</p>
<p id="p1738263104810"><a name="p1738263104810"></a><a name="p1738263104810"></a>If the preceding conditions are not met, use <strong id="b6526155416348"><a name="b6526155416348"></a><a name="b6526155416348"></a>defaultValue</strong>. The <strong id="b993917517358"><a name="b993917517358"></a><a name="b993917517358"></a>null</strong> and <strong id="b252811983513"><a name="b252811983513"></a><a name="b252811983513"></a>undefined</strong> values are not supported.</p>
</td>
</tr>
<tr id="row331mcpsimp"><td class="cellrowborder" valign="top" width="15.02%" headers="mcps1.1.5.1.1 "><p id="p333mcpsimp"><a name="p333mcpsimp"></a><a name="p333mcpsimp"></a>DeleteProp</p>
</td>
<td class="cellrowborder" valign="top" width="11.540000000000001%" headers="mcps1.1.5.1.2 "><p id="p335mcpsimp"><a name="p335mcpsimp"></a><a name="p335mcpsimp"></a>key: string</p>
</td>
<td class="cellrowborder" valign="top" width="9.5%" headers="mcps1.1.5.1.3 "><p id="p866233965012"><a name="p866233965012"></a><a name="p866233965012"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="63.94%" headers="mcps1.1.5.1.4 "><p id="p337mcpsimp"><a name="p337mcpsimp"></a><a name="p337mcpsimp"></a>Cancels two-way binding. The value of this attribute will be deleted from the persistent storage.</p>
</td>
</tr>
<tr id="row94321195117"><td class="cellrowborder" valign="top" width="15.02%" headers="mcps1.1.5.1.1 "><p id="p651421105116"><a name="p651421105116"></a><a name="p651421105116"></a>PersistProps</p>
</td>
<td class="cellrowborder" valign="top" width="11.540000000000001%" headers="mcps1.1.5.1.2 "><p id="p69911746282"><a name="p69911746282"></a><a name="p69911746282"></a>keys: {</p>
<p id="p52741115112813"><a name="p52741115112813"></a><a name="p52741115112813"></a>key: string,</p>
<p id="p1414372092813"><a name="p1414372092813"></a><a name="p1414372092813"></a>defaultValue: any</p>
<p id="p11542175114"><a name="p11542175114"></a><a name="p11542175114"></a>}[]</p>
</td>
<td class="cellrowborder" valign="top" width="9.5%" headers="mcps1.1.5.1.3 "><p id="p1451721115111"><a name="p1451721115111"></a><a name="p1451721115111"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="63.94%" headers="mcps1.1.5.1.4 "><p id="p8512119518"><a name="p8512119518"></a><a name="p8512119518"></a>Associates multiple named attribute bindings.</p>
</td>
</tr>
<tr id="row338mcpsimp"><td class="cellrowborder" valign="top" width="15.02%" headers="mcps1.1.5.1.1 "><p id="p340mcpsimp"><a name="p340mcpsimp"></a><a name="p340mcpsimp"></a>Keys</p>
</td>
<td class="cellrowborder" valign="top" width="11.540000000000001%" headers="mcps1.1.5.1.2 "><p id="p342mcpsimp"><a name="p342mcpsimp"></a><a name="p342mcpsimp"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="9.5%" headers="mcps1.1.5.1.3 "><p id="p16662163915015"><a name="p16662163915015"></a><a name="p16662163915015"></a>Array&lt;string&gt;</p>
</td>
<td class="cellrowborder" valign="top" width="63.94%" headers="mcps1.1.5.1.4 "><p id="p344mcpsimp"><a name="p344mcpsimp"></a><a name="p344mcpsimp"></a>Returns the flags of all persistent attributes.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- When using **PersistProp**, ensure that the input key exists in the **Appstorage**.
>- **DeleteProp** takes effect only for the data that has been linked during the current startup.
``` ```
PersistentStorage.PersistProp("highScore", "0"); PersistentStorage.PersistProp("highScore", "0");
...@@ -91,4 +45,3 @@ struct PersistentComponent { ...@@ -91,4 +45,3 @@ struct PersistentComponent {
} }
} }
``` ```
# AppStorage<a name="EN-US_TOPIC_0000001119929480"></a> # AppStorage
**AppStorage** is a singleton object in an application and is created by the UI framework when the application is started. It is designed to provide central storage for changing application state attributes. **AppStorage** contains all the state attributes that need to be accessed throughout the application. The **AppStorage** retains all attributes and their values as long as the application remains running, and the attribute values can be accessed through unique key values.
AppStorage is a singleton object in an application, which is created by the UI framework when the application is started and destroyed when the application exits. It is used to provide central storage for changing state attributes of an application. AppStorage contains all the state attributes that need to be accessed throughout the application. The AppStorage retains all attributes and their values as long as the application remains running, and the attribute values can be accessed through unique key values.
The UI component can synchronize the application state data with the **AppStorage** through the decorators. The application service logic can also be implemented by accessing the **AppStorage** through APIs.
The selection state attribute of the **AppStorage** can be synchronized with different data sources or data sinks. These data sources and data sinks can be local or remote devices and provide different functions, such as data persistence. Such data sources and data sinks can be implemented independently of the UI in the service logic. The UI component can synchronize the application state data with the AppStorage through the decorators. The application service logic can also be implemented by accessing the AppStorage through APIs.
By default, the attributes in the **AppStorage** are changeable. If needed, **AppStorage** can also use immutable \(read-only\) attributes.
The selection state attribute of the AppStorage can be synchronized with different data sources or data sinks. These data sources and data sinks can be local or remote devices and provide different functions, such as data persistence. Such data sources and data sinks can be implemented independently of the UI in the service logic.
## AppStorage APIs<a name="en-us_topic_0000001103218748_section89909382526"></a>
<a name="en-us_topic_0000001103218748_table109mcpsimp"></a> By default, the attributes in the AppStorage are changeable. If needed, AppStorage can also use immutable (read-only) attributes.
<table><thead align="left"><tr id="en-us_topic_0000001103218748_row115mcpsimp"><th class="cellrowborder" valign="top" width="11.700000000000001%" id="mcps1.1.5.1.1"><p id="en-us_topic_0000001103218748_p117mcpsimp"><a name="en-us_topic_0000001103218748_p117mcpsimp"></a><a name="en-us_topic_0000001103218748_p117mcpsimp"></a>Name</p>
</th>
<th class="cellrowborder" valign="top" width="13.96%" id="mcps1.1.5.1.2"><p id="en-us_topic_0000001103218748_p119mcpsimp"><a name="en-us_topic_0000001103218748_p119mcpsimp"></a><a name="en-us_topic_0000001103218748_p119mcpsimp"></a>Type</p> ## AppStorage APIs
</th>
<th class="cellrowborder" valign="top" width="12.379999999999999%" id="mcps1.1.5.1.3"><p id="p1566112607"><a name="p1566112607"></a><a name="p1566112607"></a>Return Value</p> | Name | Type | Return Value | Definition |
</th> | -------- | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="61.96%" id="mcps1.1.5.1.4"><p id="en-us_topic_0000001103218748_p121mcpsimp"><a name="en-us_topic_0000001103218748_p121mcpsimp"></a><a name="en-us_topic_0000001103218748_p121mcpsimp"></a>Definition</p> | SetAndLink | key: string,<br/>defaultValue: T | @Link | Works in a way similar to the Link API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Link instance corresponding to the default value is created and returned. |
</th> | Set | key: string,<br/>newValue: T | void | Replaces the value of a saved key. |
</tr> | Link | key: string | @Link | Returns two-way binding to this attribute if there is data with a given key. This means that attribute changes made by a variable or component will be synchronized to the AppStorage, and attribute changes made through the AppStorage will be synchronized to the variable or component. If the attribute with this key does not exist or is read-only, undefined is returned. |
</thead> | SetAndProp | propName: string,<br/>defaultValue: S | @Prop | Works in a way similar to the Prop API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Prop instance corresponding to the default value is created and returned. |
<tbody><tr id="en-us_topic_0000001103218748_row122mcpsimp"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="en-us_topic_0000001103218748_p124mcpsimp"><a name="en-us_topic_0000001103218748_p124mcpsimp"></a><a name="en-us_topic_0000001103218748_p124mcpsimp"></a>Link</p> | Prop | key: string | @Prop | Returns one-way binding to an attribute with a given key if the attribute exists. This means that attribute changes made through the AppStorage will be synchronized to the variable or component, but attribute changes made by the variable or component will be synchronized to the AppStorage. The variable returned by this method is an immutable one, which is applicable both to the variable and immutable state attributes. If the attribute with the specified key does not exist, undefined is returned.<br/>> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:<br/>> The attribute value used in the prop method must be of a simple type. |
</td> | SetOrCreate | key: string,<br/>newValue: T | boolean | If an attribute that has the same name as the specified key exists: replaces the value of the attribute and returns true when the attribute can be modified; retains the original value of the attribute and returns false otherwise.<br/>If an attribute that has the same name as the specified key does not exist: creates an attribute whose key is key and value is newValue. The values null and undefined are not supported. |
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="en-us_topic_0000001103218748_p126mcpsimp"><a name="en-us_topic_0000001103218748_p126mcpsimp"></a><a name="en-us_topic_0000001103218748_p126mcpsimp"></a>key: string</p> | Get | key: string | T or undefined | Obtains the value of the specified key. |
</td> | Has | propName: string | boolean | Checks whether the attribute corresponding to the specified key value exists. |
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p185664215018"><a name="p185664215018"></a><a name="p185664215018"></a>@Link</p> | Keys | void | array&lt;string&gt; | Returns an array of strings containing all keys. |
</td> | Delete | key: string | boolean | Deletes the key-value pair for the specified key. Returns true if the key-value pair exists and is successfully deleted; returns false otherwise. |
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="en-us_topic_0000001103218748_p128mcpsimp"><a name="en-us_topic_0000001103218748_p128mcpsimp"></a><a name="en-us_topic_0000001103218748_p128mcpsimp"></a>Returns the two-way binding to this attribute if there is data with a given key. This means that changes made to the data by a variable or component will be synchronized to the <strong id="b256152252519"><a name="b256152252519"></a><a name="b256152252519"></a>AppStorage</strong>, and changes made to the data by the <strong id="b2044815293254"><a name="b2044815293254"></a><a name="b2044815293254"></a>AppStorage</strong> will be synchronized to the variable or component. If the attribute with this key does not exist or is read-only, <strong id="b105824492514"><a name="b105824492514"></a><a name="b105824492514"></a>undefined</strong> is returned.</p> | Clear | void | boolean | Deletes all attributes. If any of the attributes is being referenced by a state variable, false is returned. |
</td> | IsMutable | key: string | boolean | Specifies whether the attribute exists and can be changed. |
</tr>
<tr id="row327610512417"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p142761957415"><a name="p142761957415"></a><a name="p142761957415"></a>SetAndLink</p> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
</td> > Currently, the API can process only basic data and cannot modify a value in an object.
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p240416172411"><a name="p240416172411"></a><a name="p240416172411"></a>key : String</p>
<p id="p540414171943"><a name="p540414171943"></a><a name="p540414171943"></a>defaultValue: T</p>
</td> ## Synchronization Between AppStorage and Components
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p96661522744"><a name="p96661522744"></a><a name="p96661522744"></a>@Link</p>
</td> In [Managing Component States](ts-component-states-state.md), we have defined how to synchronize the state variables of child components with the @State decorated variables in the parent component or ancestor component, including @Prop, @Link, and @Consume.
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p13277851841"><a name="p13277851841"></a><a name="p13277851841"></a>Works in a way similar to the <strong id="b673182616"><a name="b673182616"></a><a name="b673182616"></a>Link</strong> API. If the current key is stored in the <strong id="b117871016261"><a name="b117871016261"></a><a name="b117871016261"></a>AppStorage</strong>, the value corresponding to the key is returned. If the key has not been created, a <strong id="b1132564213289"><a name="b1132564213289"></a><a name="b1132564213289"></a>Link</strong> instance corresponding to the default value is created and returned.</p>
</td> In this section, we'll describe how to synchronize component variables with the AppStorage through the @StorageLink and @StorageProp decorators.
</tr>
<tr id="en-us_topic_0000001103218748_row129mcpsimp"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="en-us_topic_0000001103218748_p131mcpsimp"><a name="en-us_topic_0000001103218748_p131mcpsimp"></a><a name="en-us_topic_0000001103218748_p131mcpsimp"></a>Prop</p>
</td> ### @StorageLink Decorator
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="en-us_topic_0000001103218748_p133mcpsimp"><a name="en-us_topic_0000001103218748_p133mcpsimp"></a><a name="en-us_topic_0000001103218748_p133mcpsimp"></a>key: string</p>
</td> Two-way data binding can be established between components and the AppStorage through state variables decorated by @StorageLink(_key_). Wherein, key is the attribute key value in the AppStorage. When a component containing the @StorageLink decorated variable is created, the variable is initialized using the value in the AppStorage. Changes made to this variable in the component will be first synchronized to the AppStorage, and then to other bound instances, such as PersistentStorage or other bound UI components.
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p55660211014"><a name="p55660211014"></a><a name="p55660211014"></a>@Prop</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="en-us_topic_0000001103218748_p135mcpsimp"><a name="en-us_topic_0000001103218748_p135mcpsimp"></a><a name="en-us_topic_0000001103218748_p135mcpsimp"></a>Returns one-way binding to an attribute with a given key if the attribute exists. This one-way binding means that changes to the attribute can only be synchronized to variables or components through <strong id="b1983822114277"><a name="b1983822114277"></a><a name="b1983822114277"></a>AppStorage</strong>. The variable returned by this method is an immutable one, which is applicable both to the variable and immutable state attributes. If the attribute with this key does not exist, <strong id="b1420194122713"><a name="b1420194122713"></a><a name="b1420194122713"></a>undefined</strong> is returned.</p> ### @StorageProp Decorator
<div class="note" id="en-us_topic_0000001103218748_note1886831124618"><a name="en-us_topic_0000001103218748_note1886831124618"></a><a name="en-us_topic_0000001103218748_note1886831124618"></a><span class="notetitle"> NOTE: </span><div class="notebody"><p id="p522015411452"><a name="p522015411452"></a><a name="p522015411452"></a>The attribute value type used in the <strong id="b131815112279"><a name="b131815112279"></a><a name="b131815112279"></a>prop</strong> method must be of a simple type.</p>
</div></div> One-way data binding can be established between components and the AppStorage through state variables decorated by @StorageProp(_key_). Wherein, key is the attribute key value in the AppStorage. When a component containing the @StorageProp decorated variable is created, the variable is initialized using the value in the AppStorage. Changes made to the value in the AppStorage will cause the bound UI component to update the state.
</td>
</tr>
<tr id="row13351212193"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p835812194"><a name="p835812194"></a><a name="p835812194"></a>SetAndProp</p> ## Example
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p1228852918920"><a name="p1228852918920"></a><a name="p1228852918920"></a>key : string</p>
<p id="p132888294919"><a name="p132888294919"></a><a name="p132888294919"></a>defaultValue: S</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p035712792"><a name="p035712792"></a><a name="p035712792"></a>@Prop</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p18161144416910"><a name="p18161144416910"></a><a name="p18161144416910"></a>Works in a way similar to the <strong id="b129457583275"><a name="b129457583275"></a><a name="b129457583275"></a>Prop</strong> API. If the current key is stored in the <strong id="b12291153112817"><a name="b12291153112817"></a><a name="b12291153112817"></a>AppStorage</strong>, the value corresponding to the key is returned. If the key has not been created, a <strong id="b19872518172815"><a name="b19872518172815"></a><a name="b19872518172815"></a>Prop</strong> instance corresponding to the default value is created and returned.</p>
</td>
</tr>
<tr id="en-us_topic_0000001103218748_row136mcpsimp"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="en-us_topic_0000001103218748_p138mcpsimp"><a name="en-us_topic_0000001103218748_p138mcpsimp"></a><a name="en-us_topic_0000001103218748_p138mcpsimp"></a>Has</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="en-us_topic_0000001103218748_p140mcpsimp"><a name="en-us_topic_0000001103218748_p140mcpsimp"></a><a name="en-us_topic_0000001103218748_p140mcpsimp"></a>key: string</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p125661627019"><a name="p125661627019"></a><a name="p125661627019"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="en-us_topic_0000001103218748_p142mcpsimp"><a name="en-us_topic_0000001103218748_p142mcpsimp"></a><a name="en-us_topic_0000001103218748_p142mcpsimp"></a>Checks whether the attribute corresponding to the key value exists.</p>
</td>
</tr>
<tr id="en-us_topic_0000001103218748_row150mcpsimp"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="en-us_topic_0000001103218748_p1363415429353"><a name="en-us_topic_0000001103218748_p1363415429353"></a><a name="en-us_topic_0000001103218748_p1363415429353"></a>Keys</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="en-us_topic_0000001103218748_p154mcpsimp"><a name="en-us_topic_0000001103218748_p154mcpsimp"></a><a name="en-us_topic_0000001103218748_p154mcpsimp"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p19566522014"><a name="p19566522014"></a><a name="p19566522014"></a>array&lt;string&gt;</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="en-us_topic_0000001103218748_p156mcpsimp"><a name="en-us_topic_0000001103218748_p156mcpsimp"></a><a name="en-us_topic_0000001103218748_p156mcpsimp"></a>Returns an array of strings containing all keys.</p>
</td>
</tr>
<tr id="row3460194012589"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p1846mcpsimp"><a name="p1846mcpsimp"></a><a name="p1846mcpsimp"></a>Get</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p263019299243"><a name="p263019299243"></a><a name="p263019299243"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p14566921105"><a name="p14566921105"></a><a name="p14566921105"></a>T or undefined</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p1850mcpsimp"><a name="p1850mcpsimp"></a><a name="p1850mcpsimp"></a>Obtains the value of the key.</p>
</td>
</tr>
<tr id="row4460184019583"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p4826171212519"><a name="p4826171212519"></a><a name="p4826171212519"></a>Set</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p11826512152517"><a name="p11826512152517"></a><a name="p11826512152517"></a>string, newValue : T</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p185671321506"><a name="p185671321506"></a><a name="p185671321506"></a>void</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p1982671202510"><a name="p1982671202510"></a><a name="p1982671202510"></a>Replaces the value of a saved key.</p>
</td>
</tr>
<tr id="row546074014585"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p1799852316279"><a name="p1799852316279"></a><a name="p1799852316279"></a>SetOrCreate</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p146505413272"><a name="p146505413272"></a><a name="p146505413272"></a>string, newValue : T</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p168731437917"><a name="p168731437917"></a><a name="p168731437917"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p639717522815"><a name="p639717522815"></a><a name="p639717522815"></a>Returns <strong id="b28651779307"><a name="b28651779307"></a><a name="b28651779307"></a>true</strong> if an attribute with the same name exists and the attribute can be modified; returns <strong id="b57431415123013"><a name="b57431415123013"></a><a name="b57431415123013"></a>false</strong> otherwise.</p>
<p id="p17541322112611"><a name="p17541322112611"></a><a name="p17541322112611"></a>If the attribute with the same name does not exist: the first attribute whose value is the <strong id="b13513114214300"><a name="b13513114214300"></a><a name="b13513114214300"></a>defaultValue</strong> is created and returned. The <strong id="b3232681318"><a name="b3232681318"></a><a name="b3232681318"></a>null</strong> and <strong id="b17924171163110"><a name="b17924171163110"></a><a name="b17924171163110"></a>undefined</strong> values are not supported.</p>
</td>
</tr>
<tr id="row350321491214"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p17503121481216"><a name="p17503121481216"></a><a name="p17503121481216"></a>Delete</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p6503161417122"><a name="p6503161417122"></a><a name="p6503161417122"></a>key : string</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p205031814191212"><a name="p205031814191212"></a><a name="p205031814191212"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p05031014141211"><a name="p05031014141211"></a><a name="p05031014141211"></a>Deletes an attribute. If the attribute exists, <strong id="b1920473013116"><a name="b1920473013116"></a><a name="b1920473013116"></a>true</strong> is returned. Otherwise, <strong id="b98112040193114"><a name="b98112040193114"></a><a name="b98112040193114"></a>false</strong> is returned.</p>
</td>
</tr>
<tr id="row12261203911401"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p202611739204016"><a name="p202611739204016"></a><a name="p202611739204016"></a>Clear</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p526118395407"><a name="p526118395407"></a><a name="p526118395407"></a>none</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 "><p id="p326173910400"><a name="p326173910400"></a><a name="p326173910400"></a>boolean</p>
</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p22611139114012"><a name="p22611139114012"></a><a name="p22611139114012"></a>Deletes all attributes. If any of the attributes is being referenced by a state variable, <strong id="b15300751153119"><a name="b15300751153119"></a><a name="b15300751153119"></a>false</strong> is returned.</p>
</td>
</tr>
<tr id="row14209473411"><td class="cellrowborder" valign="top" width="11.700000000000001%" headers="mcps1.1.5.1.1 "><p id="p12420347194115"><a name="p12420347194115"></a><a name="p12420347194115"></a>IsMutable</p>
</td>
<td class="cellrowborder" valign="top" width="13.96%" headers="mcps1.1.5.1.2 "><p id="p10420174754114"><a name="p10420174754114"></a><a name="p10420174754114"></a>key: string</p>
</td>
<td class="cellrowborder" valign="top" width="12.379999999999999%" headers="mcps1.1.5.1.3 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="61.96%" headers="mcps1.1.5.1.4 "><p id="p1942074711417"><a name="p1942074711417"></a><a name="p1942074711417"></a>Specifies whether the attribute exists and can be changed.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Currently, the API can process only basic data and cannot modify a value in an object.
## Example<a name="en-us_topic_0000001103218748_section195112274815"></a>
``` ```
let link1 = AppStorage.Link('PropA') let varA = AppStorage.Link('varA')
let link2 = AppStorage.Link('PropA') let envLang = AppStorage.Prop('languageCode')
let prop = AppStorage.Prop('PropA')
@Entry
@Component
struct ComponentA {
@StorageLink('varA') varA: number = 2
@StorageProp('languageCode') lang: string = 'en'
private label: string = 'count'
private aboutToAppear() {
this.label = (this.lang === 'en') ? 'Number' : 'Count'
}
build() {
Row({ space: 20 }) {
link1 = 47 // causes link1 == link2 == prop == 47 Button(`${this.label}: ${this.varA}`)
link2 = link1 + prop // causes link1 == link2 == prop == 94 .onClick(() => {
prop = 1 // error, prop is immutable AppStorage.Set<number>('varA', AppStorage.Get<number>('varA') + 1)
})
Button(`lang: ${this.lang}`)
.onClick(() => {
if (this.lang === 'zh') {
AppStorage.Set<string>('languageCode', 'en')
} else {
AppStorage.Set<string>('languageCode', 'en')
}
this.label = (this.lang === 'en') ? 'Number' : 'Count'
})
}
}
}
``` ```
Each time the user clicks the Count button, the value of this.varA will increase by 1. This variable is synchronized with varA in the AppStorage. Each time the user clicks the language icon, the value of languageCode in the AppStorage will be changed, and the change will be synchronized to the this.lang variable.
# Attribution Configuration<a name="EN-US_TOPIC_0000001157228865"></a> # Attribute Configuration
Use attribute methods to configure component attributes. An attribute method follows the corresponding component and is bound to the component using the "**.**" operator.
The following is an example of configuring the **fontsize** attribute of the **<Text\>** component: Use attribute methods to configure component attributes. An attribute method follows the corresponding component and is bound to the component using the "." operator.
```
Text('123') - The following is an example of configuring the font size attribute of the Text component:
```
Text('123')
.fontSize(12) .fontSize(12)
``` ```
You can also use the "**.**" operation to implement chain call to configure multiple attributes at the same time.
Below is the sample code for configuring the **width** and **height** attributes of the **<Image\>** component at the same time: - Use the "." operator to implement chain call to configure multiple attributes at the same time, as shown below:
``` ```
Image('a.jpg') Image('a.jpg')
.alt('error.jpg') .alt('error.jpg') .width(100) .height(100)
.width(100) ```
.height(100)
```
In addition to constants, you can also pass variables or expressions, as shown below:
``` - In addition to constants, you can also pass variables or expressions, as shown below:
// Size, count, and offset are private variables defined in the component.
Text('hello')
.fontSize(this.size)
Image('a.jpg')
.width(this.count % 2 === 0 ? 100 : 200)
.height(this.offset + 100)
```
For attributes of preset components, the framework also provides some predefined enumeration types, which you can pass as parameters to methods. ```
// Size, count, and offset are private variables defined in the component.
Text('hello')
.fontSize(this.size)
Image('a.jpg')
.width(this.count % 2 === 0 ? 100 : 200) .height(this.offset + 100)
```
Enumeration types must meet the parameter type requirements on the enumeration type definitions for specific attributes.
You can configure the font color and weight attributes of the **<Text\>** component as follows: - For attributes of preset components, the framework also provides some predefined enumeration types, which you can pass as parameters to methods. Enumeration types must meet the parameter type requirements on the enumeration type definitions for specific attributes. You can configure the font color and weight attributes of the Text component as follows:
``` ```
Text('hello') Text('hello')
.fontSize(20) .fontSize(20)
.fontColor(Color.Red) .fontColor(Color.Red)
.fontWeight(FontWeight.Bold) .fontWeight(FontWeight.Bold)
``` ```
# LoadingProgress
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
> This component is supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version.
The **<LoadingProgress>** component is used to display the loading progress.
## Required Permissions
None
## Child Components
None
## APIs
LoadingProgress()
Creates a **LoadingProgress** instance.
## Attributes
| Name | Type | Default Value | Description |
| ----- | ----- | ------------- | ---------------------------------------- |
| color | Color | - | Foreground color of the loading progress bar. |
## Example
```
@Entry
@Component
struct LoadingProgressExample {
build() {
Column({ space: 5 }) {
Text('Orbital LoadingProgress ').fontSize(9).fontColor(0xCCCCCC).width('90%')
LoadingProgress()
.color(Color.Blue)
}.width('100%').margin({ top: 5 })
}
}
```
![zh-cn_image_0000001198839004](figures/loadingProgress.png)
\ No newline at end of file
# Child Component Configuration<a name="EN-US_TOPIC_0000001157228875"></a> # Child Component Configuration
For a component that supports child components, for example, a container component, add the UI descriptions of the child components inside "**\{ ... \}**". The **<Column\>**, **<Row\>**, **<Stack\>**, **<Button\>**, **<Grid\>**, and **<List\>** components are container components.
The following is a simple example of the **<Column\>** component: For a component that supports child components, for example, a container component, add the UI descriptions of the child components inside "{ ... }". The &lt;Column&gt;, &lt;Row&gt;, &lt;Stack&gt;, &lt;Button&gt;, &lt;Grid&gt;, and &lt;List&gt; components are container components.
```
Column() { - The following is a simple example of the &lt;Column&gt; component:
```
Column() {
Text('Hello') Text('Hello')
.fontSize(100) .fontSize(100)
Divider() Divider()
Text(this.myText) Text(this.myText)
.fontSize(100) .fontSize(100)
.fontColor(Color.Red) .fontColor(Color.Red)
} }
``` ```
Multiple child components can be nested in the **<Column\>** component, as shown below:
``` - Multiple child components can be nested in the &lt;Column&gt; component, as shown below:
Column() {
```
Column() {
Column() { Column() {
Button() { Button() {
Text('+ 1') Text('+ 1')
}.type(ButtonType.Capsule) }.type(ButtonType.Capsule)
.onClick(() => console.log ('+1 clicked!')) .onClick(() =&gt; console.log ('+1 clicked!'))
Image('1.jpg') Image('1.jpg')
} }
Divider() Divider()
...@@ -31,7 +34,7 @@ Column() { ...@@ -31,7 +34,7 @@ Column() {
Button() { Button() {
Text('+ 2') Text('+ 2')
}.type(ButtonType.Capsule) }.type(ButtonType.Capsule)
.onClick(() => console.log ('+2 clicked!')) .onClick(() =&gt; console.log ('+2 clicked!'))
Image('2.jpg') Image('2.jpg')
} }
Divider() Divider()
...@@ -39,9 +42,8 @@ Column() { ...@@ -39,9 +42,8 @@ Column() {
Button() { Button() {
Text('+ 3') Text('+ 3')
}.type(ButtonType.Capsule) }.type(ButtonType.Capsule)
.onClick(() => console.log('+3 clicked!')) .onClick(() =&gt; console.log('+3 clicked!'))
Image('3.jpg') Image('3.jpg')
} }
}.alignItems(HorizontalAlign.Center) // center align components inside Column }.alignItems(HorizontalAlign.Center) // center align components inside Column
``` ```
# @Builder<a name="EN-US_TOPIC_0000001134858596"></a> # @Builder
The @Builder decorated method is used to define the declarative UI description of a component and quickly generate multiple layouts in a custom component. The functionality and syntax of the @Builder decorator are the same as those of the [build Function](ts-function-build.md).
The **@Builder** decorator defines a method for rendering custom components It allows a method to work in the same way as the [build](ts-function-build.md) function. The syntax of methods decorated by **@Builder** is the same as that of the **build** function.
You can use the **@Builder** decorator to quickly generate multiple layouts within a custom component.
``` ```
@Entry @Entry
...@@ -42,3 +43,99 @@ struct CompA { ...@@ -42,3 +43,99 @@ struct CompA {
} }
``` ```
## @BuilderParam<sup>8+</sup>
The @BuilderParam decorator is used to modify the function type attributes (for example, @BuilderParam content: () => any) in a custom component. When the custom component is initialized, the attributes modified by the @BuilderParam decorator must be assigned values.
### Background
In certain circumstances, you may need to add a specific function, such as a click-to-jump action, to a custom component. However, embedding an event method directly inside of the component can add the function to all places where the component is initialized. This is where the @BuilderParam decorator come into the picture. When initializing a custom component, you can assign a @Builder decorated method to the @BuilderParam decorated attribute, thereby adding the specific function to the custom component.
### Component Initialization Through Parameters
When initializing a custom component through parameters, assign a @Builder decorated method to the @BuilderParam decorated attribute —content, and call the value of content in the custom component.
```
@Component
struct CustomContainer {
header: string = "";
@BuilderParam content: () => any;
footer: string = "";
build() {
Column() {
Text(this.header)
.fontSize(50)
this.content()
Text(this.footer)
.fontSize(50)
}
}
}
@Entry
@Component
struct CustomContainerUser {
@Builder specificParam(label: string) {
Column() {
Text(label).fontSize(50)
}
}
build() {
Column() {
CustomContainer({
header: "Header",
content: this.specificParam("111")
footer: "Footer",
})
}
}
}
```
### Component Initialization Through Trailing Closure
In a custom component, use the @BuilderParam decorated attribute to receive a trailing closure. When the custom component is initialized, the component name is followed by a pair of braces ({}) to form a trailing closure (CustomComponent(){}). You can consider a trailing closure as a container and add content to it. For example, you can add a component ({Column(){Text("content")}) to the closure. The syntax of the closure is the same as that of [build](ts-function-build.md). In this scenario, the custom component has one and only one @BuilderParam decorated attribute.
Example: Add a &lt;Column> component and a click event to the closure, and call the specificParam method decorated by @Builder in the new &lt;Column&gt; component. After the &lt;Column&gt; component is clicked, the value of the component's header attribute will be changed to changeHeader. In addition, when the component is initialized, the content of the trailing closure will be assigned to the closer attribute decorated by @BuilderParam.
```
@Component
struct CustomContainer {
header: string = "";
@BuilderParam closer: () => any;
build() {
Column() {
Text(this.header)
.fontSize(50)
this.closer()
}
}
}
@Builder function specificParam(label1: string, label2: string) {
Column() {
Text(label1)
.fontSize(50)
Text(label2)
.fontSize(50)
}
}
@Entry
@Component
struct CustomContainerUser {
@State text: string = "header"
build() {
Column() {
CustomContainer({
header: this.text,
}){
Column(){
specificParam("111", "22")
}.onClick(()=>{
this.text = "changeHeader"
})
}
}
}
}
```
# @Component<a name="EN-US_TOPIC_0000001157388849"></a> # @Component
A struct decorated by **@Component** has the component-based capability and can serve as an independent component. This type of component is also called a custom component.
This component can be combined with other components. It describes the UI structure by implementing the **build** method, which must comply with the **Builder** API constraints. The API definition is as follows: A struct decorated by @Component has the componentization capability and can serve as an independent component. This type of component is also called a custom component, and its UI structure is described in the build method. Custom components have the following features:
```
interface Builder {
build: () => void
}
```
Custom components have the following features: - Composability: Custom components can be used with preset or other components, as well as common attributes and methods.
- Reusable: Custom components can be reused by other components and used as different instances in different parent components or containers.
- Lifecycle: Custom components provide callbacks for service logic processing throughout the lifecycle.
- Data-driven update: The UI of custom components can be automatically updated based on the data of state variables.
- **Composability:** Custom components can be used with preset or other components, as well as common attributes and methods.
- **Reusable:** Custom components can be reused by other components and used as different instances in different parent components or containers.
- **Lifecycle:** Custom components provide callbacks for service logic processing throughout the lifecycle.
- **Data-driven update:** The UI of custom components can be automatically updated based on the status data.
The component lifecycle mainly involves two callbacks, **aboutToAppear** and **aboutToDisappear** . For details, see [Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md). For details about componentization, see [About @Component](ts-function-build.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- Components must comply with the preceding **Builder** API constraints. Other components are combined in declarative mode in the internal **build** method. The **build** method is called when a component is created or updated for the first time.
>- Custom constructors are prohibited for components.
## Example<a name="section84921442616"></a> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - The build method must be defined for a custom component.
>
> - Custom constructors are prohibited for custom components.
The following code illustrates how to create a custom component named **MyComponent**:
The following code illustrates how to create a custom component named MyComponent:
``` ```
@Component @Component
...@@ -39,9 +36,11 @@ struct MyComponent { ...@@ -39,9 +36,11 @@ struct MyComponent {
} }
``` ```
The **build** method of **MyComponent** is executed during initial rendering. When the component status changes, the **build** method will be executed again.
The following code illustrates how to use **MyComponent**: The build method of MyComponent is executed during initial rendering. When the component status changes, the build method will be executed again.
The following code illustrates how to use MyComponent:
``` ```
@Component @Component
...@@ -56,7 +55,8 @@ struct ParentComponent { ...@@ -56,7 +55,8 @@ struct ParentComponent {
} }
``` ```
**MyComponent** can be embedded multiple times and can be nested in different components, as shown in the code below:
MyComponent can be applied multiple times and reused in different components, as shown in the code below:
``` ```
@Component @Component
...@@ -85,4 +85,3 @@ struct ParentComponent { ...@@ -85,4 +85,3 @@ struct ParentComponent {
} }
} }
``` ```
# @CustomDialog<a name="EN-US_TOPIC_0000001192355895"></a> # @CustomDialog
The @CustomDialog decorator is used to decorate custom pop-up dialog boxes.
The **@CustomDialog** decorator is used to decorate custom pop-up dialog boxes.
``` ```
// custom-dialog-demo.ets // custom-dialog-demo.ets
...@@ -46,4 +49,3 @@ struct CustomDialogUser { ...@@ -46,4 +49,3 @@ struct CustomDialogUser {
} }
} }
``` ```
# @Entry<a name="EN-US_TOPIC_0000001110788998"></a> # @Entry
The custom component decorated by **@Entry** functions as the default entry component of the respective page. When the page is loaded, the custom component decorated by **@Entry** is created and displayed first.
>![](../public_sys-resources/icon-note.gif) **NOTE:** The custom component decorated by @Entry functions as the default entry component of the respective page. When the page is loaded, the custom component decorated by @Entry is created and displayed first.
>A source file can contain at most one custom component decorated by **@Entry**.
## Example<a name="section0615954173414"></a>
Example of using **@Entry**: > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> A source file can contain at most one custom component decorated by @Entry.
Example of using @Entry:
``` ```
// Only MyComponent decorated by @Entry is rendered and displayed. "hello world" is displayed, but "goodbye" is not displayed. // Only MyComponent decorated by @Entry is rendered and displayed. "hello world" is displayed, but "goodbye" is not displayed.
...@@ -32,4 +33,3 @@ struct HideComponent { ...@@ -32,4 +33,3 @@ struct HideComponent {
} }
} }
``` ```
# @Extend<a name="EN-US_TOPIC_0000001134698822"></a> # @Extend
The **@Extend** decorator adds new attribute functions to preset components, such as **<Text\>**, **<Column\>**, and **<Button\>**. You can use the **@Extend** decorator to quickly define and reuse the custom styles of a component. The @Extend decorator adds new attribute functions to preset components, such as &lt;Text&gt;, &lt;Column&gt;, and &lt;Button&gt;. You can use the @Extend decorator to quickly define and reuse the custom styles of a component.
``` ```
@Extend(Text) function fancy(fontSize: number) { @Extend(Text) function fancy(fontSize: number) {
...@@ -23,6 +23,4 @@ struct FancyUse { ...@@ -23,6 +23,4 @@ struct FancyUse {
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![img](public_sys-resources/icon-note.gif) **NOTE**: The @Extend decorator cannot be used in the struct definition of a custom component.
>The **@Extend** decorator cannot be used in the struct definition of a custom component. \ No newline at end of file
# @Preview<a name="EN-US_TOPIC_0000001124516048"></a> # @Preview
Custom components decorated by **@Preview** can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by **@Preview** are created and displayed.
>![](../public_sys-resources/icon-note.gif) **NOTE:** Custom components decorated by @Preview can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by @Preview are created and displayed.
>In a source file, at most one custom component can be decorated by **@Preview**.
## Example<a name="section2270154810523"></a>
Example of using **@Preview**: > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> In a source file, at most one custom component can be decorated by @Preview.
Example of using @Preview:
``` ```
// Display only Hello Component1 on the PC preview. The content under MyComponent is displayed on the real device. // Display only Hello Component1 on the PC preview. The content under MyComponent is displayed on the real device.
...@@ -57,4 +58,3 @@ struct Component2 { ...@@ -57,4 +58,3 @@ struct Component2 {
} }
} }
``` ```
# @Styles
The @Styles decorator adds new attribute functions to basic components, such as &lt;Text&gt;, &lt;Column&gt;, and &lt;Button&gt;. Currently, @Styles supports only universal attributes. You can use the @Styles decorator to quickly define and reuse the custom styles of a component.
@Styles can be defined inside or outside a component. When it is defined outside a component, the keyword function must be included.
```
@Styles function globalFancy() {
.backgroundColor(Color.Red)
}
@Entry
@Component
struct FancyUse {
@Styles componentFancy() {
.backgroundColor(Color.Blue)
}
build() {
Column({ space: 10 }) {
Text("Fancy")
.globalFancy()
.width(100)
.height(100)
.fontSize(30)
Text("Fancy")
.componentFancy()
.width(100)
.height(100)
.fontSize(30)
}
}
}
```
@Styles can also be used inside the StateStyles attribute to assign state-specific attributes to components.
In StateStyles, styles defined outside the component can be directly called. However, the keyword this must be used to call styles defined in the component.
```
@Styles function globalFancy() {
.width(100)
.height(100)
}
@Entry
@Component
struct FancyUse {
@Styles function componentFancy() {
.width(50)
.height(50)
}
build() {
Row({ space: 10 }) {
Button() {
Text("Fancy")
}
.stateStyles({
normal: {
.width(80)
.height(80)
},
disabled: this.componentFancy,
pressed: globalFancy
})
}
}
}
```
# Componentization<a name="EN-US_TOPIC_0000001110948890"></a>
- **[@Component](ts-component-based-component.md)**
- **[@Entry](ts-component-based-entry.md)**
- **[@Preview](ts-component-based-preview.md)**
- **[@Builder](ts-component-based-builder.md)**
- **[@Extend](ts-component-based-extend.md)**
- **[@CustomDialog](ts-component-based-customdialog.md)**
# Example: Component Creation and Re-Initialization<a name="EN-US_TOPIC_0000001110788992"></a> # Component Creation and Re-initialization
## Initial Creation and Rendering
1. Create the parent component ParentComp.
2. Locally initialize the state variable isCountDown of ParentComp.
3. Execute the build function of ParentComp.
4. Create a preset &lt;Column&gt; component.
1. Create a preset &lt;Text&gt; component, set the text content to be displayed, and add the &lt;Text&gt; component instance to the &lt;Column&gt; component.
2. Create the component on the true branch based on the if condition.
1. Create a preset &lt;Image&gt; component and set the image source address.
2. Create a TimerComponent using the given constructor.
1. Create a TimerComponent object.
2. Initialize the values of member variables locally.
3. Use the parameters provided by the TimerComponent constructor to update the values of member variables.
4. Execute the aboutToAppear function of TimerComponent.
5. Execute the build function of TimerComponent to create the corresponding UI description structure.
3. Create a preset &lt;Button&gt; component and set the corresponding content.
## Status Update
When a user clicks a button:
1. The value of the isCountDown state variable of ParentComp is changed to false.
2. The build function of ParentComp is executed.
3. The preset &lt;Column&gt; component is reused by the framework and reinitialized.
4. The child components of &lt;Column&gt; reuse and reinitialize the objects in the memory.
1. Reuse the preset &lt;Text&gt; component after re-initializing the component using new text content.
2. Reuse the component on the false branch based on the if condition.
1. Destroy the components on the original true branch as these components are no longer used.
1. Destroy the created preset &lt;image&gt; component instance.
2. Destroy the TimerComponent component instance, and call the aboutToDisappear function.
2. Create components on the false branch.
1. Create a preset &lt;Image&gt; component and set the image source address.
2. Create a TimerComponent again using the given constructor.
3. Initialize the newly created TimerComponent and call the aboutToAppear and build functions.
3. Reuse the preset &lt;Button&gt; component, with the new image source address.
## Example
``` ```
@Entry @Entry
...@@ -16,7 +64,7 @@ struct ParentComp { ...@@ -16,7 +64,7 @@ struct ParentComp {
TimerComponent({counter: 0, changePerSec: +1, showInColor: Color.Black }) TimerComponent({counter: 0, changePerSec: +1, showInColor: Color.Black })
} }
Button(this.isCountDown ? 'Swtich to Stopwatch' : 'Switch to Count Down') Button(this.isCountDown ? 'Swtich to Stopwatch' : 'Switch to Count Down')
.onClick(() => {this.isCountDown = !this.isCountDown}) .onClick(() =&gt; {this.isCountDown = !this.isCountDown})
} }
} }
} }
...@@ -35,56 +83,14 @@ struct TimerComponent { ...@@ -35,56 +83,14 @@ struct TimerComponent {
} }
aboutToAppear() { aboutToAppear() {
this.timerId = setInterval(() => {this.counter += this.changePerSec}, 1000) this.timerId = setInterval(() =&gt; {this.counter += this.changePerSec}, 1000)
} }
aboutToDisappear() { aboutToDisappear() {
if (this.timerId > 0) { if (this.timerId &gt; 0) {
clearTimeout(this.timerId) clearTimeout(this.timerId)
this.timerId = -1 this.timerId = -1
} }
} }
} }
``` ```
## Initial Creation and Rendering<a name="section136047306160"></a>
1. Create the parent component **ParentComp**.
2. Locally initialize the state variable **isCountDown** of **ParentComp**.
3. Execute the **build** function of **ParentComp**.
4. Create a preset **<Column\>** component.
1. Create a preset **<Text\>** component, set the text content to be displayed, and add the **<Text\>** component instance to the **<Column\>** component.
2. Create the component on the **true** branch based on the **if** condition.
1. Create a preset **<Image\>** component and set the image source address.
2. Create a **TimerComponent** using the given constructor.
1. Create a **TimerComponent** object.
2. Initialize the values of member variables locally.
3. Use the parameters provided by the **TimerComponent** constructor to update the values of member variables.
4. Execute the **aboutToAppear** function of **TimerComponent**.
5. Execute the **build** function of **TimerComponent** to create the corresponding UI description structure.
3. Create a preset **<Button\>** component and set the corresponding content.
## Status Update<a name="section157507235171"></a>
When a user clicks a button:
1. The value of the **isCountDown** state variable of **ParentComp** is changed to **false**.
2. The **build** function of **ParentComp** is executed.
3. The preset **<Column\>** component is reused by the framework and reinitialized.
4. The child components of **<Column\>** reuse and reinitialize the objects in the memory.
1. Reuse the preset **<Text\>** component after re-initializing the component using new text content.
2. Reuse the component on the **false** branch based on the **if** condition.
1. Destroy the components on the original **true** branch as these components are no longer used.
1. Destroy the created preset **<image\>** component instance.
2. Destroy the **TimerComponent** component instance, and call the **aboutToDisappear** function.
2. Create components on the **false** branch.
1. Create a preset **<Image\>** component and set the image source address.
2. Create a **TimerComponent** again using the given constructor.
3. Initialize the newly created **TimerComponent** and call the **aboutToAppear** and **build** functions.
3. Reuse the preset **<Button\>** component, with the new image source address.
# @Link<a name="EN-US_TOPIC_0000001110948894"></a> # @Link
Two-way binding can be established between the **@Link** decorated variable and the **@State** decorated variable of the parent component. The **@Link** data has the following features:
- **Support for multiple types**: The value of the **@Link** decorated variable can be of the same type as the **@State** decorated variable; that is, the value can be of the following types: **class**, **number**, **string**, **boolean**, or arrays of these types. Two-way binding can be established between the @Link decorated variable and the @State decorated variable of the parent component. The @Link data has the following features:
- **Private**: Data is accessed only within the component.
- **Single data source**: The variable of the parent component for initializing the **@Link** decorated variable must be the **@State** decorated variable.
- **Two-way binding**: When a child component changes the **@Link** decorated variable, the **@State** decorated variable of its parent component is also changed.
- **Support for initialization with the variable reference passed to the @Link decorated variable**: When creating a new instance of the component, you must use the naming parameter to initialize all **@Link** decorated variables. The **@Link** decorated variable can be initialized by using the reference of the **@State** or **@Link** decorated variable. Wherein, the **@State** decorated variable can be referenced using the '**$**' operator.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The **@Link** decorated variable cannot be initialized within the component.
## Simple Type Example<a name="section19793192619582"></a> - Support for multiple types: The value of the @Link decorated variable can be of the same type as the @State decorated variable; that is, the value can be of the following types: class, number, string, boolean, or arrays of these types.
- Private: Data is accessed only within the component.
- Single data source: The variable of the parent component for initializing the @Link decorated variable must be the @State decorated variable.
- Two-way binding: When a child component changes the @Link decorated variable, the @State decorated variable of its parent component is also changed.
- Support for initialization with the variable reference passed to the @Link decorated variable: When creating a new instance of the component, you must use the naming parameter to initialize all @Link decorated variables. The @Link decorated variable can be initialized by using the reference of the @State or @Link decorated variable. Wherein, the @State decorated variable can be referenced using the '$' operator.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> The @Link decorated variable cannot be initialized within the component.
## Simple Type Example
``` ```
@Entry @Entry
...@@ -41,9 +50,11 @@ struct PlayButton { ...@@ -41,9 +50,11 @@ struct PlayButton {
} }
``` ```
The **@Link** semantics are derived from the '**$**' operator. In other words, **$isPlaying** is the two-way binding of the internal state **this.isPlaying**. When you click **PlayButton**, the **<Image\>** and **<Text\>** components of **PlayButton** are refreshed at the same time. The @Link semantics are derived from the '$' operator. In other words, $isPlaying is the two-way binding of the internal state this.isPlaying. When you click PlayButton, the &lt;Image&gt; and &lt;Text&gt; components of PlayButton are refreshed at the same time.
## Complex Type Example
## Complex Type Example<a name="section2921131712010"></a>
``` ```
@Entry @Entry
...@@ -80,9 +91,11 @@ struct Child { ...@@ -80,9 +91,11 @@ struct Child {
} }
``` ```
In the example above, click **Button1** and **Button2** to change the list of text items displayed in the parent component. In the example above, click Button1 and Button2 to change the list of text items displayed in the parent component.
## Example of Using @Link, @State, and @Prop Together
## Example of Using @Link, @State, and @Prop Together<a name="section17490315415"></a>
``` ```
@Entry @Entry
...@@ -118,8 +131,8 @@ struct ChildB { ...@@ -118,8 +131,8 @@ struct ChildB {
} }
``` ```
In the preceding example, **ParentView** contains two child components: **ChildA** and **ChildB**. They are initialized by the state variable **counter** of **ParentView**. In the preceding example, ParentView contains two child components: ChildA and ChildB. They are initialized by the state variable counter of ParentView.
- **ChildB** uses **@Link** to establish two-way state binding. When the value of the **counterRef** state variable is changed in **ChildB**, the change is synchronized to **ParentView** and **ChildA**. - ChildB uses @Link to establish two-way state binding. When the value of the counterRef state variable is changed in ChildB, the change is synchronized to ParentView and ChildA.
- **ChildA** uses **@Prop** to establish one-way state binding from **ParentView** to itself. When **ChildA** changes the state, it is re-rendered, but the change is not updated to **ParentView** or **ChildB**.
- ChildA uses @Prop to establish one-way state binding from ParentView to itself. When ChildA changes the state, it is re-rendered, but the change is not updated to ParentView or ChildB.
# @Prop<a name="EN-US_TOPIC_0000001157388853"></a> # @Prop
**@Prop** and **@State** have the same semantics but different initialization modes. Variables decorated by **@Prop** must be initialized using the **@State** decorated variable provided by their parent components. The **@Prop** decorated variable can be modified in the component, but the modification is not updated to the parent component; that is, **@Prop** uses unidirectional data binding.
The **@Prop** state data has the following features: @Prop and @State have the same semantics but different initialization modes. Variables decorated by @Prop must be initialized using the @State decorated variable provided by their parent components. The @Prop decorated variable can be modified in the component, but the modification is not updated to the parent component; that is, @Prop uses one-way data binding.
- **Support for simple types**: Only the following simple types are supported: **number**, **string**, and **boolean**.
- **Private**: Data is accessed only within the component.
- **Support for multiple instances**: A component can have multiple attributes decorated by **@Prop**.
- **Support for initialization with a value passed to the @Prop decorated variable**: When a new instance of the component is created, all **@Prop** decorated variables must be initialized. Initialization inside the component is not supported.
## Example<a name="section599175705019"></a> The @Prop state data has the following features:
- Support for simple types: The number, string, and boolean types are supported.
- Private: Data is accessed only within the component.
- Support for multiple instances: A component can have multiple attributes decorated by @Prop.
- Support for initialization with a value passed to the @Prop decorated variable: When a new instance of the component is created, all @Prop decorated variables must be initialized. Initialization inside the component is not supported.
## Example
``` ```
@Entry @Entry
...@@ -29,10 +37,7 @@ struct ParentComponent { ...@@ -29,10 +37,7 @@ struct ParentComponent {
}.onClick(() => { }.onClick(() => {
this.countDownStartValue -= 1 this.countDownStartValue -= 1
}) })
// When creating a child component, you must provide the initial value of its @Prop decorated variable in the constructor parameter and initialize the regular variable CostOfOneAttump (not Prop).
// when creatng ChildComponent, the initial value of its @Prop variable must be supplied
// in a named constructor parameter
// also regular costOfOneAttempt (non-Prop) variable is initialied
CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2}) CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2})
} }
} }
...@@ -61,8 +66,7 @@ struct CountDownComponent { ...@@ -61,8 +66,7 @@ struct CountDownComponent {
} }
``` ```
In the preceding example, when you press **+1** or **-1**, the status of the parent component changes and the **build** method is executed again. In this case, a new **CountDownComponent** is created. The **countDownStartValue** property of the parent component is used to initialize the **@Prop** decorated variable of the child component. When you touch the **Try again** button of the child component, the value of the **count** variable decorated by **@Prop** is changed. As a result, the **CountDownComponent** is rendered again. However, the change of the **count** value does not affect the **countDownStartValue** value of the parent component. In the preceding example, when you press +1 or -1, the status of the parent component changes and the build method is executed again. In this case, a new CountDownComponent is created. The countDownStartValue property of the parent component is used to initialize the @Prop decorated variable of the child component. When you tap the Try again button of the child component, the value of the @Prop decorated variable count is changed. As a result, the CountDownComponent is rendered again. However, the change of the count value does not affect the countDownStartValue value of the parent component.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>When a new component instance is created, all its **@Prop** decorated variables must be initialized.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> When a new component instance is created, all its @Prop decorated variables must be initialized.
# @State<a name="EN-US_TOPIC_0000001157228861"></a> # @State
The **@State** decorated variable is the internal state data of the component. When the state data is modified, the** build** method of the component is called to refresh the UI.
The **@State** data has the following features: The @State decorated variable is the internal state data of the component. When the state data is modified, the build method of the component is called to refresh the UI.
- **Support for multiple types**: The following types are supported: strong types by value and by reference, including **class**, **number**, **boolean**, **string**, as well as arrays of these types, that is, **Array<class\>**, **Array<string\>**, **Array<boolean\>**, and **Array<number\>**. **object** and **any** are not allowed.
- **Support for multiple instances**: Multiple instances can coexist in a component. The internal state data of different instances is independent.
- **Internal private**: An attribute marked with **@State** cannot be directly modified outside the component. Its lifecycle depends on the component where it is located.
- **Local initialization required**: Initial values must be allocated to all **@State** decorated variables through the initialization process. Otherwise, they may become undefined in the framework.
- **Support for setting of initial attribute values based on the state variable name**: When creating a component instance, you can explicitly specify the initial value of the **@State** decorated attribute based on the variable name.
## Simple Example of @State Decorated Attribute<a name="section1943814324316"></a> The @State data has the following features:
- Support for multiple types: The following types are supported: strong types by value and by reference, including class, number, boolean, string, as well as arrays of these types, that is, Array&lt;class&gt;, Array&lt;string&gt;, Array&lt;boolean&gt;, and Array&lt;number>. object and any are not allowed.
- Support for multiple instances: Multiple instances can coexist in a component. The internal state data of different instances is independent.
- Private: An attribute marked with @State can only be accessed within the component.
- Local initialization required: Initial values must be allocated to all @State decorated variables through the initialization process. Otherwise, they may become undefined in the framework.
- Support for setting of initial attribute values based on the state variable name: When creating a component instance, you can explicitly specify the initial value of the @State decorated attribute based on the variable name.
## Simple Example of @State Decorated Attribute
``` ```
@Entry @Entry
...@@ -33,7 +42,9 @@ struct MyComponent { ...@@ -33,7 +42,9 @@ struct MyComponent {
} }
``` ```
## Complex Example of @State Decorated Variable<a name="section17881156184313"></a>
## Complex Example of @State Decorated Variable
``` ```
// Customize the status data class. // Customize the status data class.
...@@ -81,14 +92,16 @@ struct MyComponent { ...@@ -81,14 +92,16 @@ struct MyComponent {
} }
``` ```
In the preceding example: In the preceding example:
- Two **@State** decorated variables, **count** and **title**, have been defined for **MyComponent**. If the value of **count** or **title** changes, the **build** method of **MyComponent** needs to be called to render the component again.
- The **EntryComponent** has multiple **MyComponent** instances. The internal status change of the first **MyComponent** does not affect the second **MyComponent**. - Two @State decorated variables, count and title, have been defined for MyComponent. If the value of count or title changes, the build method of MyComponent needs to be called to render the component again.
- When creating a **MyComponent** instance, initialize the variables in the component based on the variable name. For example:
- The EntryComponent has multiple MyComponent instances. The internal status change of the first MyComponent does not affect the second MyComponent.
- When creating a MyComponent instance, initialize the variables in the component based on the variable name. For example:
``` ```
MyComponent({title: {value: 'Hello, World 2'}, count: 7}) MyComponent({title: {value: 'Hello, World 2'}, count: 7})
``` ```
# Configuration with Mandatory Parameters<a name="EN-US_TOPIC_0000001110948900"></a> # Configuration with Mandatory Parameters
If the API definition of a component contains any mandatory parameter, set the parameters in the parentheses next to the component. Use constants to assign values to the parameters.
If the API definition of a component contains mandatory construction parameters, the parameters must be configured in the brackets **\(\)** next to the component. You can use constants to assign values to parameters.
Examples: Examples:
Set the mandatory parameter **src** of the **<Image\>** component as follows:
``` - Set the mandatory parameter src of the &lt;Image&gt; component as follows:
Image('http://xyz/a.jpg')
```
Set the mandatory parameter **content** of the **<Text\>** component as follows: ```
Image('http://xyz/a.jpg')
```
```
Text('123')
```
You can also use variables or expressions to assign values to parameters. The result type returned by an expression must meet the parameter type requirements. - Set the mandatory parameter content of the &lt;Text&gt; component as follows:
```
Text('123')
```
To pass a variable or expression to construct the **Image** and **Text** components:
You can also use variables or expressions to assign values to parameters. The result type returned by an expression must meet the parameter type requirements. For example, to pass a variable or expression to construct the Image and Text components:
``` ```
// imagePath, where imageUrl is a private data variable defined in the component. // imagePath, where imageUrl is a private data variable defined in the component.
...@@ -29,4 +32,3 @@ Image('http://' + this.imageUrl) ...@@ -29,4 +32,3 @@ Image('http://' + this.imageUrl)
// features of the corresponding language. This specification is not limited. // features of the corresponding language. This specification is not limited.
Text(`count: ${this.count}`) Text(`count: ${this.count}`)
``` ```
# Custom Component Initialization<a name="EN-US_TOPIC_0000001110948904"></a> # Initialization of Custom Components' Member Variables
This section describes the rules for initializing component state variables.
The member variables of a component can be initialized in either of the following ways: The member variables of a component can be initialized in either of the following ways:
- Local initialization. For example: - Local initialization. For example:
``` ```
...@@ -19,180 +19,59 @@ The member variables of a component can be initialized in either of the followin ...@@ -19,180 +19,59 @@ The member variables of a component can be initialized in either of the followin
The allowed method depends on the decorator of the state variable, as shown in the following table. The allowed method depends on the decorator of the state variable, as shown in the following table.
<a name="table1130mcpsimp"></a>
<table><thead align="left"><tr id="row1136mcpsimp"><th class="cellrowborder" valign="top" width="27%" id="mcps1.1.4.1.1"><p id="p1138mcpsimp"><a name="p1138mcpsimp"></a><a name="p1138mcpsimp"></a>Decorator Type</p> | Decorator Type | Local Initialization | Initialization Using Constructor Parameters |
</th> | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.1.4.1.2"><p id="p1140mcpsimp"><a name="p1140mcpsimp"></a><a name="p1140mcpsimp"></a>Local Initialization</p> | @State | Mandatory | Optional |
</th> | @Prop | Forbidden | Mandatory |
<th class="cellrowborder" valign="top" width="53%" id="mcps1.1.4.1.3"><p id="p1142mcpsimp"><a name="p1142mcpsimp"></a><a name="p1142mcpsimp"></a>Initialization Using Constructor Parameters</p> | @Link | Forbidden | Mandatory |
</th> | @StorageLink | Mandatory | Forbidden |
</tr> | @StorageProp | Mandatory | Forbidden |
</thead> | @Provide | Mandatory | Optional |
<tbody><tr id="row1143mcpsimp"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p1145mcpsimp"><a name="p1145mcpsimp"></a><a name="p1145mcpsimp"></a>@State</p> | @Consume | Forbidden | Forbidden |
</td> | @ObjectLink | Forbidden | Mandatory |
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p1147mcpsimp"><a name="p1147mcpsimp"></a><a name="p1147mcpsimp"></a>Mandatory</p> | Normal member variable | Recommended | Optional |
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1149mcpsimp"><a name="p1149mcpsimp"></a><a name="p1149mcpsimp"></a>Optional</p>
</td>
</tr>
<tr id="row1150mcpsimp"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p1152mcpsimp"><a name="p1152mcpsimp"></a><a name="p1152mcpsimp"></a>@Prop</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p1154mcpsimp"><a name="p1154mcpsimp"></a><a name="p1154mcpsimp"></a>Forbidden</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1156mcpsimp"><a name="p1156mcpsimp"></a><a name="p1156mcpsimp"></a>Mandatory</p>
</td>
</tr>
<tr id="row1157mcpsimp"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p1159mcpsimp"><a name="p1159mcpsimp"></a><a name="p1159mcpsimp"></a>@Link</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p1161mcpsimp"><a name="p1161mcpsimp"></a><a name="p1161mcpsimp"></a>Forbidden</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1163mcpsimp"><a name="p1163mcpsimp"></a><a name="p1163mcpsimp"></a>Mandatory</p>
</td>
</tr>
<tr id="row1368143713213"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p668183713214"><a name="p668183713214"></a><a name="p668183713214"></a>@StorageLink</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p13685378329"><a name="p13685378329"></a><a name="p13685378329"></a>Mandatory</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p4681437173219"><a name="p4681437173219"></a><a name="p4681437173219"></a>Forbidden</p>
</td>
</tr>
<tr id="row147015402328"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p8471134011327"><a name="p8471134011327"></a><a name="p8471134011327"></a>@StorageProp</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p164711040143213"><a name="p164711040143213"></a><a name="p164711040143213"></a>Mandatory</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p11471740133216"><a name="p11471740133216"></a><a name="p11471740133216"></a>Forbidden</p>
</td>
</tr>
<tr id="row134917432323"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p8349843183215"><a name="p8349843183215"></a><a name="p8349843183215"></a>@Provide</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p4349114315324"><a name="p4349114315324"></a><a name="p4349114315324"></a>Mandatory</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p19349743143218"><a name="p19349743143218"></a><a name="p19349743143218"></a>Optional</p>
</td>
</tr>
<tr id="row121451446173219"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p141451046113211"><a name="p141451046113211"></a><a name="p141451046113211"></a>@Consume</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p1514564683212"><a name="p1514564683212"></a><a name="p1514564683212"></a>Forbidden</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1145346183214"><a name="p1145346183214"></a><a name="p1145346183214"></a>Forbidden</p>
</td>
</tr>
<tr id="row1489554183914"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p1789513415395"><a name="p1789513415395"></a><a name="p1789513415395"></a>@ObjectLink</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p489594133916"><a name="p489594133916"></a><a name="p489594133916"></a>Forbidden</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1389504123918"><a name="p1389504123918"></a><a name="p1389504123918"></a>Mandatory</p>
</td>
</tr>
<tr id="row1164mcpsimp"><td class="cellrowborder" valign="top" width="27%" headers="mcps1.1.4.1.1 "><p id="p1166mcpsimp"><a name="p1166mcpsimp"></a><a name="p1166mcpsimp"></a>Normal member variable</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.1.4.1.2 "><p id="p1168mcpsimp"><a name="p1168mcpsimp"></a><a name="p1168mcpsimp"></a>Recommended</p>
</td>
<td class="cellrowborder" valign="top" width="53%" headers="mcps1.1.4.1.3 "><p id="p1170mcpsimp"><a name="p1170mcpsimp"></a><a name="p1170mcpsimp"></a>Optional</p>
</td>
</tr>
</tbody>
</table>
As indicated by the preceding table: As indicated by the preceding table:
- The **@State** decorated variable needs to be initialized locally. The initial value can be overwritten by the constructor parameter.
- The **@Prop** and **@Link** decorated variables must be initialized only by constructor parameters. - The @State decorated variables need to be initialized locally. The initial value can be overwritten by the constructor parameter.
- The @Prop and @Link decorated variables must be initialized only by constructor parameters.
Comply with the following rules when using constructors to initialize member variables: Comply with the following rules when using constructors to initialize member variables:
<a name="table1176mcpsimp"></a>
<table><thead align="left"><tr id="row1184mcpsimp"><th class="cellrowborder" valign="top" width="47.47474747474748%" id="mcps1.1.6.1.1"><p id="p1186mcpsimp"><a name="p1186mcpsimp"></a><a name="p1186mcpsimp"></a>From the Variable in the Parent Component (Below) to the Variable in the Child Component (Right)</p> | From the Variable in the Parent Component (Below) to the Variable in the Child Component (Right) | @State | @Link | @Prop | Normal Variable |
</th> | -------- | -------- | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="11.111111111111112%" id="mcps1.1.6.1.2"><p id="p1188mcpsimp"><a name="p1188mcpsimp"></a><a name="p1188mcpsimp"></a>@State</p> | @State | Not allowed | Allowed | Allowed | Allowed |
</th> | @Link | Not allowed | Allowed | Not recommended | Allowed |
<th class="cellrowborder" valign="top" width="12.121212121212123%" id="mcps1.1.6.1.3"><p id="p1190mcpsimp"><a name="p1190mcpsimp"></a><a name="p1190mcpsimp"></a>@Link</p> | @Prop | Not allowed | Not allowed | Allowed | Allowed |
</th> | @StorageLink | Not allowed | Allowed | Not allowed | Allowed |
<th class="cellrowborder" valign="top" width="12.121212121212123%" id="mcps1.1.6.1.4"><p id="p1192mcpsimp"><a name="p1192mcpsimp"></a><a name="p1192mcpsimp"></a>@Prop</p> | @StorageProp | Not allowed | Not allowed | Not allowed | Allowed |
</th> | Normal variable | Allowed | Not allowed | Not allowed | Allowed |
<th class="cellrowborder" valign="top" width="17.17171717171717%" id="mcps1.1.6.1.5"><p id="p1194mcpsimp"><a name="p1194mcpsimp"></a><a name="p1194mcpsimp"></a>Normal Variable</p>
</th>
</tr>
</thead>
<tbody><tr id="row1195mcpsimp"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p1197mcpsimp"><a name="p1197mcpsimp"></a><a name="p1197mcpsimp"></a>@State</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p1199mcpsimp"><a name="p1199mcpsimp"></a><a name="p1199mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p1201mcpsimp"><a name="p1201mcpsimp"></a><a name="p1201mcpsimp"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p1203mcpsimp"><a name="p1203mcpsimp"></a><a name="p1203mcpsimp"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p1205mcpsimp"><a name="p1205mcpsimp"></a><a name="p1205mcpsimp"></a>Allowed</p>
</td>
</tr>
<tr id="row1206mcpsimp"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p1208mcpsimp"><a name="p1208mcpsimp"></a><a name="p1208mcpsimp"></a>@Link</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p1210mcpsimp"><a name="p1210mcpsimp"></a><a name="p1210mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p1212mcpsimp"><a name="p1212mcpsimp"></a><a name="p1212mcpsimp"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p1214mcpsimp"><a name="p1214mcpsimp"></a><a name="p1214mcpsimp"></a>Not recommended</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p1216mcpsimp"><a name="p1216mcpsimp"></a><a name="p1216mcpsimp"></a>Allowed</p>
</td>
</tr>
<tr id="row1217mcpsimp"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p1219mcpsimp"><a name="p1219mcpsimp"></a><a name="p1219mcpsimp"></a>@Prop</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p1221mcpsimp"><a name="p1221mcpsimp"></a><a name="p1221mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p1223mcpsimp"><a name="p1223mcpsimp"></a><a name="p1223mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p1225mcpsimp"><a name="p1225mcpsimp"></a><a name="p1225mcpsimp"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p1227mcpsimp"><a name="p1227mcpsimp"></a><a name="p1227mcpsimp"></a>Allowed</p>
</td>
</tr>
<tr id="row240501152412"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p54063122418"><a name="p54063122418"></a><a name="p54063122418"></a>@StorageLink</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p8406161132415"><a name="p8406161132415"></a><a name="p8406161132415"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p440651122418"><a name="p440651122418"></a><a name="p440651122418"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p13406111162416"><a name="p13406111162416"></a><a name="p13406111162416"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p124067118242"><a name="p124067118242"></a><a name="p124067118242"></a>Allowed</p>
</td>
</tr>
<tr id="row88861156245"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p98861853246"><a name="p98861853246"></a><a name="p98861853246"></a>@StorageProp</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p588635122419"><a name="p588635122419"></a><a name="p588635122419"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p18886353244"><a name="p18886353244"></a><a name="p18886353244"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p15887557248"><a name="p15887557248"></a><a name="p15887557248"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p5887185182418"><a name="p5887185182418"></a><a name="p5887185182418"></a>Allowed</p>
</td>
</tr>
<tr id="row1228mcpsimp"><td class="cellrowborder" valign="top" width="47.47474747474748%" headers="mcps1.1.6.1.1 "><p id="p1230mcpsimp"><a name="p1230mcpsimp"></a><a name="p1230mcpsimp"></a>Normal variable</p>
</td>
<td class="cellrowborder" valign="top" width="11.111111111111112%" headers="mcps1.1.6.1.2 "><p id="p1232mcpsimp"><a name="p1232mcpsimp"></a><a name="p1232mcpsimp"></a>Allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.3 "><p id="p1234mcpsimp"><a name="p1234mcpsimp"></a><a name="p1234mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="12.121212121212123%" headers="mcps1.1.6.1.4 "><p id="p1236mcpsimp"><a name="p1236mcpsimp"></a><a name="p1236mcpsimp"></a>Not allowed</p>
</td>
<td class="cellrowborder" valign="top" width="17.17171717171717%" headers="mcps1.1.6.1.5 "><p id="p1238mcpsimp"><a name="p1238mcpsimp"></a><a name="p1238mcpsimp"></a>Allowed</p>
</td>
</tr>
</tbody>
</table>
As indicated by the preceding table: As indicated by the preceding table:
- The normal variable of the parent component can be used to initialize the **@State** decorated variable of the child component, but not the **@Link** or **@Prop** decorated variable.
- The **@State** decorated variable of the parent component can be used to initialize the **@Prop**, **@Link** \(using **$**\), or normal variables of the child component, but cannot initialize the **@State** decorated variable of the child component. - The normal variables of the parent component can be used to initialize the @State decorated variables of the child component, but not the @Link or @Prop decorated variables.
- The **@Link** decorated variable of the parent component can initialize the **@Link** decorated or normal variables of the child component. However, initializing the **@State** decorated member of the child component can result in a syntax error. In addition, initializing the **@Prop** decorated variable is not recommended.
- The **@Prop** decorated variable of the parent component can be used to initialize the normal variables or **@Prop** decorated variables of the child component, but not the **@State** or **@Link** decorated variables. - The @State decorated variable of the parent component can be used to initialize the @Prop, @Link (using $), or normal variables of the child component, but not the @State decorated variables of the child component.
- Passing **@StorageLink** and **@StorageProp** from the parent component to the child component is prohibited.
- The @Link decorated variables of the parent component can be used to initialize the @Link decorated or normal variables of the child component. However, initializing the @State decorated members of the child component can result in a syntax error. In addition, initializing the @Prop decorated variables is not recommended.
- The @Prop decorated variables of the parent component can be used to initialize the normal variables or @Prop decorated variables of the child component, but not the @State or @Link decorated variables.
- Passing @StorageLink and @StorageProp from the parent component to the child component is prohibited.
- In addition to the preceding rules, the TypeScript strong type rules need to be followed. - In addition to the preceding rules, the TypeScript strong type rules need to be followed.
## Example<a name="section1184926392"></a>
## Example
``` ```
@Entry @Entry
...@@ -218,7 +97,7 @@ struct CompA { ...@@ -218,7 +97,7 @@ struct CompA {
Row() { Row() {
CompB({bLink: $aLink, // valid init a @Link with reference of another @Link, CompB({bLink: $aLink, // valid init a @Link with reference of another @Link,
bProp: this.aState}) // valid init a @Prop with value of a @State bProp: this.aState}) // valid init a @Prop with value of a @State
CompB({aLink: $aState, // invalid: type mismatch expected ref to ClassA, provided reference to boolean CompB({aLink: $aState, // invalid: type missmatch expected ref to ClassA, provided reference to boolean
bProp: false}) // valid init a @Prop by constants value bProp: false}) // valid init a @Prop by constants value
} }
} }
...@@ -234,4 +113,3 @@ struct CompB { ...@@ -234,4 +113,3 @@ struct CompB {
} }
} }
``` ```
# Custom Component Lifecycle Callbacks<a name="EN-US_TOPIC_0000001110948896"></a> # Custom Component Lifecycle Callbacks
The lifecycle callbacks of a custom component are used to notify users of the lifecycle of the component. These callbacks are private and are invoked by the development framework at a specified time at runtime. They cannot be manually invoked from applications. The lifecycle callbacks of a custom component are used to notify users of the lifecycle of the component. These callbacks are private and are invoked by the development framework at a specified time at runtime. They cannot be manually invoked from applications.
## Lifecycle Callback Definition<a name="section1597015432486"></a>
<a name="table56583904911"></a> ## Lifecycle Callback Definition
<table><thead align="left"><tr id="row146581198495"><th class="cellrowborder" valign="top" width="14.84%" id="mcps1.1.3.1.1"><p id="p19658139114912"><a name="p19658139114912"></a><a name="p19658139114912"></a>Function</p>
</th> | Function | Description |
<th class="cellrowborder" valign="top" width="85.16%" id="mcps1.1.3.1.2"><p id="p06581592499"><a name="p06581592499"></a><a name="p06581592499"></a>Description</p> | -------- | -------- |
</th> | aboutToAppear | Invoked after a new instance of the custom component is created and before its build function is executed. You can change state variables in the aboutToAppear function. The change will take effect when you execute the build function next time. |
</tr> | aboutToDisappear | Invoked before the destructor of the custom component is consumed. Do not change state variables in the aboutToDisappear function as doing this can cause unexpected errors. For example, the modification of the @Link decorated variable may cause unstable application running. |
</thead> | onPageShow | Invoked when a page is displayed. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect. |
<tbody><tr id="row11658109194919"><td class="cellrowborder" valign="top" width="14.84%" headers="mcps1.1.3.1.1 "><p id="p9658109154912"><a name="p9658109154912"></a><a name="p9658109154912"></a>aboutToAppear</p> | onPageHide | Invoked when a page is hidden. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect. |
</td> | onBackPress | Invoked when a user clicks the back button. Only the custom components decorated by @Entry take effect.<br/>- The value true is returned if the page processes the return logic instead of performing page routing.<br/>- The value false is returned if the default return logic is used.<br/>- If no value is returned, the default return logic is used. |
<td class="cellrowborder" valign="top" width="85.16%" headers="mcps1.1.3.1.2 "><p id="p17851645015"><a name="p17851645015"></a><a name="p17851645015"></a>Invoked after a new instance of the custom component is created and before its <strong id="b5869734121610"><a name="b5869734121610"></a><a name="b5869734121610"></a>build</strong> function is executed.</p>
<p id="p7658596490"><a name="p7658596490"></a><a name="p7658596490"></a>You can change state variables in the <strong id="b99359017178"><a name="b99359017178"></a><a name="b99359017178"></a>aboutToAppear</strong> function. The change will take effect when you execute the <strong id="b157198921719"><a name="b157198921719"></a><a name="b157198921719"></a>build</strong> function next time.</p>
</td> ## Example
</tr>
<tr id="row1465811913499"><td class="cellrowborder" valign="top" width="14.84%" headers="mcps1.1.3.1.1 "><p id="p1665939124911"><a name="p1665939124911"></a><a name="p1665939124911"></a>aboutToDisappear</p>
</td>
<td class="cellrowborder" valign="top" width="85.16%" headers="mcps1.1.3.1.2 "><p id="p182511622115113"><a name="p182511622115113"></a><a name="p182511622115113"></a>Invoked before the destructor of the custom component is consumed.</p>
<p id="p15659199144918"><a name="p15659199144918"></a><a name="p15659199144918"></a>Do not change state variables in the <strong id="b113997361170"><a name="b113997361170"></a><a name="b113997361170"></a>aboutToDisappear</strong> function as doing this can cause unexpected errors. For example, the modification of the <strong id="b1438344751717"><a name="b1438344751717"></a><a name="b1438344751717"></a>@Link</strong> decorated variable may cause unstable application running.</p>
</td>
</tr>
<tr id="row1930416179282"><td class="cellrowborder" valign="top" width="14.84%" headers="mcps1.1.3.1.1 "><p id="p1430441792819"><a name="p1430441792819"></a><a name="p1430441792819"></a>onPageShow</p>
</td>
<td class="cellrowborder" valign="top" width="85.16%" headers="mcps1.1.3.1.2 "><p id="p16304131722812"><a name="p16304131722812"></a><a name="p16304131722812"></a>Invoked when a page is displayed. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by <strong id="b1464282018197"><a name="b1464282018197"></a><a name="b1464282018197"></a>@Entry</strong> take effect.</p>
</td>
</tr>
<tr id="row124040130281"><td class="cellrowborder" valign="top" width="14.84%" headers="mcps1.1.3.1.1 "><p id="p5404191372818"><a name="p5404191372818"></a><a name="p5404191372818"></a>onPageHide</p>
</td>
<td class="cellrowborder" valign="top" width="85.16%" headers="mcps1.1.3.1.2 "><p id="p1740410136287"><a name="p1740410136287"></a><a name="p1740410136287"></a>Invoked when a page is hidden. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by <strong id="b86916375193"><a name="b86916375193"></a><a name="b86916375193"></a>@Entry</strong> take effect.</p>
</td>
</tr>
<tr id="row914614415143"><td class="cellrowborder" valign="top" width="14.84%" headers="mcps1.1.3.1.1 "><p id="p1420710493489"><a name="p1420710493489"></a><a name="p1420710493489"></a>onBackPress</p>
</td>
<td class="cellrowborder" valign="top" width="85.16%" headers="mcps1.1.3.1.2 "><p id="p1020714916483"><a name="p1020714916483"></a><a name="p1020714916483"></a>Invoked when a user clicks the back button. Only the custom components decorated by <strong id="b117484422012"><a name="b117484422012"></a><a name="b117484422012"></a>@Entry</strong> take effect.</p>
<a name="ul02081949144816"></a><a name="ul02081949144816"></a><ul id="ul02081949144816"><li>The value <strong id="b15338151114203"><a name="b15338151114203"></a><a name="b15338151114203"></a>true</strong> is returned if the page processes the return logic instead of performing page routing.</li><li>The value <strong id="b186911429200"><a name="b186911429200"></a><a name="b186911429200"></a>false</strong> is returned if the default return logic is used.</li><li>If no value is returned, the default return logic is used.</li></ul>
</td>
</tr>
</tbody>
</table>
## Example<a name="section462551935217"></a>
``` ```
@Component @Component
...@@ -72,9 +46,10 @@ struct CountDownTimerComponent { ...@@ -72,9 +46,10 @@ struct CountDownTimerComponent {
} }
``` ```
The example above shows that lifecycle functions are critical for **CountDownTimerComponent** to manage its timer resources. Similar functions include loading resources asynchronously from the network. The example above shows that lifecycle functions are critical for CountDownTimerComponent to manage its timer resources. Similar functions include loading resources asynchronously from the network.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- Promise and asynchronous callback functions can be used in lifecycle functions, for example, network resource getters and timer setters.
>- Do not use **async await** in lifecycle functions.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - Promise and asynchronous callback functions can be used in lifecycle functions, for example, network resource getters and timer setters.
>
> - Do not use async await in lifecycle functions.
# Declarative Syntax<a name="EN-US_TOPIC_0000001187113070"></a>
- **[Overview](ts-syntax-intro.md)**
- **[General UI Description Specifications](ts-general-ui-description-specifications.md)**
- **[About UI State Management](ts-ui-state-management.md)**
- **[About Rendering Control Syntax](ts-rending-control-syntax.md)**
- **[About @Component](ts-a-deep-dive-into-component.md)**
- **[About Syntactic Sugar](ts-syntactic-sugar.md)**
# Declarative UI Description Specifications<a name="EN-US_TOPIC_0000001157388851"></a>
- **[Parameterless Configuration](ts-parameterless-configuration.md)**
- **[Configuration with Mandatory Parameters](ts-configuration-with-mandatory-parameters.md)**
- **[Attribution Configuration](ts-attribution-configuration.md)**
- **[Event Configuration](ts-event-configuration.md)**
- **[Child Component Configuration](ts-child-component-configuration.md)**
# Event Configuration<a name="EN-US_TOPIC_0000001157388863"></a> # Event Configuration
You can use event methods to configure events supported by components. You can use event methods to configure events supported by components.
- Example of using a lambda expression to configure the event of a component: - Example of using a lambda expression to configure the event of a component:
``` ```
...@@ -13,9 +15,7 @@ You can use event methods to configure events supported by components. ...@@ -13,9 +15,7 @@ You can use event methods to configure events supported by components.
``` ```
- Example of using an anonymous function expression to configure the event of a component: - When using an anonymous function expression to configure the event of a component, bind must be used to ensure that the contained components are referenced by this in the function body.
In this case, **bind** must be used to ensure that the contained components are referenced by **this** in the function body.
``` ```
// Counter is a private data variable defined in the component. // Counter is a private data variable defined in the component.
...@@ -38,5 +38,3 @@ You can use event methods to configure events supported by components. ...@@ -38,5 +38,3 @@ You can use event methods to configure events supported by components.
Button('add counter') Button('add counter')
.onClick(this.myClickHandler) .onClick(this.myClickHandler)
``` ```
# Directory Structure<a name="EN-US_TOPIC_0000001111581264"></a> # Directory Structure
The following figure shows the typical directory structure of the **eTS** module \(**entry/src/main**\) for an application with feature abilities \(FAs\).
![](figures/en-us_image_0000001251421931.png) The following figure shows the typical directory structure of the eTS module (entry/src/main) for an application with feature abilities (FAs).
![en-us_image_0000001222967752](figures/en-us_image_0000001222967752.png)
Functions of the files are as follows: Functions of the files are as follows:
- The Extended TypeScript \(eTS\) files that end with the **.ets** extension describe the UI layouts, styles, event interactions, and page logics.
- The Extended TypeScript (eTS) files that end with the .ets extension describe the UI layouts, styles, event interactions, and page logics.
Functions of the folders and files are as follows: Functions of the folders and files are as follows:
- The **app.ets** file manages global application logics and lifecycles.
- The **pages** directory stores all component pages.
- The **common** directory stores common code files, such as custom components and public methods.
>![](../public_sys-resources/icon-note.gif) **NOTE:** - The app.ets file manages global application logics and lifecycles.
>- TypeScript and JavaScript files can be imported as page files.
- The pages directory stores all component pages.
- The common directory stores common code files, such as custom components and public methods.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>
> TypeScript and JavaScript files can be imported as page files.
# Rules for Accessing Application Code Files<a name="EN-US_TOPIC_0000001158261215"></a> # Rules for Accessing Application Code Files
The application code files can be accessed in the following ways: The application code files can be accessed in the following ways:
- Use a relative path to reference the code file. For example, if the upper-level directory is **../common/utils/utils.ets**, use **./common/utils/utils.ets** for the current directory.
- Use the root path of the current module to reference the code file, for example, **common/utils/utils.ets**.
- Store common code files in the **common** directory.
## Example<a name="section14151172218568"></a> - Use a relative path to reference the code file. For example, if the upper-level directory is ../common/utils/utils.ets, use ./common/utils/utils.ets for the current directory.
- Use the root path of the current module to reference the code file, for example, common/utils/utils.ets.
- Store common code files in the common directory.
## Example
``` ```
import { FoodData, FoodList } from "../common/utils/utils.ets"; import { FoodData, FoodList } from "../common/utils/utils.ets";
...@@ -29,6 +35,7 @@ struct FoodCategoryList { ...@@ -29,6 +35,7 @@ struct FoodCategoryList {
Example for importing a code file: Example for importing a code file:
``` ```
//common/utils/utils.ets //common/utils/utils.ets
...@@ -64,4 +71,3 @@ export struct FoodList { ...@@ -64,4 +71,3 @@ export struct FoodList {
} }
} }
``` ```
# File Organization<a name="EN-US_TOPIC_0000001158141245"></a>
- **[Directory Structure](ts-framework-directory.md)**
- **[Rules for Accessing Application Code Files](ts-framework-file-access-rules.md)**
# "js" Tag<a name="EN-US_TOPIC_0000001158141247"></a> # "js" Tag
Configure the **"js"** tag in the [config.json](https://developer.harmonyos.com/en/docs/documentation/doc-guides/basic-config-file-overview-0000000000011951) file of your application. The **"js"** tag contains the instance name, page route, and window configuration information.
Configure the "js" tag in the config.json file of your application. The "js" tag contains the instance name, page route, and window configuration information.
<a name="table155mcpsimp"></a>
<table><thead align="left"><tr id="row163mcpsimp"><th class="cellrowborder" valign="top" width="16.831683168316832%" id="mcps1.1.6.1.1"><p id="p165mcpsimp"><a name="p165mcpsimp"></a><a name="p165mcpsimp"></a>Tag</p>
</th> | Tag | Type | Default Value | Mandatory | Description |
<th class="cellrowborder" valign="top" width="16.831683168316832%" id="mcps1.1.6.1.2"><p id="p167mcpsimp"><a name="p167mcpsimp"></a><a name="p167mcpsimp"></a>Type</p> | -------- | -------- | -------- | -------- | -------- |
</th> | name | string | default | Yes | Name of the eTS instance. |
<th class="cellrowborder" valign="top" width="14.52145214521452%" id="mcps1.1.6.1.3"><p id="p169mcpsimp"><a name="p169mcpsimp"></a><a name="p169mcpsimp"></a>Default Value</p> | pages | Array | - | Yes | Page route information. For details, see ["pages"](#pages). |
</th> | window | Object | - | No | Window configuration information. For details, see ["window"](#window). |
<th class="cellrowborder" valign="top" width="14.19141914191419%" id="mcps1.1.6.1.4"><p id="p171mcpsimp"><a name="p171mcpsimp"></a><a name="p171mcpsimp"></a>Mandatory</p> | mode | Object | - | No | Running type and syntax style of the JS component. For details, see ["mode"](#mode). |
</th>
<th class="cellrowborder" valign="top" width="37.62376237623762%" id="mcps1.1.6.1.5"><p id="p173mcpsimp"><a name="p173mcpsimp"></a><a name="p173mcpsimp"></a>Description</p>
</th> ## pages
</tr>
</thead> The "pages" defines the route information of each page's entry component. Each page consists of the page path and page name. The following is an example:
<tbody><tr id="row174mcpsimp"><td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.1 "><p id="p176mcpsimp"><a name="p176mcpsimp"></a><a name="p176mcpsimp"></a>name</p>
</td>
<td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.2 "><p id="p178mcpsimp"><a name="p178mcpsimp"></a><a name="p178mcpsimp"></a>string</p>
</td>
<td class="cellrowborder" valign="top" width="14.52145214521452%" headers="mcps1.1.6.1.3 "><p id="p180mcpsimp"><a name="p180mcpsimp"></a><a name="p180mcpsimp"></a>default</p>
</td>
<td class="cellrowborder" valign="top" width="14.19141914191419%" headers="mcps1.1.6.1.4 "><p id="p182mcpsimp"><a name="p182mcpsimp"></a><a name="p182mcpsimp"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="37.62376237623762%" headers="mcps1.1.6.1.5 "><p id="p184mcpsimp"><a name="p184mcpsimp"></a><a name="p184mcpsimp"></a>Name of the eTS instance.</p>
</td>
</tr>
<tr id="row185mcpsimp"><td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.1 "><p id="p187mcpsimp"><a name="p187mcpsimp"></a><a name="p187mcpsimp"></a>pages</p>
</td>
<td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.2 "><p id="p189mcpsimp"><a name="p189mcpsimp"></a><a name="p189mcpsimp"></a>Array</p>
</td>
<td class="cellrowborder" valign="top" width="14.52145214521452%" headers="mcps1.1.6.1.3 "><p id="p191mcpsimp"><a name="p191mcpsimp"></a><a name="p191mcpsimp"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="14.19141914191419%" headers="mcps1.1.6.1.4 "><p id="p193mcpsimp"><a name="p193mcpsimp"></a><a name="p193mcpsimp"></a>Yes</p>
</td>
<td class="cellrowborder" valign="top" width="37.62376237623762%" headers="mcps1.1.6.1.5 "><p id="p195mcpsimp"><a name="p195mcpsimp"></a><a name="p195mcpsimp"></a>Page route information. For details, see <a href="#section58191020141212">"pages"</a>.</p>
</td>
</tr>
<tr id="row1470193511315"><td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.1 "><p id="p8471103518319"><a name="p8471103518319"></a><a name="p8471103518319"></a>window</p>
</td>
<td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.2 "><p id="p8471163515311"><a name="p8471163515311"></a><a name="p8471163515311"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="14.52145214521452%" headers="mcps1.1.6.1.3 "><p id="p194719356314"><a name="p194719356314"></a><a name="p194719356314"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="14.19141914191419%" headers="mcps1.1.6.1.4 "><p id="p13471193511316"><a name="p13471193511316"></a><a name="p13471193511316"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="37.62376237623762%" headers="mcps1.1.6.1.5 "><p id="p2047153583114"><a name="p2047153583114"></a><a name="p2047153583114"></a>Window configuration information. For details, see <a href="#section051216429126">"window"</a>.</p>
</td>
</tr>
<tr id="row9971103313451"><td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.1 "><p id="p397173317458"><a name="p397173317458"></a><a name="p397173317458"></a>mode</p>
</td>
<td class="cellrowborder" valign="top" width="16.831683168316832%" headers="mcps1.1.6.1.2 "><p id="p18971183318456"><a name="p18971183318456"></a><a name="p18971183318456"></a>Object</p>
</td>
<td class="cellrowborder" valign="top" width="14.52145214521452%" headers="mcps1.1.6.1.3 "><p id="p497283354510"><a name="p497283354510"></a><a name="p497283354510"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="14.19141914191419%" headers="mcps1.1.6.1.4 "><p id="p597212332456"><a name="p597212332456"></a><a name="p597212332456"></a>No</p>
</td>
<td class="cellrowborder" valign="top" width="37.62376237623762%" headers="mcps1.1.6.1.5 "><p id="p19555836124"><a name="p19555836124"></a><a name="p19555836124"></a>Running type and syntax style of the JS component. For details, see <a href="#section187397018139">"mode"</a>.</p>
</td>
</tr>
</tbody>
</table>
## pages<a name="section58191020141212"></a>
The **"pages"** defines the route information of each page's entry component. Each page consists of the page path and page name. The following is an example:
``` ```
{ {
...@@ -75,33 +26,22 @@ The **"pages"** defines the route information of each page's entry component. ...@@ -75,33 +26,22 @@ The **"pages"** defines the route information of each page's entry component.
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- The first page in the **"pages"** list is the home page of the application. > - The first page in the "pages" list is the home page of the application.
>- The page name must not be a component name, for example, **Text.ets** or **Button.ets**. >
>- Each page file must contain the [page entry component](ts-component-based-entry.md) \(with the @Entry decoration\). > - The page name must not be a component name, for example, Text.ets or Button.ets.
>
## window<a name="section051216429126"></a> > - Each page file must contain the [page entry component](ts-component-based-entry.md) (with the @Entry decoration).
The **"window"** configures the view window. The following attributes can be configured:
## window
<a name="table12744175911317"></a>
<table><thead align="left"><tr id="row13744259131317"><th class="cellrowborder" valign="top" width="15.4015401540154%" id="mcps1.1.4.1.1"><p id="p574413592132"><a name="p574413592132"></a><a name="p574413592132"></a>Type</p> The "window" configures the view window. The following attributes can be configured:
</th>
<th class="cellrowborder" valign="top" width="12.56125612561256%" id="mcps1.1.4.1.2"><p id="p11745115916131"><a name="p11745115916131"></a><a name="p11745115916131"></a>Default Value</p> | Type | Default Value | Description |
</th> | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="72.03720372037205%" id="mcps1.1.4.1.3"><p id="p874513594137"><a name="p874513594137"></a><a name="p874513594137"></a>Description</p> | designWidth | - | Logical width of the view. The default value is 720. (The default value is 454 for wearables.) The logical width of the view determines the unit size of lpx. For example, if designWidth is 720 and the view width is 1440 physical pixels, 1 lpx is 2 physical pixels. For details, see [lpx](ts-pixel-units.md). |
</th>
</tr>
</thead>
<tbody><tr id="row157461359131320"><td class="cellrowborder" valign="top" width="15.4015401540154%" headers="mcps1.1.4.1.1 "><p id="p774614598137"><a name="p774614598137"></a><a name="p774614598137"></a>designWidth</p>
</td>
<td class="cellrowborder" valign="top" width="12.56125612561256%" headers="mcps1.1.4.1.2 "><p id="p77461359141312"><a name="p77461359141312"></a><a name="p77461359141312"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="72.03720372037205%" headers="mcps1.1.4.1.3 "><p id="p3740171951611"><a name="p3740171951611"></a><a name="p3740171951611"></a>Logical width of the view. The default value is <strong id="b171419193421"><a name="b171419193421"></a><a name="b171419193421"></a>720</strong>. (The default value is <strong id="b7750142412424"><a name="b7750142412424"></a><a name="b7750142412424"></a>454</strong> for wearables.) The logical width of the view determines the unit size of lpx. For example, if <strong id="b170015367467"><a name="b170015367467"></a><a name="b170015367467"></a>designWidth</strong> is <strong id="b1985740184615"><a name="b1985740184615"></a><a name="b1985740184615"></a>720</strong> and the view width is 1440 physical pixels, 1 lpx is 2 physical pixels. For details, see <a href="ts-pixel-units.md">lpx</a>.</p>
</td>
</tr>
</tbody>
</table>
``` ```
{ {
...@@ -113,45 +53,25 @@ The **"window"** configures the view window. The following attributes can be c ...@@ -113,45 +53,25 @@ The **"window"** configures the view window. The following attributes can be c
} }
``` ```
## mode<a name="section187397018139"></a>
## mode
The **"mode"** configures the running type and syntax style of a JS component. The following attributes are supported:
The "mode" configures the running type and syntax style of a JS component. The following attributes are supported:
<a name="table0991613141319"></a>
<table><thead align="left"><tr id="row399151341313"><th class="cellrowborder" valign="top" width="14.041404140414041%" id="mcps1.1.4.1.1"><p id="p599171361314"><a name="p599171361314"></a><a name="p599171361314"></a>Type</p> | Type | Default Value | Description |
</th> | -------- | -------- | -------- |
<th class="cellrowborder" valign="top" width="8.700870087008699%" id="mcps1.1.4.1.2"><p id="p16991313151310"><a name="p16991313151310"></a><a name="p16991313151310"></a>Default Value</p> | type | - | Running type of the JS component. The options are as follows:<br/>- pageAbility: Run the JS component in ability mode.<br/>- form: Run the JS component as a service widget. |
</th> | syntax | - | Syntax type of the JS component. The options are as follows:<br/>- hml: compiled in the .hml, .css, or .js style.<br/>- ets: compiled in the declarative syntax style. |
<th class="cellrowborder" valign="top" width="77.25772577257726%" id="mcps1.1.4.1.3"><p id="p14991813151318"><a name="p14991813151318"></a><a name="p14991813151318"></a>Description</p>
</th> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
</tr> > If type is set to form, syntax cannot be ets.
</thead>
<tbody><tr id="row1799112131130"><td class="cellrowborder" valign="top" width="14.041404140414041%" headers="mcps1.1.4.1.1 "><p id="p4991191321313"><a name="p4991191321313"></a><a name="p4991191321313"></a>type</p>
</td> ## Example
<td class="cellrowborder" valign="top" width="8.700870087008699%" headers="mcps1.1.4.1.2 "><p id="p299261331320"><a name="p299261331320"></a><a name="p299261331320"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="77.25772577257726%" headers="mcps1.1.4.1.3 "><p id="p3992121312135"><a name="p3992121312135"></a><a name="p3992121312135"></a>Running type of the JS component. The options are as follows:</p>
<a name="ul1937861914577"></a><a name="ul1937861914577"></a><ul id="ul1937861914577"><li><strong id="b75081241041"><a name="b75081241041"></a><a name="b75081241041"></a>pageAbility</strong>: Run the JS component in ability mode.</li><li><strong id="b168910358411"><a name="b168910358411"></a><a name="b168910358411"></a>form</strong>: Run the JS component as a service widget.</li></ul>
</td>
</tr>
<tr id="row123561551181712"><td class="cellrowborder" valign="top" width="14.041404140414041%" headers="mcps1.1.4.1.1 "><p id="p335605114177"><a name="p335605114177"></a><a name="p335605114177"></a>syntax</p>
</td>
<td class="cellrowborder" valign="top" width="8.700870087008699%" headers="mcps1.1.4.1.2 "><p id="p2356951151718"><a name="p2356951151718"></a><a name="p2356951151718"></a>-</p>
</td>
<td class="cellrowborder" valign="top" width="77.25772577257726%" headers="mcps1.1.4.1.3 "><p id="p435617515178"><a name="p435617515178"></a><a name="p435617515178"></a>Syntax type of the JS component. The options are as follows:</p>
<a name="ul12256182612583"></a><a name="ul12256182612583"></a><ul id="ul12256182612583"><li><strong id="b2366192115510"><a name="b2366192115510"></a><a name="b2366192115510"></a>hml</strong>: compiled in the .hml, .css, or .js style.</li><li><strong id="b144835462511"><a name="b144835462511"></a><a name="b144835462511"></a>ets</strong>: compiled in the declarative syntax style.</li></ul>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>If **type** is set to **form**, **syntax** cannot be **ets**.
## Example<a name="section5306141614133"></a>
config.json: config.json:
``` ```
{ {
"app": { "app": {
...@@ -183,4 +103,3 @@ config.json: ...@@ -183,4 +103,3 @@ config.json:
} }
} }
``` ```
# Framework Overview<a name="EN-US_TOPIC_0000001111421382"></a>
- **[File Organization](ts-framework-file.md)**
- **["js" Tag](ts-framework-js-tag.md)**
- **[Resource Access](ts-resource-access.md)**
- **[Pixel Units](ts-pixel-units.md)**
- **[Types](ts-types.md)**
# build Function<a name="EN-US_TOPIC_0000001157228879"></a> # build Function
The build function meets the definition of the Builder API and is used to define the declarative UI description of components. Components must comply with the preceding Builder API constraints. Custom or preset components are combined in declarative mode in the build method. The build method is called when a component is created or updated.
The **build** function meets the definition of the **Builder** API and is used to define the declarative UI description of components.
``` ```
interface Builder { interface Builder {
...@@ -8,3 +11,6 @@ interface Builder { ...@@ -8,3 +11,6 @@ interface Builder {
} }
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> The build method supports only composite components and uses the rendering control syntax.
# Basic Concepts<a name="EN-US_TOPIC_0000001215268053"></a> # Basic Concepts
The TypeScript-based declarative development paradigm provides a wide array of basic components, which can be combined and extended in a declarative manner to describe the UI of an application. It also provides basic data binding and event processing mechanisms to help you implement the application interaction logic. The TypeScript-based declarative development paradigm provides a wide array of basic components, which can be combined and extended in a declarative manner to describe the UI of an application. It also provides basic data binding and event processing mechanisms to help you implement the application interaction logic.
## HelloWorld Example<a name="section7816125610596"></a>
## HelloWorld Example
``` ```
// An example of displaying Hello World. After you click the button, Hello UI is displayed. // An example of displaying Hello World. After you click the button, Hello UI is displayed.
...@@ -20,7 +23,7 @@ struct Hello { ...@@ -20,7 +23,7 @@ struct Hello {
Button() { Button() {
Text('Click me') Text('Click me')
.fontColor(Color.Red) .fontColor(Color.Red)
}.onClick(() => { }.onClick(() =&gt; {
this.myText = 'UI' this.myText = 'UI'
}) })
.width(500) .width(500)
...@@ -30,14 +33,19 @@ struct Hello { ...@@ -30,14 +33,19 @@ struct Hello {
} }
``` ```
## Basic Concepts<a name="section1163410619"></a>
## Basic Concepts
The preceding sample code shows the structure of a simple page. It involves the following basic concepts: The preceding sample code shows the structure of a simple page. It involves the following basic concepts:
- **Decorator**: a special kind of declaration that can be applied to classes, structures, methods, and variables, and assigns special meanings to them. In the sample code, **@Entry**, **@Component**, and **@State** are decorators. - Decorator: a special kind of declaration that can be applied to classes, structures, methods, and variables. In the sample code, @Entry, @Component, and @State are decorators.
- **Custom component**: a reusable UI unit, which can be combined with other components. In the sample code, **struct Hello** decorated by **@Component** is a custom component.
- **UI description**: declaratively describes the UI structure. In the sample code, the block of code in the **build\(\)** method provides the UI description. - Custom component: a reusable UI unit, which can be combined with other components. In the sample code, struct Hello decorated by @Component is a custom component.
- **Built-in component**: the default basic or layout component preset in the framework. You can directly invoke these components, such as **<Column\>**, **<Text\>**, **<Divider\>**, and **<Button\>** components in the sample code.
- **Attribute method**: a method used to configure component attributes, such as **fontSize\(\)**, **width\(\)**, **height\(\)**, and **color\(\)**. - UI description: declaratively describes the UI structure. In the sample code, the block of code in the build() method provides the UI description.
- **Event method**: a method used to add the component response logic to an event. The logic is set through an event method, such as **onClick\(\)** for a button.
- Built-in component: the default basic or layout component preset in the framework. You can directly invoke these components, such as &lt;Column&gt;, &lt;Text&gt;, &lt;Divider&gt;, and &lt;Button&gt; components in the sample code.
- Attribute method: a method used to configure component attributes, such as fontSize(), width(), height(), and color().
- Event method: a method used to add the component response logic to an event. In the sample code, the onClick method is added for the Button component for defining the click response logic.
# General UI Description Specifications<a name="EN-US_TOPIC_0000001157388843"></a>
- **[Basic Concepts](ts-general-ui-concepts.md)**
- **[Declarative UI Description Specifications](ts-declarative-ui-description-specifications.md)**
- **[Componentization](ts-component-based.md)**
# Instantiating a struct Without the new Keyword<a name="EN-US_TOPIC_0000001110788984"></a>
You can omit the **new** keyword when instantiating a **struct**.
```
// Definition
@Component
struct MyComponent {
build() {
}
}
// Use
Column() {
MyComponent()
}
// Equivalent to
new Column() {
new MyComponent()
}
```
# APIs<a name="EN-US_TOPIC_0000001166729297"></a>
- **[AppStorage](ts-application-states-appstorage.md)**
- **[PersistentStorage](ts-application-states-apis-persistentstorage.md)**
- **[Environment](ts-application-states-apis-environment.md)**
# Managing Application States<a name="EN-US_TOPIC_0000001119769576"></a>
- **[APIs](ts-managing-application-states-apis.md)**
- **[Synchronization Between AppStorage and Components](ts-application-states-storagelink-storageprop.md)**
# Managing Component States<a name="EN-US_TOPIC_0000001157388859"></a>
- **[@State](ts-component-states-state.md)**
- **[@Prop](ts-component-states-prop.md)**
- **[@Link](ts-component-states-link.md)**
# Managing Other States<a name="EN-US_TOPIC_0000001131511284"></a>
- **[@observed and @objectLink](ts-other-states-observed-objectlink.md)**
- **[@Consume and @Provide](ts-other-states-consume-provide.md)**
- **[@Watch](ts-other-states-watch.md)**
# Media Resource Types<a name="EN-US_TOPIC_0000001111421384"></a> # Media Resource Types
- The following table describes the image resource types supported by the development framework.
<a name="table74561214415"></a>
<table><thead align="left"><tr id="row9455121042"><th class="cellrowborder" valign="top" width="54%" id="mcps1.1.3.1.1"><p id="p74514120420"><a name="p74514120420"></a><a name="p74514120420"></a>Image Format</p>
</th>
<th class="cellrowborder" valign="top" width="46%" id="mcps1.1.3.1.2"><p id="p9453121840"><a name="p9453121840"></a><a name="p9453121840"></a>File Name Extension</p>
</th>
</tr>
</thead>
<tbody><tr id="row1445612145"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p1445712547"><a name="p1445712547"></a><a name="p1445712547"></a>JPEG</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p184512121747"><a name="p184512121747"></a><a name="p184512121747"></a>.jpg</p>
</td>
</tr>
<tr id="row104516123419"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p9452120419"><a name="p9452120419"></a><a name="p9452120419"></a>PNG</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p1945171215415"><a name="p1945171215415"></a><a name="p1945171215415"></a>.png</p>
</td>
</tr>
<tr id="row204512121146"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p1745171215413"><a name="p1745171215413"></a><a name="p1745171215413"></a>GIF</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p34512121047"><a name="p34512121047"></a><a name="p34512121047"></a>.gif</p>
</td>
</tr>
<tr id="row1628915301042"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p52901630247"><a name="p52901630247"></a><a name="p52901630247"></a>SVG</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p1229020304417"><a name="p1229020304417"></a><a name="p1229020304417"></a>.svg</p>
</td>
</tr>
<tr id="row1157118321548"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p18571113210419"><a name="p18571113210419"></a><a name="p18571113210419"></a>WEBP</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p125712321046"><a name="p125712321046"></a><a name="p125712321046"></a>.webp</p>
</td>
</tr>
<tr id="row193603571342"><td class="cellrowborder" valign="top" width="54%" headers="mcps1.1.3.1.1 "><p id="p1336055717420"><a name="p1336055717420"></a><a name="p1336055717420"></a>BMP</p>
</td>
<td class="cellrowborder" valign="top" width="46%" headers="mcps1.1.3.1.2 "><p id="p536055715412"><a name="p536055715412"></a><a name="p536055715412"></a>.bmp</p>
</td>
</tr>
</tbody>
</table>
- The following table describes the image resource types supported by the development framework.
| Image Format | File Name Extension |
| -------- | -------- |
| JPEG | .jpg |
| PNG | .png |
| GIF | .gif |
| SVG | .svg |
| WEBP | .webp |
| BMP | .bmp |
# @Consume and @Provide<a name="EN-US_TOPIC_0000001177510803"></a> # @Consume and @Provide
As the data provider, **Provide** can update the data of child nodes and trigger page rendering. After **Consume** detects that the **Provide** data is updated, it will initiate re-rendering of the current view.
As the data provider, @Provide can update the data of child nodes and trigger page rendering. After @Consume detects that the @Provide data is updated, it will initiate re-rendering of the current view.
**Table 1** @Provide
<a name="table657684923115"></a> Table1 @Provide
<table><thead align="left"><tr id="row15576204917311"><th class="cellrowborder" valign="top" width="11.76%" id="mcps1.2.3.1.1"><p id="p1432545513219"><a name="p1432545513219"></a><a name="p1432545513219"></a>Type</p>
</th> | Name | Description |
<th class="cellrowborder" valign="top" width="88.24%" id="mcps1.2.3.1.2"><p id="p35771495314"><a name="p35771495314"></a><a name="p35771495314"></a>Description</p> | -------- | -------- |
</th> | Decorator parameter | A constant of the string type, which is used to set an alias for a decorated variable. If an alias is specified, implement the data update for this alias. If there is no alias, use the variable name as the alias. @Provide("_alias_") is recommended. |
</tr> | Synchronization mechanism | The @Provide decorated variable is similar to the @state variable. You can modify the variable to re-render the page. You can also modify the @Consume decorated variable to modify the @State decorated variable reversely. |
</thead> | Initial value | The initial value must be set. |
<tbody><tr id="row17577164993114"><td class="cellrowborder" valign="top" width="11.76%" headers="mcps1.2.3.1.1 "><p id="p175774498318"><a name="p175774498318"></a><a name="p175774498318"></a>Decorator parameters</p> | Page re-rendering scenarios | The following will trigger page re-rendering:<br/>- Changes of variables in primitive types (boolean, string, and number)<br/>- Changes of the @Observed decorated classes or their attributes<br/>- Adding, deleting, or updatingelements in an array |
</td>
<td class="cellrowborder" valign="top" width="88.24%" headers="mcps1.2.3.1.2 "><p id="p1057724983115"><a name="p1057724983115"></a><a name="p1057724983115"></a>Alias: a constant of the string type. If an alias is specified, implement the data update for this alias. If there is no alias, use the variable name as the alias. <strong id="b6361102517296"><a name="b6361102517296"></a><a name="b6361102517296"></a>@Provide("<em id="i111131278293"><a name="i111131278293"></a><a name="i111131278293"></a>alias</em>")</strong> is recommended.</p>
</td> Table2 @Consume
</tr>
<tr id="row176181053377"><td class="cellrowborder" valign="top" width="11.76%" headers="mcps1.2.3.1.1 "><p id="p1261945143714"><a name="p1261945143714"></a><a name="p1261945143714"></a>Synchronization mechanism</p> | Type | Description |
</td> | -------- | -------- |
<td class="cellrowborder" valign="top" width="88.24%" headers="mcps1.2.3.1.2 "><p id="p361955173715"><a name="p361955173715"></a><a name="p361955173715"></a>The <strong id="b180161543014"><a name="b180161543014"></a><a name="b180161543014"></a>@Provide</strong> decorated variable is similar to the <strong id="b1520118579306"><a name="b1520118579306"></a><a name="b1520118579306"></a>@state</strong> variable. You can modify the variable to re-render the page. You can also modify the <strong id="b5329423183117"><a name="b5329423183117"></a><a name="b5329423183117"></a>@Consume</strong> decorated variable to modify the <strong id="b137201734193116"><a name="b137201734193116"></a><a name="b137201734193116"></a>@State</strong> decorated variable reversely.</p> | Initial value | No default value can be set. |
</td>
</tr>
<tr id="row103140354219"><td class="cellrowborder" valign="top" width="11.76%" headers="mcps1.2.3.1.1 "><p id="p531412324219"><a name="p531412324219"></a><a name="p531412324219"></a>Initial value</p> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
</td> > To avoid infinite loops caused by circular reference, exercise caution when using @Provide and @Consume.
<td class="cellrowborder" valign="top" width="88.24%" headers="mcps1.2.3.1.2 "><p id="p331412394220"><a name="p331412394220"></a><a name="p331412394220"></a>The initial value must be set.</p>
</td>
</tr> The description of other attributes is the same as that of @Provide.
<tr id="row171522344211"><td class="cellrowborder" valign="top" width="11.76%" headers="mcps1.2.3.1.1 "><p id="p22941739134411"><a name="p22941739134411"></a><a name="p22941739134411"></a>Page re-rendering scenarios</p>
</td>
<td class="cellrowborder" valign="top" width="88.24%" headers="mcps1.2.3.1.2 "><p id="p61513237423"><a name="p61513237423"></a><a name="p61513237423"></a>1. Primitive types: boolean, string, and number</p>
<p id="p118613561460"><a name="p118613561460"></a><a name="p118613561460"></a>2. <strong id="b464654743215"><a name="b464654743215"></a><a name="b464654743215"></a>@observed</strong>: used to modify the attributes of the <strong id="b8138554192417"><a name="b8138554192417"></a><a name="b8138554192417"></a>@observed</strong> decorated class.</p>
<p id="p232173614475"><a name="p232173614475"></a><a name="p232173614475"></a>3. Array: Add, delete, or update elements in an array.</p>
</td>
</tr>
</tbody>
</table>
**Table 2** @Consume
<a name="table11965192012493"></a>
<table><thead align="left"><tr id="row1796552012496"><th class="cellrowborder" valign="top" width="11.76%" id="mcps1.2.3.1.1"><p id="p7965182054914"><a name="p7965182054914"></a><a name="p7965182054914"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="88.24%" id="mcps1.2.3.1.2"><p id="p2965220174910"><a name="p2965220174910"></a><a name="p2965220174910"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1965182013493"><td class="cellrowborder" valign="top" width="11.76%" headers="mcps1.2.3.1.1 "><p id="p1496582020496"><a name="p1496582020496"></a><a name="p1496582020496"></a>Initial value</p>
</td>
<td class="cellrowborder" valign="top" width="88.24%" headers="mcps1.2.3.1.2 "><p id="p15965132044919"><a name="p15965132044919"></a><a name="p15965132044919"></a>No default value can be set.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>To avoid infinite loops caused by circular reference, exercise caution when using **@Provide** and **@Consume**.
The description of other attributes is the same as that of **@Provide**.
``` ```
@Entry @Entry
...@@ -103,4 +74,3 @@ struct CompC { ...@@ -103,4 +74,3 @@ struct CompC {
} }
} }
``` ```
# @observed and @objectLink<a name="EN-US_TOPIC_0000001131671052"></a> # @Observed and @ObjectLink
This section introduces to you two new decorators: @Observed and @ObjectLink.
- @Observed applies to a class, indicating that the data changes in the class are managed by the UI page, for example, @Observed class ClassA {}.
- @ObjectLink applies to an object decorated by @Observed, for example, @ObjectLink a: ClassA.
## Background
When you need to set bidirectional synchronization in a child component for a variable (parent_a) of its parent component, you can use @State to decorate the variable (parent_a) in the parent component and use @Link to decorate the corresponding variable (child_a) in the child component. In this way, data can be synchronized between the parent component and the specific child component, and between the parent component and its other child components. As shown below, bidirectional synchronization is configured for variables of ClassA in the parent and child components. If attribute c of the variable in child component 1 has its value changed, the parent component will be notified to synchronize the change. If attribute c in the parent component has its value changed, all child components will be notified to synchronize the change.
![en-us_image_0000001267647861](figures/en-us_image_0000001267647861.png)
In the preceding example, full synchronization is performed for a data object. If you want to synchronize partial information of a data object in a parent component, and if the information is a class object, use @ObjectLink and @Observed instead, as shown below.
![en-us_image_0000001267607881](figures/en-us_image_0000001267607881.png)
## Configuration Requirement
- @Observed applies to classes, and @ObjectLink applies to variables.
- The variables decorated by @ObjectLink must be of the class type.
- The classes must be decorated by @Observed.
- Parameters of the primitive types are not supported. You can use @Prop to perform unidirectional synchronization.
- @ObjectLink decorated variables are immutable.
- Attribute changes are allowed. If an object is referenced by multiple @ObjectLink decorated variables, all custom components that have these variables will be notified for re-rendering.
- Default values cannot be set for @ObjectLink decorated variables.
- The parent component must be initialized with a TypeScript expression that involves variables decorated by @State, @Link, @StorageLink, @Provide, or @Consume.
- @ObjectLink decorated variables are private variables and can be accessed only within the component.
## Examples
### Example 1
**@observed** is a decorator used for classes, indicating that the data changes in the object will be managed by the UI page. **@objectLink** is used to decorate the variables that are decorated by **@observed**.
``` ```
// Object to be observed @Observed
@Observed class ClassA { class ClassA {
static nextID : number = 0; public name : string;
public id : number;
public c: number; public c: number;
constructor(c: number, name: string = 'OK') {
constructor(c: number) { this.name = name;
this.id = ClassA.nextID++;
this.c = c; this.c = c;
} }
} }
@Observed class ClassB { class ClassB {
public a: ClassA; public a: ClassA;
constructor(a: ClassA) { constructor(a: ClassA) {
this.a = a; this.a = a;
} }
} }
```
```
@Component @Component
struct ViewA { struct ViewA {
label : string = "ep1";
@ObjectLink a : ClassA; @ObjectLink a : ClassA;
label : string = "ViewA1";
build() { build() {
Row() { Column() {
Button(`ViewA [${this.label}] this.a.c=${this.a.c} +1`) Text(`ViewA [${this.label}]: a.c=${this.a.c}`)
.fontSize(20)
Button(`+1`)
.width(100)
.margin(2)
.onClick(() => { .onClick(() => {
this.a.c += 1; this.a.c += 1;
}) })
Button(`ViewA [${this.label}] reset this.a =new ClassA(0)`) Button(`reset`)
.width(100)
.margin(2)
.onClick(() => { .onClick(() => {
this.a = new ClassA(0); // ERROR, this.a is immutable this.a = new ClassA(0); // ERROR, this.a is immutable
}) })
...@@ -46,18 +88,27 @@ struct ViewA { ...@@ -46,18 +88,27 @@ struct ViewA {
@Entry @Entry
@Component @Component
struct ViewB { struct ViewB {
@State b : ClassB = new ClassB(new ClassA(0)); @State b : ClassB = new ClassB(new ClassA(10));
build() { build() {
Column() { Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center}) {
ViewA({label: "ViewA #1", a: this.b.a}) ViewA({label: "ViewA #1", a: this.b.a})
ViewA({label: "ViewA #2", a: this.b.a}) ViewA({label: "ViewA #2", a: this.b.a})
Button(`ViewB: this.b.a.c += 1` )
.width(320)
.margin(4)
.onClick(() => {
this.b.a.c += 1;
})
Button(`ViewB: this.b.a = new ClassA(0)`) Button(`ViewB: this.b.a = new ClassA(0)`)
.width(240)
.margin(4)
.onClick(() => { .onClick(() => {
this.b.a = new ClassA(0); this.b.a = new ClassA(0);
}) })
Button(`ViewB: this.b = new ClassB(ClassA(0))`) Button(`ViewB: this.b = new ClassB(ClassA(0))`)
.width(240)
.margin(4)
.onClick(() => { .onClick(() => {
this.b = new ClassB(new ClassA(0)); this.b = new ClassB(new ClassA(0));
}) })
...@@ -66,6 +117,65 @@ struct ViewB { ...@@ -66,6 +117,65 @@ struct ViewB {
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>**@ObjectLink** is used to decorate variables and cannot be initialized. **@Observed** is used to decorate a class.
### Example 2
```
var nextID: number = 0;
@Observed
class ClassA {
public name : string;
public c: number;
public id : number;
constructor(c: number, name: string = 'OK') {
this.name = name;
this.c = c;
this.id = nextID++;
}
}
@Component
struct ViewA {
label : string = "ViewA1";
@ObjectLink a: ClassA;
build() {
Row() {
Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`)
.onClick(() => {
this.a.c += 1;
})
}
}
}
@Entry
@Component
struct ViewB {
@State arrA : ClassA[] = [ new ClassA(0), new ClassA(0) ];
build() {
Column() {
ForEach (this.arrA, (item) => {
ViewA({label: `#${item.id}`, a: item})
},
(item) => item.id.toString()
)
ViewA({label: `ViewA this.arrA[first]`, a: this.arrA[0]})
ViewA({label: `ViewA this.arrA[last]`, a: this.arrA[this.arrA.length-1]})
Button(`ViewB: reset array`)
.onClick(() => {
this.arrA = [ new ClassA(0), new ClassA(0) ];
})
Button(`ViewB: push`)
.onClick(() => {
this.arrA.push(new ClassA(0))
})
Button(`ViewB: shift`)
.onClick(() => {
this.arrA.shift()
})
}
}
}
```
# @Watch<a name="EN-US_TOPIC_0000001177658253"></a> # @Watch
@Watch is used to listen for changes of state variables. The syntax structure is as follows:
```
@State @Watch("onChanged") count : number = 0
```
As shown above, add an @Watch decorator to the target state variable to register an onChanged callback. When the state variable count is changed, the onChanged callback will be triggered.
@Watch can be used to listen for changes of variables decorated by @State, @Prop, @Link, @ObjectLink, @Provide, @Consume, @StorageProp, or @StorageLink.
The application can register a callback through **@Watch**. This callback is triggered when a variable decorated by any of the following decorators changes: **@State**, **@Prop**, **@Link**, **@ObjectLink**, **@Provide**, **@Consume**, **@StorageProp**, and **@StorageLink**. The variables in **@Watch** must be enclosed in **""**.
``` ```
@Entry @Entry
...@@ -12,7 +27,7 @@ struct CompA { ...@@ -12,7 +27,7 @@ struct CompA {
updateTotal() : number { updateTotal() : number {
let sum = 0; let sum = 0;
this.shopBasket.forEach((i) => { sum += i; }); this.shopBasket.forEach((i) => { sum += i; });
// calculate new total shop basket value and apply discount if over 100RMB // Calculate the total amount of items in the shopping basket. If the amount exceeds CNY100, the specified discount will be applied.
this.totalPurchase = (sum < 100) ? sum : 0.9 * sum; this.totalPurchase = (sum < 100) ? sum : 0.9 * sum;
return this.totalPurchase; return this.totalPurchase;
} }
...@@ -31,4 +46,3 @@ struct CompA { ...@@ -31,4 +46,3 @@ struct CompA {
} }
} }
``` ```
# Parameterless Configuration<a name="EN-US_TOPIC_0000001157228859"></a> # Configuration Without Parameters
If the API definition of a component does not contain mandatory parameters, you do not need to configure any content in the parentheses next to the component.
For example, the following **Divider** component does not contain parameters: If the API definition of a component does not contain mandatory parameters, you do not need to configure any content in the parentheses next to the component. For example, the Divider component does not contain parameters:
``` ```
Column() { Column() {
...@@ -11,4 +10,3 @@ Column() { ...@@ -11,4 +10,3 @@ Column() {
Text('item 2') Text('item 2')
} }
``` ```
# Pixel Units<a name="EN-US_TOPIC_0000001111581268"></a> # Pixel Units
The framework provides four pixel units, with vp as the reference data unit. The framework provides four pixel units, with vp as the reference data unit.
<a name="table230mcpsimp"></a>
<table><thead align="left"><tr id="row235mcpsimp"><th class="cellrowborder" valign="top" width="13%" id="mcps1.1.3.1.1"><p id="p237mcpsimp"><a name="p237mcpsimp"></a><a name="p237mcpsimp"></a>Name</p>
</th>
<th class="cellrowborder" valign="top" width="87%" id="mcps1.1.3.1.2"><p id="p239mcpsimp"><a name="p239mcpsimp"></a><a name="p239mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row240mcpsimp"><td class="cellrowborder" valign="top" width="13%" headers="mcps1.1.3.1.1 "><p id="p242mcpsimp"><a name="p242mcpsimp"></a><a name="p242mcpsimp"></a>px</p>
</td>
<td class="cellrowborder" valign="top" width="87%" headers="mcps1.1.3.1.2 "><p id="p244mcpsimp"><a name="p244mcpsimp"></a><a name="p244mcpsimp"></a>Physical pixel unit of the screen.</p>
</td>
</tr>
<tr id="row245mcpsimp"><td class="cellrowborder" valign="top" width="13%" headers="mcps1.1.3.1.1 "><p id="p247mcpsimp"><a name="p247mcpsimp"></a><a name="p247mcpsimp"></a>vp</p>
</td>
<td class="cellrowborder" valign="top" width="87%" headers="mcps1.1.3.1.2 "><p id="p249mcpsimp"><a name="p249mcpsimp"></a><a name="p249mcpsimp"></a>Pixels specific to the screen density, which are converted into physical pixels of the screen based on the screen pixel density.</p>
</td>
</tr>
<tr id="row250mcpsimp"><td class="cellrowborder" valign="top" width="13%" headers="mcps1.1.3.1.1 "><p id="p252mcpsimp"><a name="p252mcpsimp"></a><a name="p252mcpsimp"></a>fp</p>
</td>
<td class="cellrowborder" valign="top" width="87%" headers="mcps1.1.3.1.2 "><p id="p254mcpsimp"><a name="p254mcpsimp"></a><a name="p254mcpsimp"></a>Font pixel, which is similar to vp and varies according to the system font size.</p>
</td>
</tr>
<tr id="row920003123018"><td class="cellrowborder" valign="top" width="13%" headers="mcps1.1.3.1.1 "><p id="p1020016393011"><a name="p1020016393011"></a><a name="p1020016393011"></a>lpx</p>
</td>
<td class="cellrowborder" valign="top" width="87%" headers="mcps1.1.3.1.2 "><p id="p1120043183010"><a name="p1120043183010"></a><a name="p1120043183010"></a>Logical pixel unit of the window. It is the ratio of the actual screen width to the logical width (configured by <a href="ts-framework-js-tag.md#table12744175911317">designWidth</a>). For example, if <strong id="b2423202212551"><a name="b2423202212551"></a><a name="b2423202212551"></a>designWidth</strong> is set to <strong id="b20172226195518"><a name="b20172226195518"></a><a name="b20172226195518"></a>720</strong>, then 1lpx is equal to 2px for a screen with an actual width of 1440 physical pixels.</p>
</td>
</tr>
</tbody>
</table>
## Pixel Unit Conversion<a name="section43478451141"></a> | Name | Description |
| -------- | -------- |
| px | Physical pixel unit of the screen. |
| vp | Pixels specific to the screen density, which are converted into physical pixels of the screen based on the screen pixel density. |
| fp | Font pixel, which is similar to vp and varies according to the system font size. |
| lpx | Logical pixel unit of the window. It is the ratio of the actual screen width to the logical width (configured by [designWidth](ts-framework-js-tag.md)). For example, if designWidth is set to 720, then 1lpx is equal to 2px for a screen with an actual width of 1440 physical pixels. |
## Pixel Unit Conversion
Conversion from other pixel units to px is supported. Conversion from other pixel units to px is supported.
<a name="table16548143615916"></a> | API | Description |
<table><thead align="left"><tr id="row175481036794"><th class="cellrowborder" valign="top" width="35.69%" id="mcps1.1.3.1.1"><p id="p14548123614910"><a name="p14548123614910"></a><a name="p14548123614910"></a>API</p> | -------- | -------- |
</th> | vp2px(value : number) : number | Converts a value in units of vp to a value in units of px. |
<th class="cellrowborder" valign="top" width="64.31%" id="mcps1.1.3.1.2"><p id="p11548183618912"><a name="p11548183618912"></a><a name="p11548183618912"></a>Description</p> | px2vp(value : number) : number | Converts a value in units of px to a value in units of vp. |
</th> | fp2px(value : number) : number | Converts a value in units of fp to a value in units of px. |
</tr> | px2fp(value : number) : number | Converts a value in units of px to a value in units of fp. |
</thead> | lpx2px(value : number) : number | Converts a value in units of lpx to a value in units of px. |
<tbody><tr id="row75487361090"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p05483367914"><a name="p05483367914"></a><a name="p05483367914"></a>vp2px(value : number) : number</p> | px2lpx(value : number) : number | Converts a value in units of px to a value in units of lpx. |
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p6239203321019"><a name="p6239203321019"></a><a name="p6239203321019"></a>Converts a value in units of vp to a value in units of px.</p>
</td> ## Example
</tr>
<tr id="row0770112219335"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p177017220331"><a name="p177017220331"></a><a name="p177017220331"></a>px2vp(value : number) : number</p>
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p8770192212335"><a name="p8770192212335"></a><a name="p8770192212335"></a>Converts a value in units of px to a value in units of vp.</p>
</td>
</tr>
<tr id="row15951172693314"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p15951102643316"><a name="p15951102643316"></a><a name="p15951102643316"></a>fp2px(value : number) : number</p>
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p995152643319"><a name="p995152643319"></a><a name="p995152643319"></a>Converts a value in units of fp to a value in units of px.</p>
</td>
</tr>
<tr id="row83152033153314"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p231503317331"><a name="p231503317331"></a><a name="p231503317331"></a>px2fp(value : number) : number</p>
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p143158337338"><a name="p143158337338"></a><a name="p143158337338"></a>Converts a value in units of px to a value in units of fp.</p>
</td>
</tr>
<tr id="row1619816394331"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p121981939173310"><a name="p121981939173310"></a><a name="p121981939173310"></a>lpx2px(value : number) : number</p>
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p819843963311"><a name="p819843963311"></a><a name="p819843963311"></a>Converts a value in units of lpx to a value in units of px.</p>
</td>
</tr>
<tr id="row955964320338"><td class="cellrowborder" valign="top" width="35.69%" headers="mcps1.1.3.1.1 "><p id="p35591243143310"><a name="p35591243143310"></a><a name="p35591243143310"></a>px2lpx(value : number) : number</p>
</td>
<td class="cellrowborder" valign="top" width="64.31%" headers="mcps1.1.3.1.2 "><p id="p14559343153314"><a name="p14559343153314"></a><a name="p14559343153314"></a>Converts a value in units of px to a value in units of lpx.</p>
</td>
</tr>
</tbody>
</table>
## Example<a name="section208264919153"></a>
``` ```
@Entry @Entry
...@@ -121,5 +72,4 @@ struct Example { ...@@ -121,5 +72,4 @@ struct Example {
} }
``` ```
![](figures/pixel-unit.gif) ![en-us_image_0000001267607893](figures/en-us_image_0000001267607893.gif)
# ForEach<a name="EN-US_TOPIC_0000001110788996"></a> # ForEach
The development framework provides ForEach to iterate arrays and create components for each array item. ForEach is defined as follows:
The development framework provides **ForEach** to iterate arrays and create components for each array item. **ForEach** is defined as follows:
``` ```
ForEach( ForEach(
...@@ -10,28 +13,48 @@ ForEach( ...@@ -10,28 +13,48 @@ ForEach(
) )
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- Loop rendering uses **ForEach** to automatically generate child components from the provided array. ## ForEach
>- **ForEach** must be used in container components.
>- The first parameter must be an array. An empty array is allowed. If an array is empty, no child component is created. You can set the functions whose return values are of the array type, for example, **arr.slice \(1, 3\)**. The set functions cannot change any state variables including the array itself, such as **Array.splice**, **Array.sort**, and **Array.reverse**.
>- The second parameter is used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces \(\{...\}\). ForEach(arr: any[],itemGenerator: (item: any, index?: number) => void, keyGenerator?: (item: any, index?: number) => string):void
>- The third parameter is optional and used as an anonymous function for key value generation. It generates a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from the key value of the new item. The key-value generator is optional. However, for performance reasons, it is strongly recommended that the generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in **ForEach** will be rebuilt.
>- The generated child components must be allowed in the parent container component of **ForEach**. The child component generator function can contain the **if/else** conditional statement. In addition, **ForEach** can be contained in the **if/else** conditional statement.
>- The calling sequence of subitem generator functions may be different from that of the data items in the array. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: Table1 Parameters
| Name | Type | Mandatory | Default Value | Description |
| -------- | -------- | -------- | -------- | -------- |
| arr | any[] | Yes | - | Must be an array. An empty array is allowed. If an array is empty, no child component is created. You can set the functions whose return values are of the array type, for example, arr.slice (1, 3). The set functions cannot change any state variables including the array itself, such as Array.splice, Array.sort, and Array.reverse. |
| itemGenerator | (item: any, index?: number) => void | Yes | - | Used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in braces ({...}) |
| keyGenerator | (item: any, index?: number) => string | No | - | Used as an anonymous parameter for generating a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from that of the new item. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in ForEach will be rebuilt. |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - ForEach must be used in container components.
>
> - The generated child components are allowed in the parent container component of ForEach. The child component generator function can contain the if/else conditional statement, and the if/else conditional statement can contain ForEach.
>
> - The calling sequence of subitem generator functions may be different from that of the data items in the array. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage:
>
> ``` > ```
> ForEach(anArray, item => {Text(`${++counter}. item.label`)}) > ForEach(anArray, item => {Text(`${++counter}. item.label`)})
> ``` > ```
>
> Below is an example of correct usage: > Below is an example of correct usage:
>
>
> ``` > ```
> ForEach(anArray.map((item1, index1) => { return { i: index1 + 1, data: item1 }; }), > ForEach(anArray.map((item1, index1) => { return { i: index1 + 1, data: item1 }; }),
> item => Text(`${item.i}. item.data.label`), > item => Text(`${item.i}. item.data.label`),
> item => item.data.id.toString()) > item => item.data.id.toString())
> ``` > ```
## Example<a name="section155489126613"></a>
## Example
The following is an example of a simple-type array: The following is an example of a simple-type array:
``` ```
@Entry @Entry
@Component @Component
...@@ -57,7 +80,7 @@ struct MyComponent { ...@@ -57,7 +80,7 @@ struct MyComponent {
} }
``` ```
The following is an example of a complex-type array: The following is an example of a complex-type array:
``` ```
class Month { class Month {
...@@ -121,4 +144,3 @@ struct Calendar1 { ...@@ -121,4 +144,3 @@ struct Calendar1 {
} }
} }
``` ```
# if/else<a name="EN-US_TOPIC_0000001110948888"></a> # if/else
Use **if/else** for conditional rendering.
>![](../public_sys-resources/icon-note.gif) **NOTE:** Use if/else for conditional rendering.
>- State variables can be used in the **if** conditional statement.
>- You can use the **if** conditional statement to implement rendering of child components.
>- The **if** conditional statement must be used in container components.
>- Some container components limit the type or number of child components. When **if** is placed in these components, the limitation applies to components created in **if** and **else** statements. For example, when **if** is used in the **<Grid\>** component, only the **<GridItem\>** component can be used in the **if** conditional statement, and only the **<ListItem\>** component can be used in the **<List\>** component.
## Example<a name="section917781203210"></a>
Example of using the **if** conditional statement: > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - State variables can be used in the if conditional statement.
>
> - You can use the if conditional statement to implement rendering of child components.
>
> - The if conditional statement must be used in container components.
>
> - Some container components limit the type or number of child components. When if is placed in these components, the limitation applies to components created in if and else statements. For example, when if is used in the &lt;Grid&gt; component, whose child components can only be &lt;GridItem&gt;, only the &lt;GridItem> component can be used in the if conditional statement.
## Example
Example of using the if conditional statement:
``` ```
Column() { Column() {
...@@ -20,7 +27,10 @@ Column() { ...@@ -20,7 +27,10 @@ Column() {
} }
``` ```
Example of using the **if**, **else if**, and **else** conditional statements:
Example of using the if, else if, and else conditional statements:
``` ```
Column() { Column() {
...@@ -35,4 +45,3 @@ Column() { ...@@ -35,4 +45,3 @@ Column() {
} }
} }
``` ```
# LazyForEach<a name="EN-US_TOPIC_0000001136122422"></a> # LazyForEach
The development framework provides LazyForEach to iterate data from provided data sources and create corresponding components during each iteration. LazyForEach is defined as follows:
The development framework provides the **LazyForEach** component to iterate data as required and create corresponding components during each iteration. **LazyForEach** is defined as follows:
``` ```
LazyForEach(
dataSource: IDataSource, // Data source to be iterated
itemGenerator: (item: any) => void, // child component generator
keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended.
): void
interface IDataSource {
totalCount(): number; // Get total count of data
getData(index: number): any; // Get single data by index
registerDataChangeListener(listener: DataChangeListener): void; // Register listener to listening data changes
unregisterDataChangeListener(listener: DataChangeListener): void; // Unregister listener
}
interface DataChangeListener { interface DataChangeListener {
onDataReloaded(): void; // Called while data reloaded onDataReloaded(): void; // Called while data reloaded
onDataAdded(index: number): void; // Called while single data added onDataAdded(index: number): void; // Called while single data added
...@@ -10,42 +26,75 @@ interface DataChangeListener { ...@@ -10,42 +26,75 @@ interface DataChangeListener {
onDataDeleted(index: number): void; // Called while single data deleted onDataDeleted(index: number): void; // Called while single data deleted
onDataChanged(index: number): void; // Called while single data changed onDataChanged(index: number): void; // Called while single data changed
} }
interface IDataSource {
totalCount(): number; // Get total count of data
getData(index: number): any; // Get single data by index
registerDataChangeListener(listener: DataChangeListener): void; // Register listener to listening data changes
unregisterDataChangeListener(listener: DataChangeListener): void; // Unregister listener
}
LazyForEach(
dataSource: IDataSource, // Data source to be iterated
itemGenerator: (item: any) => void, // child component generator
keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended.
): void
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- When data is updated through **onDataChanged** of **LazyForEach**, if **itemGenerator** contains a fully static view \(that is, the view does not contain state variables\), the view will not be updated. ## APIs
>- **LazyForEach** is used to automatically generate child components from the provided data source.
>- **LazyForEach** must be used in the container component. Only the **<List\>**, **<Grid\>**, and **<Swiper\>** components support on-demand data loading \(that is, only the visible part and a small amount of data before and after the visible part are loaded for caching\). For other components, all data is loaded at a time.
>- The first parameter must be an object inherited from **IDataSource**. You need to implement related APIs. ### LazyForEach
>- The second parameter is used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces \(\{...\}\).
>- The third parameter is optional and used as an anonymous function for key value generation. It generates a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from the key value of the new item. The key-value generator is optional. However, for performance reasons, it is strongly recommended that the generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in **ForEach** will be rebuilt. LazyForEach(dataSource: IDataSource, itemGenerator: (item: any) => void, keyGenerator?: (item: any) => string):void
>- The generated child component must be allowed in the parent container component of **LazyForEach**, so that **LazyForEach** can be included in the **if/else** conditional statement.
>- **LazyForEach** must create one and only one child component in each iteration. Table1 Parameters
>- **ForEach** cannot be used as a child component of **LazyForEach**, and **LazyForEach** does not support nesting.
>- The **if/else** conditional statement is not allowed in **LazyForEach**. | Name | Type | Mandatory | Default Value | Description |
>- The calling sequence of the subitem generator function may be different from that of the data items in the data source. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: | -------- | -------- | -------- | -------- | -------- |
| dataSource | IDataSource | Yes | - | Object used to implement the IDataSource API. You need to implement related APIs. |
| itemGenerator | (item: any) => void | Yes | - | Used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces ({...}) |
| keyGenerator | (item: any) => string | No | - | Used as an anonymous parameter for generating a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from that of the new item. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in LazyForEach will be rebuilt. |
Table2 Description of IDataSource
| Name | Description |
| -------- | -------- |
| totalCount(): number | Obtains the total number of data records. |
| getData(index: number): any | Obtains the data corresponding to the specified index. |
| registerDataChangeListener(listener: DataChangeListener): void | Registers the data change listener. |
| unregisterDataChangeListener(listener: DataChangeListener): void | Unregisters the data change listener. |
Table3 Description of DataChangeListener
| Name | Description |
| -------- | -------- |
| onDataReloaded(): void | Reloads all data. |
| onDataAdded(index: number): void | Notifies the component that data is added to the position indicated by the specified index. |
| onDataMoved(from: number, to: number): void | Notifies the component that data is moved from the from position to the to position. |
| onDataDeleted(index: number): void | Notifies the component that data is deleted from the position indicated by the specified index. |
| onDataChanged(index: number): void | Notifies the component that data in the position indicated by the specified index is changed. |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - LazyForEach must be used in the container component. Only the &lt;List&gt;, &lt;Grid&gt;, and &lt;Swiper&gt; components support LazyForEach (that is, only the visible part and a small amount of data before and after the visible part are loaded for caching). For other components, all data is loaded at a time.
>
> - LazyForEach must create one and only one child component in each iteration.
>
> - The generated child component must be in the parent container component of LazyForEach.
>
> - LazyForEach can be included in an if/else conditional statement, but cannot contain an if/else conditional statement.
>
> - For the purpose of high-performance rendering, when the onDataChanged method of the DataChangeListener object is used to update the UI, the component update is triggered only when the state variable is used in the component specified in the UI description of itemGenerator.
>
> - The calling sequence of the subitem generator function may be different from that of the data items in the data source. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage:
>
> ``` > ```
> ForEach(dataSource, item => {Text(`${++counter}. item.label`)}) > LazyForEach(dataSource, item => {Text(`${++counter}. item.label`)})
> ``` > ```
>
> Below is an example of correct usage: > Below is an example of correct usage:
>
>
> ``` > ```
> ForEach(dataSource, > LazyForEach(dataSource,
> item => Text(`${item.i}. item.data.label`)), > item => Text(`${item.i}. item.data.label`)),
> item => item.data.id.toString()) > item => item.data.id.toString())
> ``` > ```
## Example<a name="section155489126613"></a>
## Example
``` ```
// Basic implementation of IDataSource to handle data listener // Basic implementation of IDataSource to handle data listener
...@@ -141,4 +190,3 @@ struct MyComponent { ...@@ -141,4 +190,3 @@ struct MyComponent {
} }
} }
``` ```
# About Rendering Control Syntax<a name="EN-US_TOPIC_0000001110788982"></a>
- **[if/else](ts-rending-control-syntax-if-else.md)**
- **[ForEach](ts-rending-control-syntax-foreach.md)**
- **[LazyForEach](ts-rending-control-syntax-lazyforeach.md)**
# Resource Access<a name="EN-US_TOPIC_0000001135683834"></a>
- **[Accessing Application Resources](ts-application-resource-access.md)**
- **[Media Resource Types](ts-media-resource-type.md)**
# Restrictions on Using TypeScript for Generators<a name="EN-US_TOPIC_0000001110789000"></a>
TypeScript has the following restrictions on generators:
- Expressions can be used only in character strings \($\{expression\}\), **if** conditions, **ForEach** parameters, and component parameters.
- No expressions should cause any application state variables \(**@State**, **@Link**, and **@Prop**\) to change. Otherwise, undefined and potentially unstable framework behavior may occur.
- You can use **console.log** in the first line of the generator function body so that you can track component re-rendering more easily. Expressions in the log character strings also comply with the preceding restrictions.
- The generator function cannot contain local variables.
None of the above restrictions apply to anonymous function implementations of event-handling functions \(such as **onClick**\) and to the rest of the UI component description.
Incorrect:
```
build() {
let a: number = 1 // invalid: variable declaration not allowed
console.log(`a: ${a}`) // invalid: console.log only allowed in first line of build
Column() {
Text('Hello ${this.myName.toUpperCase()}') // ok.
ForEach(this.arr.reverse(), ..., ...) // invalid: Array.reverse modifies the @State array varible in place
}
buildSpecial() // invalid: no function calls
Text(this.calcTextValue()) // this function call is ok.
}
```
# Chain Call<a name="EN-US_TOPIC_0000001110788988"></a>
You can configure the UI structure and its attributes and events and separate them with a dot\(.\) to implement chain call.
```
Column() {
Image('1.jpg')
.alt('error.jpg')
.width(100)
.height(100)
}.padding(10)
```
# @Decorator<a name="EN-US_TOPIC_0000001110948902"></a>
**@Decorator** can be applied to variable declarations, class definitions, structure definitions, or method definitions.
Multiple decorator implementations can be superimposed on the target element and written on the same line or multiple lines. It is recommended that the implementation be written on multiple lines.
In the example below, the elements decorated by **@Component** take on the form of a component, and the variables decorated by **@State** have the meaning of state data.
```
@Component
struct MyComponent {
@State count: number = 0
}
```
Multiple decorator implementations can be written on the same line.
```
@Entry @Component struct MyComponent {
}
```
However, you are advised to write the decorator implementations on multiple lines.
```
@Entry
@Component
struct MyComponent {
}
```
## Supported Decorators<a name="section5500155514324"></a>
<a name="table1571mcpsimp"></a>
<table><thead align="left"><tr id="row1577mcpsimp"><th class="cellrowborder" valign="top" width="13.16%" id="mcps1.1.4.1.1"><p id="p1579mcpsimp"><a name="p1579mcpsimp"></a><a name="p1579mcpsimp"></a>Decorator</p>
</th>
<th class="cellrowborder" valign="top" width="23.96%" id="mcps1.1.4.1.2"><p id="p1581mcpsimp"><a name="p1581mcpsimp"></a><a name="p1581mcpsimp"></a>Decorates...</p>
</th>
<th class="cellrowborder" valign="top" width="62.88%" id="mcps1.1.4.1.3"><p id="p1583mcpsimp"><a name="p1583mcpsimp"></a><a name="p1583mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1584mcpsimp"><td class="cellrowborder" valign="top" width="13.16%" headers="mcps1.1.4.1.1 "><p id="p1586mcpsimp"><a name="p1586mcpsimp"></a><a name="p1586mcpsimp"></a>@Component</p>
</td>
<td class="cellrowborder" valign="top" width="23.96%" headers="mcps1.1.4.1.2 "><p id="p1588mcpsimp"><a name="p1588mcpsimp"></a><a name="p1588mcpsimp"></a>struct</p>
</td>
<td class="cellrowborder" valign="top" width="62.88%" headers="mcps1.1.4.1.3 "><p id="p1590mcpsimp"><a name="p1590mcpsimp"></a><a name="p1590mcpsimp"></a>The decorated structure has the component-based capability. The <strong id="b151410144016"><a name="b151410144016"></a><a name="b151410144016"></a>build</strong> method must be implemented to update the UI.</p>
</td>
</tr>
<tr id="row1591mcpsimp"><td class="cellrowborder" valign="top" width="13.16%" headers="mcps1.1.4.1.1 "><p id="p1593mcpsimp"><a name="p1593mcpsimp"></a><a name="p1593mcpsimp"></a>@Entry</p>
</td>
<td class="cellrowborder" valign="top" width="23.96%" headers="mcps1.1.4.1.2 "><p id="p12728164243518"><a name="p12728164243518"></a><a name="p12728164243518"></a>struct</p>
</td>
<td class="cellrowborder" valign="top" width="62.88%" headers="mcps1.1.4.1.3 "><p id="p1597mcpsimp"><a name="p1597mcpsimp"></a><a name="p1597mcpsimp"></a>The decorated component is used as the entry of a page. The component is rendered and displayed when the page is loaded.</p>
</td>
</tr>
<tr id="row1598mcpsimp"><td class="cellrowborder" valign="top" width="13.16%" headers="mcps1.1.4.1.1 "><p id="p1600mcpsimp"><a name="p1600mcpsimp"></a><a name="p1600mcpsimp"></a>@State</p>
</td>
<td class="cellrowborder" valign="top" width="23.96%" headers="mcps1.1.4.1.2 "><p id="p1602mcpsimp"><a name="p1602mcpsimp"></a><a name="p1602mcpsimp"></a>Primitive types, classes, and arrays</p>
</td>
<td class="cellrowborder" valign="top" width="62.88%" headers="mcps1.1.4.1.3 "><p id="p1604mcpsimp"><a name="p1604mcpsimp"></a><a name="p1604mcpsimp"></a>If the decorated state data is modified, the <strong id="b9877114516116"><a name="b9877114516116"></a><a name="b9877114516116"></a>build</strong> method of the component will be called to update the UI.</p>
</td>
</tr>
<tr id="row1605mcpsimp"><td class="cellrowborder" valign="top" width="13.16%" headers="mcps1.1.4.1.1 "><p id="p1607mcpsimp"><a name="p1607mcpsimp"></a><a name="p1607mcpsimp"></a>@Prop</p>
</td>
<td class="cellrowborder" valign="top" width="23.96%" headers="mcps1.1.4.1.2 "><p id="p1609mcpsimp"><a name="p1609mcpsimp"></a><a name="p1609mcpsimp"></a>Primitive types</p>
</td>
<td class="cellrowborder" valign="top" width="62.88%" headers="mcps1.1.4.1.3 "><p id="p1611mcpsimp"><a name="p1611mcpsimp"></a><a name="p1611mcpsimp"></a>The modified state data is used to establish a unidirectional data dependency between the parent component and the child component. When the data associated with the parent component is modified, the UI of the current component is updated.</p>
</td>
</tr>
<tr id="row1612mcpsimp"><td class="cellrowborder" valign="top" width="13.16%" headers="mcps1.1.4.1.1 "><p id="p1614mcpsimp"><a name="p1614mcpsimp"></a><a name="p1614mcpsimp"></a>@Link</p>
</td>
<td class="cellrowborder" valign="top" width="23.96%" headers="mcps1.1.4.1.2 "><p id="p1616mcpsimp"><a name="p1616mcpsimp"></a><a name="p1616mcpsimp"></a>Primitive types, classes, and arrays</p>
</td>
<td class="cellrowborder" valign="top" width="62.88%" headers="mcps1.1.4.1.3 "><p id="p1618mcpsimp"><a name="p1618mcpsimp"></a><a name="p1618mcpsimp"></a>This decorator is used for two-way binding between the parent component and the child component. The internal state data of the parent component is used as the data source. Any changes made to one component will be reflected to the other.</p>
</td>
</tr>
</tbody>
</table>
# struct<a name="EN-US_TOPIC_0000001157388847"></a>
Components can be implemented based on **struct**s. Components cannot inherit from each other. The **struct**s implemented components can be created and destroyed more quickly than **class** implemented components.
```
@Component
struct MyComponent {
@State data: string = ''
build() {
}
}
```
# About Syntactic Sugar<a name="EN-US_TOPIC_0000001157228877"></a> # About Syntactic Sugar
- **[@Decorator](ts-syntactic-sugar-decorator.md)**
- **[Chain Call](ts-syntactic-sugar-chaining.md)** ## Decorators
- **[struct](ts-syntactic-sugar-struct.md)** A decorator @Decorator can decorate a class, structure, or class attribute. Multiple decorators can be applied to the same target element and defined on a single line or multiple lines. It is recommended that the decorators be defined on multiple lines.
- **[Instantiating a struct Without the new Keyword](ts-instantiating-a-struct-without-new-keyword.md)** In the example below, the elements decorated by @Component take on the form of a component, and the variables decorated by @State can be used to represent states.
- **[Using a Separate Line for New Component](ts-using-a-separate-line-for-new-component.md)**
- **[Restrictions on Using TypeScript for Generators](ts-restrictions-for-generators.md)** ```
@Component
struct MyComponent {
@State count: number = 0
}
```
Multiple decorators can be defined on a single line, as shown below:
```
@Entry @Component struct MyComponent {
}
```
However, you are advised to define the decorators on multiple lines, as shown below:
```
@Entry
@Component
struct MyComponent {
}
```
### Supported Decorators
| Decorator | Decorates... | Description |
| -------- | -------- | -------- |
| @Component | struct | The decorated structure has the component-based capability. The build method must be implemented to update the UI. |
| @Entry | struct | The decorated component is used as the entry of a page. The component is rendered and displayed when the page is loaded. |
| @Preview | struct | Custom components decorated by @Preview can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by @Preview are created and displayed. |
| @Builder | Methods | In the decorated method, you can use the declarative UI description to quickly generate multiple layouts in a custom component. |
| @Extend | Methods | This decorator adds new attribute functions to a preset component, allowing you to quickly define and reuse the custom style of the component. |
| @CustomDialog | struct | This decorator is used to decorate custom pop-up dialog boxes. |
| @State | Primitive data types, classes, and arrays | If the decorated state data is modified, the build method of the component will be called to update the UI. |
| @Prop | Primitive data types | This decorator is used to establish one-way data binding between the parent and child components. When the data associated with the parent component is modified, the UI of the current component is updated. |
| @Link | Primitive data types, classes, and arrays | This decorator is used to establish two-way data binding between the parent and child components. The internal state data of the parent component is used as the data source. Any changes made to one component will be reflected to the other. |
| @Observed | Classes | This decorator is used to indicate that the data changes in the class will be managed by the UI page. |
| @ObjectLink | Objects of @Observed decorated classes | When the decorated state variable is modified, the parent and sibling components that have the state variable will be notified for UI re-rendering. |
| @Consume | Primitive data types, classes, and arrays | When the @Consume decorated variable detects the update of the @Provide decorated variable, the re-rendering of the current custom component is triggered. |
| @Provide | Primitive data types, classes, and arrays | As the data provider, @Provide can update the data of child nodes and trigger page rendering. |
| @Watch | Variables decorated by @State, @Prop, @Link, @ObjectLink, @Provide, @Consume, @StorageProp, or @StorageLink | This decorator is used to listen for the changes of the state variables. The application can register a callback method through @Watch. |
## Chain Call
You can configure the UI structure and its attributes and events and separate them with a dot(.) to implement chain call.
```
Column() {
Image('1.jpg')
.alt('error.jpg')
.width(100)
.height(100)
}.padding(10)
```
## struct
Components can be implemented based on structs. Components cannot inherit from each other. The structs implemented components can be created and destroyed more quickly than class implemented components.
```
@Component
struct MyComponent {
@State data: string = ''
build() {
}
}
```
## Instantiating a struct Without the new Keyword
You can omit the new keyword when instantiating a struct.
```
// Definition
@Component
struct MyComponent {
build() {
}
}
// Use
Column() {
MyComponent()
}
// Equivalent to
new Column() {
new MyComponent()
}
```
## Restrictions on Using TypeScript in Generators
TypeScript has the following restrictions on generators:
- Expressions can be used only in character strings (${expression}), if conditions, ForEach parameters, and component parameters.
- No expressions should cause any application state variables (@State, @Link, and @Prop) to change. Otherwise, undefined and potentially unstable framework behavior may occur.
- The generator function cannot contain local variables.
None of the above restrictions apply to anonymous function implementations of event-handling functions (such as onClick)
Incorrect:
```
build() {
let a: number = 1 // invalid: variable declaration not allowed
Column() {
Text('Hello ${this.myName.toUpperCase()}') // ok.
ForEach(this.arr.reverse(), ..., ...) // invalid: Array.reverse modifies the @State array varible in place
}
buildSpecial() // invalid: no function calls
Text(this.calcTextValue()) // this function call is ok.
}
```
## $$
$$ supports two-way binding for simple variables and @State, @Link, and @Prop decorated variables.
Currently, $$ supports only the rendering between the show parameter of the bindPopup attribute and the @State decorated variable, and the checked attribute of the <Radio> component.
```
@Entry
@Component
struct bindPopup {
@State customPopup: boolean = false
build() {
Column() {
Button(){
Text('Popup')
}
.onClick(()=>{
this.customPopup = !this.customPopup
})
.bindPopup(
$$this.customPopup, {
message: "showPopup"
}
)
}
}
}
```
# Overview<a name="EN-US_TOPIC_0000001110948892"></a> # Overview
This section defines the core mechanism and functions of the TypeScript-based declarative development paradigm. It acquaints you with the declarative UI descriptions, componentization mechanisms, UI state management, rendering control syntax, and syntactic sugar. This section defines the core mechanism and functions of the TypeScript-based declarative development paradigm. It acquaints you with the declarative UI descriptions, componentization mechanisms, UI state management, rendering control syntax, and syntactic sugar.
Follow the provided guidelines for UI development. For details about the components, see [Components](../reference/arkui-js/js-components.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:** Follow the provided guidelines for UI development. For details about the components, see components.
>- All examples use the TypeScript \(TS\) language. If you are using another language, comply with the syntax requirements for that language.
>- The components used in the examples are preset in the UI framework and are used only to explain the UI description specifications.
>- Universal attribute and event methods generally apply to all components, and the attribute and event methods within a component apply only to this component. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - All examples use the TypeScript (TS) language. If you are using another language, comply with the syntax requirements for that language.
>
> - The components used in the examples are preset in the UI framework and are used only to explain the UI description specifications.
>
> - Universal attribute and event methods generally apply to all components, and the attribute and event methods within a component apply only to this component.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
System resources include colors, rounded corners, fonts, spacing, character strings, and images. By using system resources, you can develop different applications with the same visual style. System resources include colors, rounded corners, fonts, spacing, character strings, and images. By using system resources, you can develop different applications with the same visual style.
To reference a system resource, use the **"$r('sys.type.resource_id')"** format. Wherein: **sys** indicates a system resource; **type** indicates the resource type, which can be **color**, **float**, **string**, or **media**; **resource_id** indicates the resource ID, which is determined when the system resource is provided. For details about available system resource IDs. To reference a system resource, use the "$r('sys.type.resource_id')" format. Wherein: sys indicates a system resource; type indicates the resource type, which can be color, float, string, or media; resource_id indicates the resource ID, which is determined when the system resource is provided. For details about available system resource IDs.
``` ```
Text('Hello') Text('Hello')
......
...@@ -4,33 +4,33 @@ ...@@ -4,33 +4,33 @@
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Length | string&nbsp;\|&nbsp;number | Length unit. If the input is a number, use **vp**. If the input is a string, explicitly specify the unit, for example, **'10px'**, or specify the length in percentage, for example, **'100%'**.| | Length | string \| number | Length unit. If the input is a number, use vp. If the input is a string, explicitly specify the unit, for example, '10px', or specify the length in percentage, for example, '100%'.|
## Angle Type ## Angle Type
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Angle | string&nbsp;\|&nbsp;number | Angle unit. If the input is a number, use **deg**. If the input is a string, explicitly specify the unit, which can be either of the following: <br/>-&nbsp;deg, as in **'100deg'** <br/>-&nbsp;rad, as in **'3.14rad'** | | Angle | string \| number | Angle unit. If the input is a number, use deg. If the input is a string, use either of the following angle units:<br>- deg: for example, '100deg'<br>- rad: for example, '3.14rad' |
## Point Type ## Point Type
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Point | [Length,&nbsp;Length] | Coordinates of a point. The first value is the x-axis coordinate, and the second value is the y-axis coordinate.| | Point | [Length, Length] | Coordinates of a point. The first value is the x-axis coordinate, and the second value is the y-axis coordinate.|
## Color Type ## Color Type
The **Color** used by the component attribute method is described as follows: The Color type used by component attribute methods is described as follows:
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Color | string&nbsp;\|&nbsp;number&nbsp;\|&nbsp;Color | Color information. If the input is a string, use **rgb** or **rgba** to specify the color. If the input is a number, use Hex format to specify the color. If the input is a **Color" enum, use a color value to specify the color. <br/>-&nbsp;'rgb(255,&nbsp;255,&nbsp;255)' <br/>-&nbsp;'rgba(255,&nbsp;255,&nbsp;255,&nbsp;1.0)' <br/>-&nbsp;Hex format: 0xrrggbb, 0xaarrggbb, '\#FFFFFF' <br/>-&nbsp;Enum: Color.Black, Color.White| | Color | string \| number \| Color | Color information. If the input is a string, use rgb or rgba to specify the color. If the input is a number, use Hex format to specify the color. If the input is a Color enum, use a color value to specify the color.<br>- 'rgb(255, 255, 255)'<br>- 'rgba(255, 255, 255, 1.0)'<br>- Hex format: 0xrrggbb, 0xaarrggbb, '\#FFFFFF'<br>- Enum: Color.Black, Color.White |
The supported **Color** enums are described as follows: The supported Color enums are described as follows:
| Color| Value| Illustration| | Color| Value| Illustration|
...@@ -49,55 +49,60 @@ The supported **Color** enums are described as follows: ...@@ -49,55 +49,60 @@ The supported **Color** enums are described as follows:
## ColorStop Type ## ColorStop Type
**ColorStop** is used to describe the progressive color stop. ColorStop is used to describe the progressive color stop.
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| ColorStop | [Color,&nbsp;number] | Type of the progressive color stop. The first parameter specifies the color value, and the second parameter specifies the ratio of 0 to 1.| | ColorStop | [Color, number] | Type of the progressive color stop. The first parameter specifies the color value, and the second parameter specifies the ratio of 0 to 1.|
## Resource Type ## Resource Type
Resource reference type, which is used to set the value of a component attribute. The Resource type is used to reference resources for setting the value of a component attribute.
You can use **$r** or **$rawfile** to create a **Resource** object. For details, see [Resource Access](ts-media-resource-type.md). You can use $r or $rawfile to create a Resource object. For details, see [Resource Access](ts-application-resource-access.md).
- $r('belonging.type.name') - $r('belonging.type.name')
**belonging**: system or application resource. The value can be **'sys'** or **'app'**. belonging: system or application resource. The value can be 'sys' or 'app'.
**type**: resource type, which can be **'color'**, **'float'**, **'string'**, or **'media'**. type: resource type, which can be 'color', 'float', 'string', or 'media'.
**name**: resource name, which is determined during resource definition. name: resource name, which is determined during resource definition.
- $rawfile('filename') - $rawfile('filename')
**filename**: name of the file in **resources/rawfile** of the project. filename: name of the file in resources/rawfile of the project.
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Resource | {<br/>readonly&nbsp;id:&nbsp;[number];<br/>readonly&nbsp;type:&nbsp;[number];<br/>readonly&nbsp;params?:&nbsp;any[];<br/>} | **id**: resource ID. <br/>**type**: resource type (enumerated value). <br/>**params**: optional parameters. <br/>After a **Resource** object is created using **$r** or **$rawfile**, modifying attribute values of the object is prohibited.| | Resource | {<br>readonly id: [number];<br>readonly type: [number];<br>readonly params?: any[];<br>} | id: resource ID.<br>type: resource type (enumerated value).<br>params: optional parameters.<br>After a Resource object is created using $r or $rawfile, modifying attribute values of the object is prohibited.|
## ResourceStr<sup>8+</sup> ## ResourceStr Type<sup>8+</sup>
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| ResourceStr | string&nbsp;\|&nbsp;[Resource](#resourcetype) | Resource string.| | ResourceStr | string \| Resource| Resource string.|
## Resource Color<sup>8+</sup> ## ResourceColor Type<sup>8+</sup>
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| ResourceColor | Color&nbsp;\|&nbsp;number&nbsp;\|&nbsp;string&nbsp;\|&nbsp;[Resource](#resourcetype) | Resource color.| | ResourceColor | Color \| number \| string \| Resource | Resource color.|
## Font Type<sup>8+</sup>
## Custom Builder<sup>8+</sup> | Name| Type| Description|
| -------- | -------- | -------- |
| Font | {<br>size?: Length;<br>weight?: FontWeight \| number \| string;<br>family?: string \| Resource;<br>style?: FontStyle;<br>} | Text style.<br>size: font size. For the number type, use the unit fp.<br>weight: font weight. For the number type, the value ranges from 100 to 900, at an interval of 100. The default value is 400. A larger value indicates a larger font weight.<br>family: font family. Use commas (,) to separate multiple fonts. The priority of the fonts is the sequence in which they are placed. An example value is 'Arial, sans-serif'.<br>style: font style.|
## CustomBuilder Type<sup>8+</sup>
You can use **CustomBuilder** to define custom UI descriptions in component attribute methods. You can use CustomBuilder to define custom UI descriptions in component attribute methods.
| Name| Type| Description| | Name| Type| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| CustomBuilder | ()&nbsp;=&gt;&nbsp;any | Builder of component attribute methods for defining custom UI descriptions. This type of method must be decorated by **@Builder**. For details, see [@Builder](ts-component-based-builder.md).| | CustomBuilder | () => any | Builder of component attribute methods for defining custom UI descriptions. This type of method must be decorated by @Builder. For details, see [@Builder](ts-component-based-builder.md).|
## Example ## Example
......
# About UI State Management<a name="EN-US_TOPIC_0000001157388855"></a>
- **[Basic Concepts](ts-ui-state-mgmt-concepts.md)**
- **[Managing Component States](ts-managing-component-states.md)**
- **[Managing Application States](ts-managing-application-states.md)**
- **[Managing Other States](ts-managing-other-states.md)**
# Basic Concepts<a name="EN-US_TOPIC_0000001169868220"></a> # Basic Concepts
In the declarative UI programming paradigm, the UI is a function in the specific application state, and you update a UI by modifying the current application state.
The development framework provides comprehensive application state management capabilities, as shown in the figure below. In the declarative UI programming paradigm, the UI is a function in the specific application state, and you update a UI by modifying the current application state. The development framework provides comprehensive application state management capabilities, as shown in the figure below.
![](figures/corespec_figures_state-mgmt-overview.png)
## State Variable Decorators<a name="section13236174803615"></a> ![en-us_image_0000001222967768](figures/en-us_image_0000001222967768.png)
- **@State**: grants a component the state attribute. Each time the **@State** decorated variable changes, the component re-renders and updates the UI.
- **@Link**: allows a component to depend on some state attributes of its parent component. Each time the data in one component is updated, the state of the other component is updated, and the parent and child components are rendered again. ## State Variable Decorators
- **@Prop**: works in a way similar to that of **@Link**. The only difference is that the changes made by a child component are not synchronized to the parent component. - @State: state attribute of the component. Each time the @State decorated variable changes, the component re-renders and updates the UI.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** - @Link: allows a component to depend on some state attributes of its parent component. Each time the data in one component is updated, the state of the other component is updated, and the parent and child components are rendered again.
> The state variable name cannot be **id**, for example, **@Prop id:number**.
## Application State Data<a name="section16386143212559"></a> - @Prop: works in a way similar to that of @Link. The difference is that the changes made by a child component are not synchronized to the parent component.
**AppStorage** is the central store of the application states used in the entire UI. The UI framework creates a singleton **AppStorage** object for the application and provides the corresponding decorators and APIs for the application.
- **@StorageLink**: works in a way similar to that of **@Consume**. The difference is that the link object with the specified name is obtained from the **AppStorage**. It establishes two-way binding between the UI component and **AppStorage** to synchronize data. ## Application State Data
- **@StorageProp**: synchronizes UI component attributes with the **AppStorage** unidirectionally. The value change in the **AppStorage** will trigger an update of the attribute value in the UI component, but the attribute value of the UI component will not cause an update of the attribute value in the **AppStorage**.
- Service logic implementation API: adds, reads, modifies, or deletes the state attributes of applications. The changes made by this API will be synchronized to the UI component for UI update. AppStorage is the central store of the application states in the entire UI. The UI framework creates a singleton AppStorage object for the application and provides the corresponding decorators and APIs for the application.
- @StorageLink: works in a way similar to that of @Consume. The difference is that the link object with the specified name is obtained from the AppStorage. It establishes two-way binding between the UI component and AppStorage to synchronize data.
- @StorageProp: synchronizes UI component attributes with the AppStorage unidirectionally. That is, the value change in the AppStorage will trigger an update of the corresponding UI component, but the change of the UI component will not cause an update of the attribute value in the AppStorage.
- Service logic implementation API: adds, reads, modifies, or deletes the state attributes of applications. The changes made by this API will be synchronized to the UI component for UI update.
# Using a Separate Line for New Component<a name="EN-US_TOPIC_0000001110788994"></a>
**Semicolons \(;\) can be omitted at the end of each line of code.**
```
Column() {
Image('icon.png')
Text('text')
}
```
It is equivalent to:
```
Column() {
Image('icon.png');
Text('text');
}
```
**Only one component can be created in a line. An if, else, else if, or ForEach statement must also be in a separate line.**
Incorrect:
```
Column() {
Image('icon.png') Text('text') // invalid, creation of two components in same line
}
if (this.condi) {Image('icon.png')} // invalid, if and creation a components in same line
```
**Built-in container components, if, and ForEach item generator functions must use closed parentheses \(\{\}\) in the case of a single subitem.**
Incorrect:
```
if (this.condi)
Image('icon.png'), // invalid, missing {}
else
Text('text');
```
```
ForEach(this.arr,
(item) => Image('icon.png'), // invalid, missing {}
(item) => item.id.toString()
}
```
# JavaScript-based Web-Like Development Paradigm<a name="EN-US_TOPIC_0000001214730071"></a>
- **[Overview](ui-js-overview.md)**
- **[Framework](js-framework.md)**
- **[Building the UI](ui-js-building-ui.md)**
- **[Common Component Development Guidelines](ui-js-common-components.md)**
- **[Animation Development Guidelines](ui-js-animate.md)**
- **[Custom Components](ui-js-custom-components.md)**
# TypeScript-based Declarative Development Paradigm<a name="EN-US_TOPIC_0000001169328728"></a>
- **[Overview](ui-ts-overview.md)**
- **[Framework Overview](ts-framework.md)**
- **[Declarative Syntax](ts-declarative-syntax.md)**
- **[Experiencing the Declarative UI](ui-ts-experiencing-declarative-ui.md)**
- **[Defining Page Layout and Connection](ui-ts-page-layout-connections.md)**
# ArkUI<a name="EN-US_TOPIC_0000001065103332"></a>
- **[JavaScript-based Web-Like Development Paradigm](ui-arkui-js.md)**
- **[TypeScript-based Declarative Development Paradigm](ui-arkui-ts.md)**
# Defining Attribute Style Animations<a name="EN-US_TOPIC_0000001172005058"></a> # Defining Attribute Style Animations
Keyframes is used to scale a component by dynamically setting the width and height of its parent component. Set the **scale** attribute for child components to scale the child and parent components at the same time. Then, set the **opacity** attribute to display or hide the child and parent components.
Keyframes is used to scale a component by dynamically setting the width and height of its parent component. Set the scale attribute for child components to scale the child and parent components at the same time. Then, set the opacity attribute to display or hide the child and parent components.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -78,9 +79,11 @@ text{ ...@@ -78,9 +79,11 @@ text{
} }
``` ```
![](figures/d1.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001267647889](figures/en-us_image_0000001267647889.gif)
>1. The values of **animation** attributes are not sequenced. However, the values of **duration** and **delay** are parsed based on the sequence in which they are displayed.
>2. The **animation-duration** attribute must be set. Otherwise, the duration is 0, which means there is no animation effect. When **animation-fill-mode** is set to **forwards**, the component directly displays the style of the last frame.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> 1. The values of animation attributes are not sequenced. However, the values of duration and delay are parsed based on the sequence in which they are displayed.
>
> 2. The animation-duration attribute must be set. Otherwise, the duration is 0, which means there is no animation effect. When animation-fill-mode is set to forwards, the component directly displays the style of the last frame.
# Defining Animations with the background-position Attribute<a name="EN-US_TOPIC_0000001172006248"></a> # Defining Animations with the background-position Attribute
By changing the **background-position** attribute \(where the first value is the position on the x-axis and the second value is the position on the y-axis\), you move a background image. If the background image goes beyond the respective component boundaries, the excess parts will not be displayed.
By changing the background-position attribute (where the first value is the position on the x-axis and the second value is the position on the y-axis), you move a background image. If the background image goes beyond the respective component boundaries, the excess parts will not be displayed.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -74,8 +75,9 @@ By changing the **background-position** attribute \(where the first value is t ...@@ -74,8 +75,9 @@ By changing the **background-position** attribute \(where the first value is t
} }
``` ```
![](figures/q8.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001267607873](figures/en-us_image_0000001267607873.gif)
>The **background-position** attribute can only be used to move background images, but not the background color \(**background-color**\).
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> The background-position attribute can only be used to move background images, but not the background color (background-color).
# Component Animation<a name="EN-US_TOPIC_0000001171528146"></a> # Component Animation
Create and run an animation shortcut on the component. For details, see [Universal Methods](../reference/arkui-js/js-components-common-methods.md). Create and run an animation shortcut on the component. For details, see [Universal Methods](../reference/arkui-js/js-components-common-methods.md).
## Obtaining an Animation Object<a name="section662542112713"></a>
Call the **animate** method to obtain an **animation** object, which supports animation attributes, methods, and events. ## Obtaining an Animation Object
Call the animate method to obtain an animation object, which supports animation attributes, methods, and events.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -13,6 +16,7 @@ Call the **animate** method to obtain an **animation** object, which support ...@@ -13,6 +16,7 @@ Call the **animate** method to obtain an **animation** object, which support
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -29,6 +33,7 @@ Call the **animate** method to obtain an **animation** object, which support ...@@ -29,6 +33,7 @@ Call the **animate** method to obtain an **animation** object, which support
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -57,15 +62,17 @@ export default { ...@@ -57,15 +62,17 @@ export default {
} }
``` ```
![](figures/1-14.gif) ![en-us_image_0000001222807812](figures/en-us_image_0000001222807812.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - When using the animate method, you must pass the keyframes and options parameters.
> - If animate is called multiple times and the replace policy is used, parameters passed to the last call will take effect.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- When using the **animate** method, you must pass the keyframes and options parameters.
>- If **animate** is called multiple times and the **replace** policy is used, parameters passed to the last call will take effect.
## Setting Animation Parameters<a name="section36079502817"></a> ## Setting Animation Parameters
After obtaining an animation object, you can set its style working on the component by using the keyframes parameter.
After obtaining an **animation** object, you can set its style working on the component by using the keyframes parameter.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -74,6 +81,7 @@ After obtaining an **animation** object, you can set its style working on the ...@@ -74,6 +81,7 @@ After obtaining an **animation** object, you can set its style working on the
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -90,6 +98,7 @@ After obtaining an **animation** object, you can set its style working on the ...@@ -90,6 +98,7 @@ After obtaining an **animation** object, you can set its style working on the
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -134,14 +143,16 @@ export default { ...@@ -134,14 +143,16 @@ export default {
} }
``` ```
![](figures/1-15.gif) ![en-us_image_0000001267647897](figures/en-us_image_0000001267647897.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- The sequence of **translate**, **scale**, and **rotate** affects the animation effect. > - The sequence of translate, scale, and rotate affects the animation effect.
>- **transformOrigin** works only for **scale** and **rotate**. >
> - transformOrigin works only for scale and rotate.
Set the animation attributes by using the options parameter. Set the animation attributes by using the options parameter.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
...@@ -149,6 +160,7 @@ Set the animation attributes by using the options parameter. ...@@ -149,6 +160,7 @@ Set the animation attributes by using the options parameter.
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -165,6 +177,7 @@ Set the animation attributes by using the options parameter. ...@@ -165,6 +177,7 @@ Set the animation attributes by using the options parameter.
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -174,13 +187,7 @@ export default { ...@@ -174,13 +187,7 @@ export default {
onInit() { onInit() {
}, },
onShow() { onShow() {
var options = { var options = { duration: 1500, easing: 'ease-in', delay: 5, iterations: 2, direction: 'normal', };
duration: 1500,
easing: 'ease-in',
delay: 5,
iterations: 2,
direction: 'normal',
};
var frames = [ var frames = [
{ {
transform: { transform: {
...@@ -201,18 +208,24 @@ export default { ...@@ -201,18 +208,24 @@ export default {
} }
``` ```
![](figures/3-16.gif) ![en-us_image_0000001222967796](figures/en-us_image_0000001222967796.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>**direction**: mode of playing the animation. > direction: mode of playing the animation.
>**normal**: plays the animation in forward loop mode. >
>**reverse**: plays the animation in reverse loop mode. > normal: plays the animation in forward loop mode.
>**alternate**: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction. >
>**alternate-reverse**: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction. > reverse: plays the animation in reverse loop mode.
>
> alternate: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction.
>
> alternate-reverse: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction.
## Adding an Event and Calling a Method<a name="section950105162810"></a>
Animation objects support animation events and methods. You can achieve the intended animation by adding **start** and **cancel** events and calling the **play**, **pause**, **rewind**, and **stop** methods. ## Adding an Event and Calling a Method
Animation objects support animation events and methods. You can achieve the intended animation by adding start and cancel events and calling the play, pause, rewind, and stop methods.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -230,6 +243,7 @@ Animation objects support animation events and methods. You can achieve the inte ...@@ -230,6 +243,7 @@ Animation objects support animation events and methods. You can achieve the inte
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -262,6 +276,7 @@ button{ ...@@ -262,6 +276,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -336,9 +351,10 @@ export default { ...@@ -336,9 +351,10 @@ export default {
} }
``` ```
![](figures/111-17.gif) ![en-us_image_0000001223127752](figures/en-us_image_0000001223127752.gif)
Change the animation status by changing the playStat attribute.
Change the animation status by changing the **playStat** attribute.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -354,6 +370,7 @@ Change the animation status by changing the **playStat** attribute. ...@@ -354,6 +370,7 @@ Change the animation status by changing the **playStat** attribute.
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -386,6 +403,7 @@ button{ ...@@ -386,6 +403,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -463,5 +481,4 @@ export default { ...@@ -463,5 +481,4 @@ export default {
} }
``` ```
![](figures/1111.gif) ![en-us_image_0000001267607921](figures/en-us_image_0000001267607921.gif)
# CSS Animation<a name="EN-US_TOPIC_0000001211008759"></a>
- **[Defining Attribute Style Animations](ui-js-animate-attribute-style.md)**
- **[Defining Animations with the transform Attribute](ui-js-animate-transform.md)**
- **[Defining Animations with the background-position Attribute](ui-js-animate-background-position-style.md)**
# Animation Effect<a name="EN-US_TOPIC_0000001217007973"></a> # Animation Effect
You can set the interpolator to implement the animation effect. For details, see [Animation](../reference/apis/js-apis-basic-features-animator.md). You can set the interpolator to implement the animation effect. For details, see [Animation](../reference/apis/js-apis-basic-features-animator.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>This feature is supported since API version 6.
## Creating an Animation Object<a name="section2124172032912"></a> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> This feature is supported since API version 6.
## Creating an Animation Object
Use createAnimator to create an animation object and set the animation attributes by using the options parameter.
Use **createAnimator** to create an **animation** object and set the **animation** attributes by using the options parameter.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -20,6 +24,7 @@ Use **createAnimator** to create an **animation** object and set the **anim ...@@ -20,6 +24,7 @@ Use **createAnimator** to create an **animation** object and set the **anim
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -40,6 +45,7 @@ button{ ...@@ -40,6 +45,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import animator from '@ohos.animator'; import animator from '@ohos.animator';
...@@ -72,16 +78,20 @@ export default { ...@@ -72,16 +78,20 @@ export default {
} }
``` ```
![](figures/22.gif) ![en-us_image_0000001267887885](figures/en-us_image_0000001267887885.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- When you use **createAnimator** to create an animation object, you must pass the **options** parameter. > - When you use createAnimator to create an animation object, you must pass the options parameter.
>- **begin** indicates the start point of the animation interpolation. If it is not set, the default value **0** is used. >
>- **end** indicates the end point of the animation interpolation. If it is not set, the default value **1** is used. > - begin indicates the start point of the animation interpolation. If it is not set, the default value 0 is used.
>
> - end indicates the end point of the animation interpolation. If it is not set, the default value 1 is used.
## Adding Animation Events and Calling Methods<a name="section123951438112912"></a>
The **animator** supports events and methods, which you can use to customize the animation effect. Events include **frame**, **cancel**, **repeat**, and **finish**. Methods include **update**, **play**, **pause**, **cancel**, **reverse**, and **finish**. For details about the supported events and methods, see [animator supported events and animator supported APIs](../reference/apis/js-apis-basic-features-animator.md). ## Adding Animation Events and Calling Methods
The animator supports events and methods, which you can use to customize the animation effect. Events include frame, cancel, repeat, and finish. Methods include update, play, pause, cancel, reverse, and finish. For details about the supported events and methods, see [animator supported events and animator supported APIs](../reference/apis/js-apis-basic-features-animator.md).
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -106,6 +116,7 @@ The **animator** supports events and methods, which you can use to customize t ...@@ -106,6 +116,7 @@ The **animator** supports events and methods, which you can use to customize t
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -148,6 +159,7 @@ button{ ...@@ -148,6 +159,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import animator from '@ohos.animator'; import animator from '@ohos.animator';
...@@ -230,8 +242,7 @@ export default { ...@@ -230,8 +242,7 @@ export default {
} }
``` ```
![](figures/1-18.gif) ![en-us_image_0000001223287724](figures/en-us_image_0000001223287724.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>When calling the **update** method, you can use it to update the animation parameters. The input parameters are the same as those of **createAnimator**.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> When calling the update method, you can use it to update the animation parameters. The input parameters are the same as those of createAnimator.
# Animation Frame<a name="EN-US_TOPIC_0000001217286541"></a> # Animation Frame
## Requesting an Animation Frame<a name="section1280411399304"></a>
Use the **requestAnimationFrame** method to request frames on a one-by-one basis. This method accepts a callback as an argument. ## Requesting an Animation Frame
Use the requestAnimationFrame method to request frames on a one-by-one basis. This method accepts a callback as an argument.
When runframe calls requestAnimationFrame, the step callback with the timestamp parameter is passed, and this timestamp iss assigned to startTime. When the difference between the timestamp and startTime is less than the specified value, requestAnimationFrame is called again, and the animation stops.
When **runframe** calls **requestAnimationFrame**, the **step** callback with the **timestamp** parameter is passed, and this **timestamp** iss assigned to **startTime**. When the difference between the **timestamp** and **startTime** is less than the specified value, **requestAnimationFrame** is called again, and the animation stops.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -25,6 +27,7 @@ When **runframe** calls **requestAnimationFrame**, the **step** callback wi ...@@ -25,6 +27,7 @@ When **runframe** calls **requestAnimationFrame**, the **step** callback wi
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -39,6 +42,7 @@ button{ ...@@ -39,6 +42,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -93,14 +97,16 @@ export default { ...@@ -93,14 +97,16 @@ export default {
} }
``` ```
![](figures/3333.gif) ![en-us_image_0000001267767877](figures/en-us_image_0000001267767877.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> When invoking the callback, the requestAnimationFrame method passes the timestamp as the first parameter, which indicates the time when requestAnimationFrame starts to execute the callback.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>When invoking the callback, the **requestAnimationFrame** method passes the timestamp as the first parameter, which indicates the time when **requestAnimationFrame** starts to execute the callback.
## Canceling an Animation Frame<a name="section13657493110"></a> ## Canceling an Animation Frame
Use the cancelAnimationFrame method to cancel frames on a one-by-one basis. When this method is called, the animation frame request sent through requestAnimationFrame will be canceled.
Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis. When this method is called, the animation frame request sent through **requestAnimationFrame** will be canceled.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -121,6 +127,7 @@ Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis ...@@ -121,6 +127,7 @@ Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -135,6 +142,7 @@ button{ ...@@ -135,6 +142,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -181,8 +189,7 @@ export default { ...@@ -181,8 +189,7 @@ export default {
} }
``` ```
![](figures/4444.gif) ![en-us_image_0000001223127740](figures/en-us_image_0000001223127740.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>When **cancelAnimationFrame** is called, a parameter that indicates an ID must be passed.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> When cancelAnimationFrame is called, a parameter that indicates an ID must be passed.
# Interpolator Animation<a name="EN-US_TOPIC_0000001171846694"></a>
- **[Animation Effect](ui-js-animate-dynamic-effects.md)**
- **[Animation Frame](ui-js-animate-frame.md)**
# JS Animation<a name="EN-US_TOPIC_0000001165728844"></a>
- **[Component Animation](ui-js-animate-component.md)**
- **[Interpolator Animation](ui-js-animate-interpolator.md)**
# Defining Animations for SVG Components
You can use child components in the &lt;svg&gt; component to animate attributes over time.
#### Attribute Style Animation
In the [animate](../reference/arkui-js/js-components-svg-animate.md) child component of the &lt;svg> component, set attributeName to the attribute you want to animate, set from to the animation start value, and set to to the animation end value.
```
<!-- xxx.hml -->
<div class="container">
<svg>
<text x="300" y="300" fill="blue">
Hello
<animate attributeName="font-size" from="30" to="60" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="fill" from="red" to="blue" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="opacity" from="1" to="0.3" dur="3s" repeatCount="indefinite">
</animate>
</text>
<text x="300" y="600" fill="blue">
World
<animate attributeName="font-size" from="30" to="60" values="30;80" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="fill" from="red" to="blue" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="opacity" from="0.3" to="1" dur="3s" repeatCount="indefinite">
</animate>
</text>
</svg>
</div>
```
![en-us_image_0000001183871404.gif](figures/en-us_image_0000001183871404.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) NOTE:
> When values is also set, the from and to settings do not take effect.
#### Motion Path Animation
In the [animateMotion](../reference/arkui-js/js-components-svg-animatemotion.md) child component of the &lt;svg&gt; component, set path to define a shape for the animation.
```
<!-- xxx.hml -->
<div class="container">
<svg fill="white" width="800" height="900">
<path d="M300,200 h-150 a150 150 0 1 0 150 -150 z" fill="white" stroke="blue" stroke-width="5" >
</path>
<path fill="red" d="M-5,-5 L10,0 L-5,5 L0,0 Z" >
<animateMotion dur="2000" repeatCount="indefinite" rotate="auto-reverse"path="M300,200 h-150 a150 150 0 1 0 150 -150 z">
</animateMotion>
</path>
</svg>
</div>
```
![en-us_image_0000001229510983.gif](figures/en-us_image_0000001229510983.gif)
#### animateTransform Animation
In the [animateTransform](../reference/arkui-js/js-components-svg-animatetransform.md) child component of the &lt;svg&gt; component, set attributeName to bind the corresponding attribute to the transform attribute, and set type to the animation type, from to the start value, and to to the end value.
```
<!-- xxx.hml -->
<div class="container" style="">
<svg>
<line x1="90" y1="300" x2="90" y2="730" stroke-width="10" stroke="black" stroke-linecap="round">
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="3s" values="0;30;10;30;20;30;25;30" keyTimes="0;0.3;0.5;0.7;0.8;0.9;1.0;1.1"
fill="freeze">
</animateTransform>
</line>
<circle cx="500" cy="500" r="50" stroke-width="15" fill="red" stroke="#e70d0d">
<animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="3s" values="0;30;10;30;20;30;25;30" keyTimes="0;0.3;0.5;0.7;0.8;0.9;1.0;1.1" fill="freeze">
</animateTransform>
<animateTransform attributeName="transform" attributeType="XML" type="scale" dur="6s" values="1;1;1.3" keyTimes="0;0.5;1" fill="freeze"></animateTransform>
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="9s" values="0;0;300 7" keyTimes="0;0.6;0.9" fill="freeze"></animateTransform>
</circle>
<rect width="500" height="200" x="90" y="840">
<animateTransform attributeName="transform" attributeType="XML" type="skewY" dur="6s" values="0;0;30" keyTimes="0;0.5;1" fill="freeze"></animateTransform>
</rect>
<line x1="650" y1="300" x2="650" y2="600" stroke-width="20" stroke="blue" stroke-linecap="round">
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="9s" values="0;0;0 800" keyTimes="0;0.6;1" fill="freeze"></animateTransform>
</line>
</svg>
</div>
```
```
/* xxx.css */
.container {
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
background-color: #F1F3F5;
}
```
![en-us_image_0000001182832088.gif](figures/en-us_image_0000001182832088.gif)
\ No newline at end of file
# Defining Animations with the transform Attribute<a name="EN-US_TOPIC_0000001171687726"></a> # Defining Animations with the transform Attribute
Set the **transform** attribute for component rotation, scaling, translation, and skewing.
## Designing Static Animation<a name="section82321901242"></a> Set the transform attribute for component rotation, scaling, translation, and skewing.
## Designing Static Animation
Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the translate attribute of the rectangle to the coordinate (150px, -150px) to form a door, use the position attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component (square), set the scale attribute to scale up the parent and child components together to determine the window size, and use the skewX attribute to skew the component and set the coordinate translate(200px,-830px) to form a chimney.
Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the **translate** attribute of the rectangle to the coordinate \(150px, -150px\) to form a door, use the **position** attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component \(square\), set the **scale** attribute to scale up the parent and child components together to determine the window size, and use the **skewX** attribute to skew the component and set the coordinate **translate\(200px,-830px\)** to form a chimney.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -21,6 +24,7 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p ...@@ -21,6 +24,7 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -86,12 +90,14 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p ...@@ -86,12 +90,14 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p
} }
``` ```
![](figures/111-13.png) ![en-us_image_0000001267887841](figures/en-us_image_0000001267887841.png)
## Designing Translation Animation<a name="section1212234417247"></a> ## Designing Translation Animation
Decrease the y-coordinate over a time frame to make the ball bounce back. Gradually decrease the bounce height until it drops to 0. An animation where the ball falls is hereby created. Decrease the y-coordinate over a time frame to make the ball bounce back. Gradually decrease the bounce height until it drops to 0. An animation where the ball falls is hereby created.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
...@@ -100,6 +106,7 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua ...@@ -100,6 +106,7 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -162,11 +169,13 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua ...@@ -162,11 +169,13 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua
} }
``` ```
![](figures/q2.gif) ![en-us_image_0000001222967760](figures/en-us_image_0000001222967760.gif)
## Designing Rotation Animation
## Designing Rotation Animation<a name="section74101411112517"></a> Set the rotation center around an element in different transform-origin positions. Of the rotate3d values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise.
Set the rotation center around an element in different **transform-origin** positions. Of the **rotate3d** values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -187,6 +196,7 @@ Set the rotation center around an element in different **transform-origin** po ...@@ -187,6 +196,7 @@ Set the rotation center around an element in different **transform-origin** po
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -292,16 +302,18 @@ Set the rotation center around an element in different **transform-origin** po ...@@ -292,16 +302,18 @@ Set the rotation center around an element in different **transform-origin** po
} }
``` ```
![](figures/d2.gif) ![en-us_image_0000001222807776](figures/en-us_image_0000001222807776.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> transform-origin specifies the origin of an element's transformation. If only one value is set, the other value is 50%. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Designing Scaling Animation
>**transform-origin** specifies the origin of an element's transformation. If only one value is set, the other value is **50%**. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis.
## Designing Scaling Animation<a name="section137551633132519"></a> This example implements a ripple animation with the scale attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the opacity attribute to hide or display the components. To scale and hide/display a component at the same time, set both the scale and opacity attributes. Finally, set different animation durations for different components to achieve the diffusion effect.
This example implements a ripple animation with the **scale** attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the **opacity** attribute to hide or display the components. To scale and hide/display a component at the same time, set both the **scale** and **opacity** attributes. Finally, set different animation durations for different components to achieve the diffusion effect. Set the scaling values for the x-axis, y-axis, and z-axis in scale3d to implement the animation.
Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to implement the animation.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -318,6 +330,7 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im ...@@ -318,6 +330,7 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -333,14 +346,12 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im ...@@ -333,14 +346,12 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im
height: 100px; height: 100px;
border-radius: 50px; border-radius: 50px;
background:linear-gradient(#dcaec1, #d3a8e3); background:linear-gradient(#dcaec1, #d3a8e3);
z-index: 1; z-index: 1; position: absolute;
position: absolute;
} }
.ripple{ .ripple{
margin-top: 400px; margin-top: 400px;
margin-left: 40%; margin-left: 40%;
position: absolute; position: absolute; z-index: 0;
z-index: 0;
width: 100px; width: 100px;
height: 100px; height: 100px;
border-radius: 50px; border-radius: 50px;
...@@ -406,14 +417,16 @@ text{ ...@@ -406,14 +417,16 @@ text{
} }
``` ```
![](figures/d3.gif) ![en-us_image_0000001267887837](figures/en-us_image_0000001267887837.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> After the transform attributes are set, the child element changes with the parent element. Value changing of other attributes (such as height and width) of the parent element will not affect the child element.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Setting matrix
>After the **transform** attributes are set, the child element changes with the parent element. Value changing of other attributes \(such as **height** and **width**\) of the parent element will not affect the child element.
## Setting matrix<a name="section114961910132614"></a> The matrix attribute defines a transformation matrix with six input parameters: scaleX, skewY, skewX, scaleY, translateX, and translateY. In the following example, matrix is set to matrix(1,0,0,1,0,200) to skew and translate the component.
The **matrix** attribute defines a transformation matrix with six input parameters: **scaleX**, **skewY**, **skewX**, **scaleY**, **translateX**, and **translateY**. In the following example, **matrix** is set to **matrix\(1,0,0,1,0,200\)** to skew and translate the component.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -422,6 +435,7 @@ The **matrix** attribute defines a transformation matrix with six input parame ...@@ -422,6 +435,7 @@ The **matrix** attribute defines a transformation matrix with six input parame
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
...@@ -451,11 +465,13 @@ The **matrix** attribute defines a transformation matrix with six input parame ...@@ -451,11 +465,13 @@ The **matrix** attribute defines a transformation matrix with six input parame
} }
``` ```
![](figures/q3.gif) ![en-us_image_0000001267767853](figures/en-us_image_0000001267767853.gif)
## Integrating transform Attributes
## Integrating transform Attributes<a name="section20503152610"></a> You can set multiple transform attributes at the same time to apply different transformations to a component. The following example applies the scale, translate, and rotate attributes simultaneously.
You can set multiple **transform** attributes at the same time to apply different transformations to a component. The following example applies the **scale**, **translate**, and **rotate** attributes simultaneously.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -468,6 +484,7 @@ You can set multiple **transform** attributes at the same time to apply differ ...@@ -468,6 +484,7 @@ You can set multiple **transform** attributes at the same time to apply differ
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
...@@ -514,8 +531,7 @@ You can set multiple **transform** attributes at the same time to apply differ ...@@ -514,8 +531,7 @@ You can set multiple **transform** attributes at the same time to apply differ
/* Use change1 and change2 for comparison. */ /* Use change1 and change2 for comparison. */
@keyframes change1{ @keyframes change1{
0%{ 0%{
transform: translate(0,0); transform: translate(0,0); transform: rotate(0deg)
transform: rotate(0deg)
} }
100%{ 100%{
transform: translate(0,500px); transform: translate(0,500px);
...@@ -559,10 +575,11 @@ You can set multiple **transform** attributes at the same time to apply differ ...@@ -559,10 +575,11 @@ You can set multiple **transform** attributes at the same time to apply differ
} }
``` ```
![](figures/d4.gif) ![en-us_image_0000001223127712](figures/en-us_image_0000001223127712.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>1. When multiple **transform** attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one **transform**, for example, **transform: scale\(1\) rotate\(0\) translate\(0,0\)**.
>2. When using the shorthand notion, note that the animation effect varies according to the sequence of the style values.
>3. The style values in the **transform** attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> 1. When multiple transform attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one transform, for example, transform: scale(1) rotate(0) translate(0,0).
>
> 2. When using the shorthand notion, **NOTE** that the animation effect varies according to the sequence of the style values.
>
> 3. The style values in the transform attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played.
# Animation Development Guidelines<a name="EN-US_TOPIC_0000001164217296"></a>
- **[CSS Animation](ui-js-animate-css.md)**
- **[JS Animation](ui-js-animate-javascript.md)**
# Developing Animations<a name="EN-US_TOPIC_0000001063908646"></a> # Developing Animations
Animations are classified into [Static Animation](#section456613911492) and [Continuous Animation](#section17836125204914).
## Static Animation<a name="section456613911492"></a> Animations are classified into [Static Animation](#static-animation) and [Continuous Animation](#continuous-animation).
## Static Animation
The transform attributes are the core of the static animation. A static animation can transform in the following three ways and only once in each way at a time: The transform attributes are the core of the static animation. A static animation can transform in the following three ways and only once in each way at a time:
- **translate**: Moves a specified component horizontally or vertically. - translate: Moves a specified component horizontally or vertically.
- **scale**: Scales a specified component horizontally or vertically to the required scale.
- **rotate**: Rotates a specified component by a specified angle along the horizontal axis, vertical axis, or center point. - scale: Scales a specified component horizontally or vertically to the required scale.
- rotate: Rotates a specified component by a specified angle along the horizontal axis, vertical axis, or center point.
For more information, see [Component Methods](../reference/arkui-js/js-components-common-methods.md). The following is an example: For more information, see [Component Methods](../reference/arkui-js/js-components-common-methods.md). The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
...@@ -21,6 +26,7 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen ...@@ -21,6 +26,7 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -51,22 +57,30 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen ...@@ -51,22 +57,30 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen
} }
``` ```
**Figure 1** Static animation<a name="fig454415020219"></a>
![](figures/static-animation.png "static-animation")
## Continuous Animation<a name="section17836125204914"></a> figure1 Static animation
![en-us_image_0000001223127724](figures/en-us_image_0000001223127724.png)
## Continuous Animation
The static animation has only the start and end states. To set the transition state and conversion effect, use continuous animations. The static animation has only the start and end states. To set the transition state and conversion effect, use continuous animations.
The core of a continuous animation is animation attributes, which define the start and end states of the animation and the curve of time and speed. Animation attributes can implement the following effects: The core of a continuous animation is animation attributes, which define the start and end states of the animation and the curve of time and speed. Animation attributes can implement the following effects:
- **animation-name**: Background color, opacity, width, height, and transformation type applied to the element after the animation is executed - animation-name: Background color, opacity, width, height, and transformation type applied to the element after the animation is executed
- **animation-delay** and **animation-duration**: Element delay and duration after the animation is executed
- **animation-timing-function**: Speed curve of an animation, which makes the animation more fluent - animation-delay and animation-duration: Element delay and duration after the animation is executed
- **animation-iteration-count**: Number of animation playback times
- **animation-fill-mode**: Whether to restore the initial state after the animation is executed - animation-timing-function: Speed curve of an animation, which makes the animation more fluent
- animation-iteration-count: Number of animation playback times
- animation-fill-mode: Whether to restore the initial state after the animation is executed
To use the animation attributes, you need to define a @keyframes rule in the .css file, set the animation transition effect in @keyframes, and invoke the effect through a style class in the .hml file. The following is an example for animation-name:
To use the animation attributes, you need to define a @keyframes rule in the **.css** file, set the animation transition effect in @keyframes, and invoke the effect through a style class in the **.hml** file. The following is an example for **animation-name**:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -82,6 +96,7 @@ To use the animation attributes, you need to define a @keyframes rule in the ** ...@@ -82,6 +96,7 @@ To use the animation attributes, you need to define a @keyframes rule in the **
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.item-container { .item-container {
...@@ -131,6 +146,7 @@ To use the animation attributes, you need to define a @keyframes rule in the ** ...@@ -131,6 +146,7 @@ To use the animation attributes, you need to define a @keyframes rule in the **
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -147,6 +163,6 @@ export default { ...@@ -147,6 +163,6 @@ export default {
} }
``` ```
**Figure 2** Continuous animation effect<a name="fig1173091112515"></a> figure2 Continuous animation effect
![](figures/continuous-animation-effect.gif "continuous-animation-effect")
![en-us_image_0000001223287696](figures/en-us_image_0000001223287696.gif)
# Component Overview<a name="EN-US_TOPIC_0000001063340551"></a> # Component Overview
Components are the core of a UI page. Each component can provide visible and interactive functional units that are independent from each other. This is achieved by data and method encapsulation. You can use and reuse any component anywhere as needed. For details about how to use the components, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md).
Components are the core of a UI page. Each component can provide visible and interactive functional units that are independent from each other. This is achieved by data and method encapsulation. You can use and reuse any component anywhere as needed. For details about how to use the components, see [Components](../reference/arkui-js/js-components-common-attributes.md).
You can also customize a new component through proper combination of components to make the development simple and easy. For details about how to customize components, see [Custom Components](ui-js-custom-components.md). You can also customize a new component through proper combination of components to make the development simple and easy. For details about how to customize components, see [Custom Components](ui-js-custom-components.md).
## Classification<a name="section154381954142018"></a>
Components can be classified into the following types based on their functions. ## Classification
<a name="table5353044132913"></a> Components can be classified into the following types based on their functions.
<table><thead align="left"><tr id="row18353134417291"><th class="cellrowborder" valign="top" width="33.23%" id="mcps1.1.3.1.1"><p id="p9353844172910"><a name="p9353844172910"></a><a name="p9353844172910"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="66.77%" id="mcps1.1.3.1.2"><p id="p17353194412910"><a name="p17353194412910"></a><a name="p17353194412910"></a>Components</p>
</th>
</tr>
</thead>
<tbody><tr id="row735474422917"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p135464414291"><a name="p135464414291"></a><a name="p135464414291"></a>Container</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p163541544152914"><a name="p163541544152914"></a><a name="p163541544152914"></a>badge, dialog, div, form, list, list-item, list-item-group, panel, popup, refresh, stack, stepper, stepper-item, swiper, tabs, tab-bar, tab-content</p>
</td>
</tr>
<tr id="row5354124411297"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p33541644182911"><a name="p33541644182911"></a><a name="p33541644182911"></a>Basic</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p171418529304"><a name="p171418529304"></a><a name="p171418529304"></a>button, chart, divider, image, image-animator, input, label, marquee, menu, option, picker, picker-view, piece, progress, qrcode, rating, richtext, search, select, slider, span, switch, text, textarea, toolbar, toolbar-item, toggle</p>
</td>
</tr>
<tr id="row1235411446292"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p535419445292"><a name="p535419445292"></a><a name="p535419445292"></a>Media</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p113542443298"><a name="p113542443298"></a><a name="p113542443298"></a>video</p>
</td>
</tr>
<tr id="row1935454413298"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p14354184402911"><a name="p14354184402911"></a><a name="p14354184402911"></a>Canvas</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p435484419292"><a name="p435484419292"></a><a name="p435484419292"></a>canvas</p>
</td>
</tr>
<tr id="row138471514133011"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p2848141417309"><a name="p2848141417309"></a><a name="p2848141417309"></a>Grid</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p1824219411343"><a name="p1824219411343"></a><a name="p1824219411343"></a>grid-container, grid-row, grid-col</p>
</td>
</tr>
<tr id="row1199452616306"><td class="cellrowborder" valign="top" width="33.23%" headers="mcps1.1.3.1.1 "><p id="p99943266305"><a name="p99943266305"></a><a name="p99943266305"></a>SVG</p>
</td>
<td class="cellrowborder" valign="top" width="66.77%" headers="mcps1.1.3.1.2 "><p id="p129949269305"><a name="p129949269305"></a><a name="p129949269305"></a>svg, rect, circle, ellipse, path, line, polyline, polygon, text, tspan, textPath, animate, animateMotion, animateTransform</p>
</td>
</tr>
</tbody>
</table>
| Type | Components |
| -------- | -------- |
| Container | badge, dialog, div, form, list, list-item, list-item-group, panel, popup, refresh, stack, stepper, stepper-item, swiper, tabs, tab-bar, tab-content |
| Basic | button, chart, divider, image, image-animator, input, label, marquee, menu, option, picker, picker-view, piece, progress, qrcode, rating, richtext, search, select, slider, span, switch, text, textarea, toolbar, toolbar-item, toggle |
| Media | video |
| Canvas | canvas |
| Grid | grid-container, grid-row, grid-col |
| SVG | svg, rect, circle, ellipse, path, line, polyline, polygon, text, tspan, textPath, animate, animateMotion, animateTransform |
# Defining Events<a name="EN-US_TOPIC_0000001063300566"></a> # Defining Events
Events mainly include gesture events for touchscreen devices. Events mainly include gesture events for touchscreen devices.
## Gesture Events<a name="section21104561094"></a>
A gesture represents a semantic action \(for example, tap, drag, or longpress\) that can trigger one or more events. A gesture lifecycle may consist of multiple events from the start to the end of the gesture. Supported events: ## Gesture Events
A gesture represents a semantic action (for example, tap, drag, or longpress) that can trigger one or more events. A gesture lifecycle may consist of multiple events from the start to the end of the gesture. Supported events:
Touch
- touchstart: Triggered when the touch starts
- touchmove: Triggered when the touch moves
**Touch** - touchcancel: Triggered when the touch is interrupted, for example, by an incoming call notification or pop-up message
- **touchstart**: Triggered when the touch starts - touchend: Triggered when the touch ends
- **touchmove**: Triggered when the touch moves
- **touchcancel**: Triggered when the touch is interrupted, for example, by an incoming call notification or pop-up message
- **touchend**: Triggered when the touch ends
**Click** Click
**click**: Triggered when a user taps the screen quickly. click: Triggered when a user taps the screen quickly.
**Longpress** Longpress
**longpress**: Triggered when a user keeps tapping the screen at the same position for a while. longpress: Triggered when a user keeps tapping the screen at the same position for a while.
The following is an example: The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
...@@ -47,6 +52,7 @@ The following is an example: ...@@ -47,6 +52,7 @@ The following is an example:
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -70,6 +76,7 @@ The following is an example: ...@@ -70,6 +76,7 @@ The following is an example:
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -101,4 +108,3 @@ export default { ...@@ -101,4 +108,3 @@ export default {
}, },
} }
``` ```
# Adding Interactions<a name="EN-US_TOPIC_0000001064068636"></a> # Adding Interactions
You can make the UI interactive by binding events to components. This section describes how to bind **<div\>**, **<text\>**, and **<image\>** components to click events to build a thumb up button, as shown in the following figure. You can make the UI interactive by binding events to components. This section describes how to bind &lt;div&gt;, &lt;text&gt;, and &lt;image&gt; components to click events to build a thumb up button, as shown in the following figure.
figure1 Thumb up button effect
**Figure 1** Thumb up button effect<a name="fig071716222515"></a> ![en-us_image_0000001267647901](figures/en-us_image_0000001267647901.gif)
![](figures/zan.gif) The thumb up button is implemented by binding a click event to a &lt;div&gt; component. The &lt;div&gt; component contains an &lt;image&gt; component and a &lt;text&gt; component.
The thumb up button is implemented by binding a click event to a **<div\>** component. The **<div\>** component contains an **<image\>** component and a **<text\>** component.
- The **<image\>** component is used to display unselected and selected \(highlighted\) thumbs up images. The click event function alternately updates the paths of the images that are liked and not liked. - The &lt;image&gt; component is used to display unselected and selected (highlighted) thumbs up images. The click event function alternately updates the paths of the images that are liked and not liked.
- The **<text\>** component is used to display the number of thumbs up. The number is updated in the function of the click event.
The click event calls the **likeClick\(\)** function defined in the **.js** file. You can change the value of **isPressed** to update the image component. If the value of **isPressed** is **true**, the number of thumbs up is incremented by 1. The **likeClick\(\)** function takes effect on the **<div\>** component in the **.hml** file. The style of each child component for the thumbs up button is set in the **.css** file. The following is an example: - The &lt;text&gt; component is used to display the number of thumbs up. The number is updated in the function of the click event.
The click event calls the likeClick() function defined in the .js file. You can change the value of isPressed to update the image component. If the value of isPressed is true, the number of thumbs up is incremented by 1. The likeClick() function takes effect on the &lt;div&gt; component in the .hml file. The style of each child component for the thumbs up button is set in the .css file. The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -71,5 +73,5 @@ export default { ...@@ -71,5 +73,5 @@ export default {
} }
``` ```
ArkUI also provides many form components, such as switches, tags, and pickers, for you to flexibly lay out pages and improve their interactions with users. For details, see [Container Components](../reference/arkui-js/js-components-container.md).
ArkUI also provides many form components, such as switches, tags, and pickers, for you to flexibly lay out pages and improve their interactions with users. For details, see Container Components.
# Adding a Comment<a name="EN-US_TOPIC_0000001063470826"></a> # Adding a Comment
After a user enters a comment and clicks the submit button, the content is displayed in the comment area. The user can click the delete button to delete the current comment and enter another comment again. After a user enters a comment and clicks the submit button, the content is displayed in the comment area. The user can click the delete button to delete the current comment and enter another comment again.
To set such a comment area on a page, you need to associate a click event with **<div\>**, **<text\>**, and **<input\>**. You can use the **<input\>** component to obtain the comment entered by a user, use the **<text\>** component to display the comment, and use **commentText** to mark the **<text\>** component \(controlled by the **if** attribute\). Associate the click event with the **<text\>** component that contains **Done** and **Delete** to update the **commentText** and **inputValue**. The following is an example:
To set such a comment area on a page, you need to associate a click event with &lt;div&gt;, &lt;text&gt;, and &lt;input&gt;. You can use the &lt;input&gt; component to obtain the comment entered by a user, use the &lt;text&gt; component to display the comment, and use commentText to mark the &lt;text&gt; component (controlled by the if attribute). Associate the click event with the &lt;text&gt; component that contains Done and Delete to update the commentText and inputValue. The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -19,6 +21,8 @@ To set such a comment area on a page, you need to associate a click event with ...@@ -19,6 +21,8 @@ To set such a comment area on a page, you need to associate a click event with
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -60,6 +64,8 @@ To set such a comment area on a page, you need to associate a click event with ...@@ -60,6 +64,8 @@ To set such a comment area on a page, you need to associate a click event with
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -75,4 +81,3 @@ export default { ...@@ -75,4 +81,3 @@ export default {
}, },
} }
``` ```
# Adding a Container<a name="EN-US_TOPIC_0000001062990841"></a> # Adding a Container
To assemble the basic elements of a page, you need a container component. The **<div\>**, **<list\>**, and **<tabs\>** components are commonly used for laying out page elements. You can use **<div\>** as the container in a page with simple layout. **<div\>** supports a variety of child components required to build the page.
## <List\><a name="section1875054932714"></a> To assemble the basic elements of a page, you need a container component. The &lt;div&gt;, &lt;list&gt;, and &lt;tabs&gt; components are commonly used for laying out page elements. You can use &lt;div&gt; as the container in a page with simple layout. &lt;div&gt; supports a variety of child components required to build the page.
## &lt;List&gt;
If you use &lt;div&gt; repeatedly to render a complex page, frame freezing may occur. In this case, use the &lt;list&gt; component instead of &lt;div&gt; to lay out list items, which provides a smooth list scrolling. **NOTE** that &lt;list&gt; supports only &lt;list-item&gt; as it child components. The following is an example:
If you use **<div\>** repeatedly to render a complex page, frame freezing may occur. In this case, use the **<list\>** component instead of **<div\>** to lay out list items, which provides a smooth list scrolling. Note that **<list\>** supports only **<list-item\>** as it child components. The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -15,6 +18,7 @@ If you use **<div\>** repeatedly to render a complex page, frame freezing may ...@@ -15,6 +18,7 @@ If you use **<div\>** repeatedly to render a complex page, frame freezing may
</list> </list>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.desc-text { .desc-text {
...@@ -23,6 +27,7 @@ If you use **<div\>** repeatedly to render a complex page, frame freezing may ...@@ -23,6 +27,7 @@ If you use **<div\>** repeatedly to render a complex page, frame freezing may
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -32,11 +37,13 @@ export default { ...@@ -32,11 +37,13 @@ export default {
} }
``` ```
To shorten the sample code, the list contains only one **<list-item\>** component that holds only one **<text\>** component. In practice, a **<list\>** has multiple **<list-item\>** components, and a **<list-item\>** has multiple child components. To shorten the sample code, the list contains only one &lt;list-item&gt; component that holds only one &lt;text&gt; component. In practice, a &lt;list&gt; has multiple &lt;list-item&gt; components, and a &lt;list-item&gt; has multiple child components.
## <Tabs\><a name="section91861363535"></a>
If your page needs to be dynamically loaded, use the **<tabs\>** component. This component supports the change event, which is triggered after tab switching. A **<tabs\>** component can hold only one **<tab-bar\>** and one **<tab-content\>**. The following is an example: ## &lt;Tabs&gt;
If your page needs to be dynamically loaded, use the &lt;tabs&gt; component. This component supports the change event, which is triggered after tab switching. A &lt;tabs&gt; component can hold only one &lt;tab-bar&gt; and one &lt;tab-content&gt;. The following is an example:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -54,6 +61,7 @@ If your page needs to be dynamically loaded, use the **<tabs\>** component. Th ...@@ -54,6 +61,7 @@ If your page needs to be dynamically loaded, use the **<tabs\>** component. Th
</tabs> </tabs>
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -65,5 +73,4 @@ export default { ...@@ -65,5 +73,4 @@ export default {
} }
``` ```
The **<tab-content\>** component is used to display the tab content, which vertically fills the remaining space of the **<tabs\>** component by default. The &lt;tab-content&gt; component is used to display the tab content, which vertically fills the remaining space of the &lt;tabs&gt; component by default.
# Adding an Image<a name="EN-US_TOPIC_0000001063590816"></a> # Adding an Image
Generally, the [**<image\>**](../reference/arkui-js/js-components-basic-image.md) component is used to add images on a page. The method of using this component is similar to that of using the **<text\>** component.
To reference images via the **<image\>** component, you must create the **common** directory under **js** \> **default**, and then store the image files in the **common** directory. For details about the directory structure, see [Directory Structure](js-framework-file.md). The following sample code shows you how to add an image and set its style. Generally, the [&lt;image&gt;](../reference/arkui-js/js-components-basic-image.md)component is used to add images on a page. The method of using this component is similar to that of using the &lt;text&gt; component.
To reference images via the &lt;image&gt; component, you must create the common directory under jsdefault, and then store the image files in the common directory. For details about the directory structure, see [Directory Structure](js-framework-file.md). The following sample code shows you how to add an image and set its style.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -26,4 +28,3 @@ export default { ...@@ -26,4 +28,3 @@ export default {
}, },
} }
``` ```
# Layout Description<a name="EN-US_TOPIC_0000001063230905"></a> # Layout Description
The baseline width for page design is 720 logical pixels. The display width of a page element depends on the ratio of the screen width to the baseline width. The baseline width for page design is 720 logical pixels. The display width of a page element depends on the ratio of the screen width to the baseline width.
For example, when the width of a component is 100 px, its display width is converted as follows: For example, when the width of a component is 100 px, its display width is converted as follows:
On a screen with the width of 720 physical pixels, the display width is 100 physical pixels. On a screen with the width of 1440 physical pixels, the display width is 200 physical pixels. On a screen with the width of 720 physical pixels, the display width is 100 physical pixels. On a screen with the width of 1440 physical pixels, the display width is 200 physical pixels.
Basic page elements include title, text, and image areas. Each basic element may contain multiple sub-elements. You can add components, such as buttons, switches, and progress bars, to these elements and sub-elements as required. When setting the layout, you need to consider the following for each basic element: Basic page elements include title, text, and image areas. Each basic element may contain multiple sub-elements. You can add components, such as buttons, switches, and progress bars, to these elements and sub-elements as required. When setting the layout, you need to consider the following for each basic element:
- Size and arrangement - Size and arrangement
- Overlapping with other elements - Overlapping with other elements
- Alignment, padding, and margin - Alignment, padding, and margin
- Sub-elements and their positions
- Container components and their types
You can disassemble elements on the page first and then implement them in sequence. This reduces visual confusion and logical conflicts caused by element nesting and improves code readability for easier modification. For example, as shown below, you disassemble the page elements and elements in the comment area. - Sub-elements and their positions
**Figure 1** Page layout<a name="fig11335192315417"></a> - Container components and their types
![](figures/page-layout.png "page-layout")
**Figure 2** Layout of the comment area<a name="fig186911810182717"></a> You can disassemble elements on the page first and then implement them in sequence. This reduces visual confusion and logical conflicts caused by element nesting and improves code readability for easier modification. For example, as shown below, you disassemble the page elements and elements in the comment area.
figure1 Page layout
![en-us_image_0000001222967792](figures/en-us_image_0000001222967792.png)
![](figures/figures3.png) figure2 Layout of the comment area
![en-us_image_0000001267767889](figures/en-us_image_0000001267767889.png)
# Adding Title and Paragraph Text<a name="EN-US_TOPIC_0000001063749052"></a> # Adding Title and Paragraph Text
The &lt;text&gt; component is most commonly used to display text in title and paragraph areas. You can set attributes and styles for a &lt;text&gt; component and add the text to be displayed between the &lt;text&gt; and &lt;/text&gt; tags. For details about the attributes and styles, see [text](../reference/arkui-js/js-components-basic-text.md). The following is an example of adding title and paragraph text on a page:
The **<text\>** component is most commonly used to display text in title and paragraph areas. You can set attributes and styles for a **<text\>** component and add the text to be displayed between the **<text\>** and **</text\>** tags. For details about the attributes and styles, see [text](../reference/arkui-js/js-components-basic-text.md). The following is an example of adding title and paragraph text on a page:
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -11,6 +14,8 @@ The **<text\>** component is most commonly used to display text in title and p ...@@ -11,6 +14,8 @@ The **<text\>** component is most commonly used to display text in title and p
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -31,6 +36,8 @@ The **<text\>** component is most commonly used to display text in title and p ...@@ -31,6 +36,8 @@ The **<text\>** component is most commonly used to display text in title and p
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -41,4 +48,3 @@ export default { ...@@ -41,4 +48,3 @@ export default {
}, },
} }
``` ```
# Building the Layout<a name="EN-US_TOPIC_0000001063148753"></a>
- **[Layout Description](ui-js-building-ui-layout-intro.md)**
- **[Adding Title and Paragraph Text](ui-js-building-ui-layout-text.md)**
- **[Adding an Image](ui-js-building-ui-layout-image.md)**
- **[Adding a Comment](ui-js-building-ui-layout-comment.md)**
- **[Adding a Container](ui-js-building-ui-layout-external-container.md)**
# Defining Page Routes<a name="EN-US_TOPIC_0000001063442795"></a> # Defining Page Routes
Many applications consist of more than one page. For example, in a music application, a user taps a song on a music list page, and then needs to jump to the playback page of the song. You need to link these pages through page routing to implement redirection as required.
The page router finds the target page based on the page URI. The following describes how to switch between two pages: An application generally consist of more than one page. For example, in a music application, a user taps a song on a music list page to jump to the playback page of the song. You need to link these pages through the page router to implement redirection as required.
1. In the **Project** window of DevEco Studio, choose **entry \> src \> main** \> **js** \> **default**. Right-click the **pages** folder and choose **New****JS Page** from the shortcut menu to create the **detail** page.
2. Call **router.push\(\)** to navigate users to the **detail** page.
3. Call **router.back\(\)** to navigate users to the **index** page.
## Building the Page Layout<a name="section135242911291"></a> The page router finds the target page based on the page URI. The following describes how to implement redirection between two pages:
1. In the “Project“ window of DevEco Studio, choose entry > src > mainjsdefault. Right-click the pages folder and choose NewJS Page from the shortcut menu to create the detail page.
2. Call router.push() to navigate users to the detail page.
3. Call router.back() to navigate users to the index page.
## Building the Page Layout
The index and detail pages each contains a &lt;text> component that specifies the current page, and a &lt;button&gt; component that implements the switching between two pages. Example code in .hml files is as follows:
The **index** and **detail** pages each contains a **<text\>** component that specifies the current page, and a **<button\>** component that implements the switching between two pages. Example code in **.hml** files is as follows:
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -20,6 +27,7 @@ The **index** and **detail** pages each contains a **<text\>** component t ...@@ -20,6 +27,7 @@ The **index** and **detail** pages each contains a **<text\>** component t
</div> </div>
``` ```
``` ```
<!-- detail.hml --> <!-- detail.hml -->
<div class="container"> <div class="container">
...@@ -28,9 +36,11 @@ The **index** and **detail** pages each contains a **<text\>** component t ...@@ -28,9 +36,11 @@ The **index** and **detail** pages each contains a **<text\>** component t
</div> </div>
``` ```
## Setting Page Styles<a name="section174441114183216"></a>
Set styles for the **index** and **detail** pages. Centers the **<text\>** and **<button\>** components and spaces the two components with 50 pixels. The CSS code for the two pages is as follows: ## Setting Page Styles
Set styles for the index and detail pages. Center the &lt;text&gt; and &lt;button&gt; components and space the two components with 50 pixels. The CSS code for the two pages is as follows:
``` ```
/* index.css */ /* index.css */
...@@ -47,9 +57,11 @@ Set styles for the **index** and **detail** pages. Centers the **<text\>** ...@@ -47,9 +57,11 @@ Set styles for the **index** and **detail** pages. Centers the **<text\>**
} }
``` ```
## Setting the Switch<a name="section1276711211359"></a>
To make the **launch** method of the **<button\>** component take effect, the redirection logic needs to be implemented in the **.js** file of the page. Call **router.push\(\)** to add the page URI to the route stack, that is, to jump to the page specified by the URI. You need to import the router module before calling the router method. The sample code is as follows: ## Implementing Redirection
To make the launch method of the &lt;button&gt; component take effect, the redirection logic needs to be implemented in the .js file of the page. Call router.push() to add the page URI to the route stack, that is, to jump to the page specified by the URI. You need to import the router module before calling the router method. The sample code is as follows:
``` ```
// index.js // index.js
...@@ -63,6 +75,7 @@ export default { ...@@ -63,6 +75,7 @@ export default {
} }
``` ```
``` ```
// detail.js // detail.js
import router from '@system.router'; import router from '@system.router';
...@@ -73,8 +86,8 @@ export default { ...@@ -73,8 +86,8 @@ export default {
} }
``` ```
The following figure shows the effect. The figure below shows the effect.
**Figure 1** Page routing<a name="fig41915914355"></a> figure1 Page routing
![](figures/page-routing.png "page-routing")
![en-us_image_0000001222967784](figures/en-us_image_0000001222967784.png)
# Building the UI<a name="EN-US_TOPIC_0000001063580501"></a>
- **[Component Overview](ui-js-building-ui-component.md)**
- **[Building the Layout](ui-js-building-ui-layout.md)**
- **[Adding Interactions](ui-js-building-ui-interactions.md)**
- **[Developing Animations](ui-js-building-ui-animation.md)**
- **[Defining Events](ui-js-building-ui-event.md)**
- **[Defining Page Routes](ui-js-building-ui-routes.md)**
# Common Component Development Guidelines<a name="EN-US_TOPIC_0000001154666642"></a>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The sample code provided in this document is applicable to the 720 px screen width on the phones.
- **[Text](ui-js-components-text.md)**
- **[Input](ui-js-components-input.md)**
- **[Button](ui-js-components-button.md)**
- **[List](ui-js-components-list.md)**
- **[Picker](ui-js-components-picker.md)**
- **[Dialog](ui-js-components-dialog.md)**
- **[Form](ui-js-components-form.md)**
- **[Stepper](ui-js-components-stepper.md)**
- **[Tabs](ui-js-component-tabs.md)**
- **[Image](ui-js-components-images.md)**
# Tabs<a name="EN-US_TOPIC_0000001157214240"></a> # &lt;tabs&gt; Development
The **<tabs\>** component is a common UI component for navigation. It allows quick access to different functions of an app. For details, see [tabs](../reference/arkui-js/js-components-container-tabs.md).
## Creating Tabs<a name="section1820920264"></a> The &lt;tabs&gt; component is a common UI component for navigation. It allows quick access to different functions of an app. For details, see [tabs](../reference/arkui-js/js-components-container-tabs.md).
## Creating Tabs
Create a &lt;tabs&gt; component in the .hml file under pages/index.
Create a **<tabs\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -26,6 +29,7 @@ Create a **<tabs\>** component in the **.hml** file under **pages/index**. ...@@ -26,6 +29,7 @@ Create a **<tabs\>** component in the **.hml** file under **pages/index**.
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -42,11 +46,13 @@ Create a **<tabs\>** component in the **.hml** file under **pages/index**. ...@@ -42,11 +46,13 @@ Create a **<tabs\>** component in the **.hml** file under **pages/index**.
} }
``` ```
![](figures/3-9.gif) ![en-us_image_0000001223287676](figures/en-us_image_0000001223287676.gif)
## Setting the Tabs Orientation
## Setting the Tabs Orientation<a name="section1696313408199"></a> By default, the active tab of a &lt;tabs&gt; component is the one with the specified index. To show the &lt;tabs&gt; vertically, set the vertical attribute to true.
By default, the active tab of a **<tabs\>** component is the one with the specified **index**. To show the **<tabs\>** vertically, set the **vertical** attribute to **true**.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -68,9 +74,10 @@ By default, the active tab of a **<tabs\>** component is the one with the spec ...@@ -68,9 +74,10 @@ By default, the active tab of a **<tabs\>** component is the one with the spec
</div> </div>
``` ```
![](figures/29.gif) ![en-us_image_0000001222967756](figures/en-us_image_0000001222967756.gif)
Set the mode attribute to enable the child components of the <tab-bar> to be evenly distributed. Set the scrollable attribute to disable scrolling of the <tab-content>.
Set the **mode** attribute to enable the child components of the **<tab-bar\>** to be evenly distributed. Set the **scrollable** attribute to disable scrolling of the **<tab-content\>**.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -92,11 +99,12 @@ Set the **mode** attribute to enable the child components of the **<tab-bar\> ...@@ -92,11 +99,12 @@ Set the **mode** attribute to enable the child components of the **<tab-bar\>
</div> </div>
``` ```
![](figures/30.gif) ![en-us_image_0000001267647857](figures/en-us_image_0000001267647857.gif)
## Setting the Style<a name="section482815298502"></a> ## Setting the Style
Set the background color, border, and tab-content layout of the **<tabs\>** component. Set the background color, border, and tab-content layout of the &lt;tabs&gt; component.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -118,6 +126,7 @@ Set the background color, border, and tab-content layout of the **<tabs\>** co ...@@ -118,6 +126,7 @@ Set the background color, border, and tab-content layout of the **<tabs\>** co
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -141,16 +150,17 @@ Set the background color, border, and tab-content layout of the **<tabs\>** co ...@@ -141,16 +150,17 @@ Set the background color, border, and tab-content layout of the **<tabs\>** co
margin-top: 10px; margin-top: 10px;
height: 300px; height: 300px;
color: blue; color: blue;
justify-content: center; justify-content: center; align-items: center;
align-items: center;
} }
``` ```
![](figures/31.gif) ![en-us_image_0000001267767857](figures/en-us_image_0000001267767857.gif)
## Displaying the Tab Index<a name="section331041121215"></a>
Add the **change** event for the **<tabs\>** component to display the index of the current tab after tab switching. ## Displaying the Tab Index
Add the change event for the &lt;tabs&gt; component to display the index of the current tab after tab switching.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -172,6 +182,7 @@ Add the **change** event for the **<tabs\>** component to display the index ...@@ -172,6 +182,7 @@ Add the **change** event for the **<tabs\>** component to display the index
</div> </div>
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -184,17 +195,19 @@ export default { ...@@ -184,17 +195,19 @@ export default {
} }
``` ```
![](figures/32.gif) ![en-us_image_0000001222807772](figures/en-us_image_0000001222807772.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - A &lt;tabs&gt; can wrap at most one [<tab-bar>](../reference/arkui-js/js-components-container-tab-bar.md) and at most one [<tab-content>](../reference/arkui-js/js-components-container-tab-content.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>
>- A **<tabs\>** can wrap at most one [**<tab-bar\>**](../reference/arkui-js/js-components-container-tab-bar.md) and at most one [**<tab-content\>**](../reference/arkui-js/js-components-container-tab-content.md).
## Example Scenario<a name="section1117302718531"></a> ## Example Scenario
In this example, you can switch between tabs and the active tab has the title text in red with an underline below. In this example, you can switch between tabs and the active tab has the title text in red with an underline below.
Use the **<tabs\>**, **<tab-bar\>**, and **<tab-content\>** components to implement tab switching. Then define the arrays and attributes. Add the **change** event to change the attribute values in the arrays so that the active tab has a different font color and an underline. Use the &lt;tabs&gt;, <tab-bar>, and <tab-content> components to implement tab switching. Then define the arrays and attributes. Add the change event to change the attribute values in the arrays so that the active tab has a different font color and an underline.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -224,10 +237,11 @@ Use the **<tabs\>**, **<tab-bar\>**, and **<tab-content\>** components to im ...@@ -224,10 +237,11 @@ Use the **<tabs\>**, **<tab-bar\>**, and **<tab-content\>** components to im
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
background-color:#F1F3F5; background-color:#F1F3F5;
} }
.tab_bar { .tab_bar {
width: 100%; width: 100%;
...@@ -256,6 +270,7 @@ Use the **<tabs\>**, **<tab-bar\>**, and **<tab-content\>** components to im ...@@ -256,6 +270,7 @@ Use the **<tabs\>**, **<tab-bar\>**, and **<tab-content\>** components to im
} }
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -299,5 +314,4 @@ export default { ...@@ -299,5 +314,4 @@ export default {
} }
``` ```
![](figures/33.gif) ![en-us_image_0000001267607885](figures/en-us_image_0000001267607885.gif)
# Button<a name="EN-US_TOPIC_0000001202654279"></a> # &lt;button&gt; Development
The **<button\>** component can be used to set a capsule, circle, text, arc, or download button. For details, see [button](../reference/arkui-js/js-components-basic-button.md).
## Creating a <button\> Component<a name="section1483585710237"></a> The&lt;button&gt;component can be used to set a capsule, circle, text, arc, or download button. For details, see [button](../reference/arkui-js/js-components-basic-button.md).
## Creating a &lt;button&gt; Component
Create a &lt;button&gt; component in the .hml file under pages/index.
Create a **<button\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -13,6 +16,7 @@ Create a **<button\>** component in the **.hml** file under **pages/index** ...@@ -13,6 +16,7 @@ Create a **<button\>** component in the **.hml** file under **pages/index**
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -23,11 +27,12 @@ Create a **<button\>** component in the **.hml** file under **pages/index** ...@@ -23,11 +27,12 @@ Create a **<button\>** component in the **.hml** file under **pages/index**
} }
``` ```
![](figures/3-2.png) ![en-us_image_0000001267887821](figures/en-us_image_0000001267887821.png)
## Setting the Button Type<a name="section1599710524112"></a>
Set the **type** attribute of the **<input\>** component to **button**, **date**, or any of the supported values. ## Setting the Button Type
Set the type attribute of the &lt;input&gt; component to button, date, or any of the supported values.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -61,15 +66,21 @@ Set the **type** attribute of the **<input\>** component to **button**, ** ...@@ -61,15 +66,21 @@ Set the **type** attribute of the **<input\>** component to **button**, **
} }
``` ```
![](figures/05-3.png)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001222967744](figures/en-us_image_0000001222967744.png)
>- For capsule buttons, border-related styles are not supported.
>- For circle buttons, text-related styles are not supported.
>- For text buttons, the text size is adaptive, and **radius**, **width**, and **height** cannot be set. The **background-color** style is not supported when the background is completely transparent. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
>- If the icon used by the **<button\>** component is from the cloud, you must declare the **ohos.permission.INTERNET** permission in the **config.json** file under the **resources** folder. > - For capsule buttons, border-related styles are not supported.
>
> - For circle buttons, text-related styles are not supported.
>
> - For text buttons, the text size is adaptive, and radius, width, and height cannot be set. The background-color style is not supported when the background is completely transparent.
>
> - If the icon used by the&lt;button&gt;component is from the cloud, you must declare the ohos.permission.INTERNET permission in the config.json file under the resources folder.
Sample code for declaring the **ohos.permission.INTERNET** permission in the **config.json** file under the **resources** folder: Sample code for declaring the ohos.permission.INTERNET permission in the config.json file under the resources folder:
``` ```
<!-- config.json --> <!-- config.json -->
...@@ -80,9 +91,11 @@ Sample code for declaring the **ohos.permission.INTERNET** permission in the ...@@ -80,9 +91,11 @@ Sample code for declaring the **ohos.permission.INTERNET** permission in the
} }
``` ```
## Showing the Download Progress<a name="section12724145171819"></a>
Add the **progress** method to the **<button\>** component to display the download progress in real time. ## Showing the Download Progress
Add the progress method to the&lt;button&gt;component to display the download progress in real time.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -91,6 +104,7 @@ Add the **progress** method to the **<button\>** component to display the do ...@@ -91,6 +104,7 @@ Add the **progress** method to the **<button\>** component to display the do
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -106,6 +120,7 @@ Add the **progress** method to the **<button\>** component to display the do ...@@ -106,6 +120,7 @@ Add the **progress** method to the **<button\>** component to display the do
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -154,13 +169,14 @@ export default { ...@@ -154,13 +169,14 @@ export default {
} }
``` ```
![](figures/34.gif) ![en-us_image_0000001223287652](figures/en-us_image_0000001223287652.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> >
>- The **setProgress** method supports only buttons of the download type. > The setProgress method supports only buttons of the download type.
## Example Scenario<a name="section64731917115116"></a> ## Example Scenario
Switch between the button types for different types of text. Switch between the button types for different types of text.
...@@ -262,5 +278,5 @@ export default { ...@@ -262,5 +278,5 @@ export default {
} }
``` ```
![](figures/21.gif)
![en-us_image_0000001222967740](figures/en-us_image_0000001222967740.gif)
# Dialog<a name="EN-US_TOPIC_0000001201895755"></a> # &lt;dialog&gt; Development
The **<dialog\>** component is custom pop-up container for showing critical information or calling for an action. For details, see [dialog](../reference/arkui-js/js-components-container-dialog.md).
## Creating a <dialog\> Component<a name="section174764398569"></a> The &lt;dialog&gt; component is custom pop-up container for showing critical information or calling for an action. For details, see [dialog](../reference/arkui-js/js-components-container-dialog.md).
Create a **<dialog\>** component in the **.hml** file under **pages/index** and add **<button\>** components to trigger the **<dialog\>**. The **<dialog\>** component supports only the **width**, **height**, **margin**, **margin-\[left|top|right|bottom\]**, and **margin-\[start|end\]** styles.
## Creating a &lt;dialog&gt; Component
Create a &lt;dialog&gt; component in the .hml file under pages/index and add &lt;button&gt; components to trigger the &lt;dialog&gt;. The &lt;dialog&gt; component supports only the width, height, margin, margin-[left|top|right|bottom], and margin-[start|end] styles.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="doc-page"> <div class="doc-page">
<dialog class="dialogClass" id="dialogId"> <dialog class="dialogClass" id="dialogId"><div class="content">
<div class="content">
<text>this is a dialog</text> <text>this is a dialog</text>
</div> </div>
</dialog> </dialog>
...@@ -18,6 +19,7 @@ Create a **<dialog\>** component in the **.hml** file under **pages/index** ...@@ -18,6 +19,7 @@ Create a **<dialog\>** component in the **.hml** file under **pages/index**
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.doc-page { .doc-page {
...@@ -49,6 +51,7 @@ button{ ...@@ -49,6 +51,7 @@ button{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
export default { export default {
...@@ -59,11 +62,12 @@ export default { ...@@ -59,11 +62,12 @@ export default {
} }
``` ```
![](figures/5-5.gif) ![en-us_image_0000001267767893](figures/en-us_image_0000001267767893.gif)
## Setting Dialog Box Response<a name="section15709114251818"></a>
Add a **cancel** event that is triggered when a user touches a non-dialog area to cancel the pop-up dialog box. Add the **show** and **close** methods to display and close the dialog box, respectively. ## Setting Dialog Box Response
Add a cancel event that is triggered when a user touches a non-dialog area to cancel the pop-up dialog box. Add the show and close methods to display and close the dialog box, respectively.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -125,16 +129,22 @@ export default { ...@@ -125,16 +129,22 @@ export default {
} }
``` ```
![](figures/38.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001223287720](figures/en-us_image_0000001223287720.gif)
>- This component supports only one child component.
>- Attributes and styles of a **<dialog\>** component cannot be dynamically updated.
>- The **<dialog\>** component does not support the **focusable** and **click-effect** attributes. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - This component supports only one child component.
>
> - Attributes and styles of a &lt;dialog&gt; component cannot be dynamically updated.
>
> - The &lt;dialog&gt; component does not support the focusable and click-effect attributes.
## Example Scenario
## Example Scenario<a name="section54252520379"></a>
Use the **<dialog\>** component to implement a schedule. When the dialog box is open, use the [**<textarea\>**](../reference/arkui-js/js-components-basic-textarea.md) component to add an event and touch the OK button to obtain the current time and save the input text. The events in the calendar are displayed in a list. Use the &lt;dialog&gt; component to implement a schedule. When the dialog box is open, use the [&lt;textarea&gt;](../reference/arkui-js/js-components-basic-textarea.md) component to add an event and touch the OK button to obtain the current time and save the input text. The events in the calendar are displayed in a list.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -292,5 +302,5 @@ export default { ...@@ -292,5 +302,5 @@ export default {
} }
``` ```
![](figures/6.gif)
![en-us_image_0000001223127756](figures/en-us_image_0000001223127756.gif)
# Form<a name="EN-US_TOPIC_0000001201655789"></a> # &lt;form&gt; Development
The **<form\>** component allows the content in [**<input\>**](../reference/arkui-js/js-components-basic-input.md) components to be submitted and reset. For details, see [form](../reference/arkui-js/js-components-container-form.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:** The &lt;form&gt; component allows the content in [&lt;input&gt;](../reference/arkui-js/js-components-basic-input.md)components to be submitted and reset. For details, see [form](../reference/arkui-js/js-components-container-form.md).
>This component is supported since API version 6.
## Creating a <form\> Component<a name="section1688401116367"></a>
Create a **<form\>** component in the **.hml** file under **pages/index**. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> This component is supported since API version 6.
## Creating a &lt;form&gt; Component
Create a &lt;form&gt; component in the .hml file under pages/index.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
<form> <form> <input type="text" style="width:80%"></input>
<input type="text" style="width:80%"></input>
</form> </form>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -28,11 +31,12 @@ Create a **<form\>** component in the **.hml** file under **pages/index**. ...@@ -28,11 +31,12 @@ Create a **<form\>** component in the **.hml** file under **pages/index**.
} }
``` ```
![](figures/11.png) ![en-us_image_0000001267887873](figures/en-us_image_0000001267887873.png)
## Zooming In or Out on a Form<a name="section462755916266"></a>
To implement the zoom effect after a form is clicked, add the **click-effect** attribute to the **<form\>** component. For values of **click-effect**, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md). ## Zooming In or Out on a Form
To implement the zoom effect after a form is clicked, add the click-effect attribute to the &lt;form&gt; component. For values of click-effect, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md).
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -43,9 +47,11 @@ To implement the zoom effect after a form is clicked, add the **click-effect** ...@@ -43,9 +47,11 @@ To implement the zoom effect after a form is clicked, add the **click-effect**
</div> </div>
``` ```
## Setting the Form Style<a name="section17276142315293"></a>
Add the **background-color** and **border** attributes. ## Setting the Form Style
Add the background-color and border attributes.
``` ```
/* xxx.css */ /* xxx.css */
...@@ -62,11 +68,13 @@ Add the **background-color** and **border** attributes. ...@@ -62,11 +68,13 @@ Add the **background-color** and **border** attributes.
} }
``` ```
![](figures/7.gif)
## Adding Response Events<a name="section1587614482301"></a> ![en-us_image_0000001267607913](figures/en-us_image_0000001267607913.gif)
To submit or reset a form, add the **submit** and **reset** events. ## Adding Response Events
To submit or reset a form, add the submit and reset events.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -88,6 +96,7 @@ To submit or reset a form, add the **submit** and **reset** events. ...@@ -88,6 +96,7 @@ To submit or reset a form, add the **submit** and **reset** events.
</div> </div>
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -105,13 +114,16 @@ export default{ ...@@ -105,13 +114,16 @@ export default{
} }
``` ```
![](figures/8-6.gif)
## Example Scenario<a name="section54252520379"></a> ![en-us_image_0000001267767885](figures/en-us_image_0000001267767885.gif)
## Example Scenario
Select an option and submit or reset the form data. Select an option and submit or reset the form data.
Create [**<input\>**](../reference/arkui-js/js-components-basic-input.md) components, set their **type** attribute to **checkbox** and **radio**, and use the **onsubmit** and **onreset** events of the **<form\>** component to submit and reset the form data. Create [&lt;input&gt;](../reference/arkui-js/js-components-basic-input.md) (en-us_topic_0000001173324647.xml) components, set their type attribute to checkbox and radio, and use the onsubmit and onreset events of the &lt;form&gt; component to submit and reset the form data.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -148,6 +160,7 @@ Create [**<input\>**](../reference/arkui-js/js-components-basic-input.md) comp ...@@ -148,6 +160,7 @@ Create [**<input\>**](../reference/arkui-js/js-components-basic-input.md) comp
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -165,6 +178,7 @@ label{ ...@@ -165,6 +178,7 @@ label{
} }
``` ```
``` ```
/* xxx.js */ /* xxx.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -182,5 +196,4 @@ export default { ...@@ -182,5 +196,4 @@ export default {
} }
``` ```
![](figures/9.gif) ![en-us_image_0000001222967788](figures/en-us_image_0000001222967788.gif)
# Image<a name="EN-US_TOPIC_0000001202854311"></a> # &lt;image&gt; Development
The **<image\>** component is used to render and display images. For details, see [image](../reference/arkui-js/js-components-basic-image.md).
## Creating an <image\> Component<a name="section1688401116367"></a> The &lt;image&gt; component is used to render and display images. For details, see [image](../reference/arkui-js/js-components-basic-image.md).
Create an **<image\>** component in the **.hml** file under **pages/index**.
## Creating an &lt;image&gt; Component
Create an &lt;image&gt; component in the .hml file under pages/index.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -13,6 +15,7 @@ Create an **<image\>** component in the **.hml** file under **pages/index** ...@@ -13,6 +15,7 @@ Create an **<image\>** component in the **.hml** file under **pages/index**
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -23,11 +26,12 @@ Create an **<image\>** component in the **.hml** file under **pages/index** ...@@ -23,11 +26,12 @@ Create an **<image\>** component in the **.hml** file under **pages/index**
} }
``` ```
![](figures/10-10.png) ![en-us_image_0000001223127736](figures/en-us_image_0000001223127736.png)
## Setting the Image Style<a name="section17276142315293"></a>
Set the **width**, **height**, and **object-fit** attributes to define the width, height, and scale type of an image. ## Setting the Image Style
Set the width, height, and object-fit attributes to define the width, height, and scale type of an image.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -42,11 +46,10 @@ Set the **width**, **height**, and **object-fit** attributes to define the w ...@@ -42,11 +46,10 @@ Set the **width**, **height**, and **object-fit** attributes to define the w
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color:#F1F3F5; background-color:#F1F3F5;
} }
image{ image{
width: 80%; width: 80%; height: 500px;
height: 500px;
border: 5px solid saddlebrown; border: 5px solid saddlebrown;
border-radius: 20px; border-radius: 20px;
object-fit: contain; object-fit: contain;
...@@ -55,11 +58,13 @@ image{ ...@@ -55,11 +58,13 @@ image{
} }
``` ```
![](figures/7-11.png)
## Display Multiple Images<a name="section297282517378"></a> ![en-us_image_0000001222807796](figures/en-us_image_0000001222807796.png)
Define a **for** loop to display multiple images cyclically. Set **option** to specify the image scale style. For details about the scale styles, see the description of object-fit.
## Display Multiple Images
Define a for loop to display multiple images cyclically. Set option to specify the image scale style. For details about the scale styles, see the description of object-fit.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -81,6 +86,7 @@ Define a **for** loop to display multiple images cyclically. Set **option** ...@@ -81,6 +86,7 @@ Define a **for** loop to display multiple images cyclically. Set **option**
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.page-container { .page-container {
...@@ -114,6 +120,7 @@ Define a **for** loop to display multiple images cyclically. Set **option** ...@@ -114,6 +120,7 @@ Define a **for** loop to display multiple images cyclically. Set **option**
} }
``` ```
``` ```
/* index.js */ /* index.js */
export default { export default {
...@@ -129,11 +136,14 @@ export default { ...@@ -129,11 +136,14 @@ export default {
} }
``` ```
![](figures/34-12.gif)
## Loading Images<a name="section06913511375"></a> ![en-us_image_0000001267767873](figures/en-us_image_0000001267767873.gif)
## Loading Images
When an image is successfully loaded, the complete event is triggered, and the loaded image is returned. If an exception occurs during image loading, the error event is triggered, and the image loading failure is printed.
When an image is successfully loaded, the **complete** event is triggered, and the loaded image is returned. If an exception occurs during image loading, the **error** event is triggered, and the image loading failure is printed.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -147,6 +157,7 @@ When an image is successfully loaded, the **complete** event is triggered, and ...@@ -147,6 +157,7 @@ When an image is successfully loaded, the **complete** event is triggered, and
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container{ .container{
...@@ -163,6 +174,7 @@ When an image is successfully loaded, the **complete** event is triggered, and ...@@ -163,6 +174,7 @@ When an image is successfully loaded, the **complete** event is triggered, and
} }
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -184,11 +196,12 @@ export default { ...@@ -184,11 +196,12 @@ export default {
} }
``` ```
![](figures/111.gif) ![en-us_image_0000001267887865](figures/en-us_image_0000001267887865.gif)
## Example Scenario<a name="section54252520379"></a>
In this example you touch and hold an image to gradually hide it. After the image is completely hidden, it will show in its original setting. Set a **setInterval** timer to change the image opacity at a specified interval so that it is hidden gradually. When the opacity changes to **0**, the timer is cleared and the opacity is set to **1**. ## Example Scenario
In this example you touch and hold an image to gradually hide it. After the image is completely hidden, it will show in its original setting. Set a setInterval timer to change the image opacity at a specified interval so that it is hidden gradually. When the opacity changes to 0, the timer is cleared and the opacity is set to 1.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -204,6 +217,7 @@ In this example you touch and hold an image to gradually hide it. After the imag ...@@ -204,6 +217,7 @@ In this example you touch and hold an image to gradually hide it. After the imag
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.page-container { .page-container {
...@@ -211,6 +225,7 @@ In this example you touch and hold an image to gradually hide it. After the imag ...@@ -211,6 +225,7 @@ In this example you touch and hold an image to gradually hide it. After the imag
align-self: center; align-self: center;
justify-content: center; justify-content: center;
background-color:#F1F3F5; background-color:#F1F3F5;
background-color: #F1F3F5;
} }
.content{ .content{
flex-direction:column; flex-direction:column;
...@@ -229,13 +244,10 @@ In this example you touch and hold an image to gradually hide it. After the imag ...@@ -229,13 +244,10 @@ In this example you touch and hold an image to gradually hide it. After the imag
justify-content: space-between; justify-content: space-between;
} }
.testimage { .testimage {
width: 100%; width: 100%; height: 400px; object-fit: scale-down; border-radius: 20px;}
height: 400px;
object-fit: scale-down;
border-radius: 20px;
}
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -263,5 +275,4 @@ export default { ...@@ -263,5 +275,4 @@ export default {
} }
``` ```
![](figures/17.gif) ![en-us_image_0000001267607905](figures/en-us_image_0000001267607905.gif)
# Input<a name="EN-US_TOPIC_0000001202854309"></a> # <input> Development
The **<input\>** component provides an interactive way to receive user input of various types, including **date**, **checkbox**, and **button**. For details, see [input](../reference/arkui-js/js-components-basic-input.md).
## Creating an <input\> Component<a name="section119721242413"></a> The <input> component provides an interactive way to receive user input of various types, including date, checkbox, and button. For details, see [input](../reference/arkui-js/js-components-basic-input.md).
## Creating an <input> Component
Create an <input> component in the .hml file under pages/index.
Create an **<input\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container"> <div class="container">
<input type="text"> <input type="text"> Please enter the content </input>
Please enter the content
</input>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -25,11 +27,13 @@ Create an **<input\>** component in the **.hml** file under **pages/index** ...@@ -25,11 +27,13 @@ Create an **<input\>** component in the **.hml** file under **pages/index**
} }
``` ```
![](figures/2.png) ![en-us_image_0000001222807768](figures/en-us_image_0000001222807768.png)
## Setting the Input Type<a name="section34344913465"></a> ## Setting the Input Type
Set the type attribute of the <input> component to button, date, or any of the supported values.
Set the **type** attribute of the **<input\>** component to **button**, **date**, or any of the supported values.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -51,6 +55,7 @@ Set the **type** attribute of the **<input\>** component to **button**, ** ...@@ -51,6 +55,7 @@ Set the **type** attribute of the **<input\>** component to **button**, **
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -83,6 +88,7 @@ Set the **type** attribute of the **<input\>** component to **button**, ** ...@@ -83,6 +88,7 @@ Set the **type** attribute of the **<input\>** component to **button**, **
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -92,15 +98,19 @@ export default { ...@@ -92,15 +98,19 @@ export default {
} }
``` ```
![](figures/18.gif)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001223287672](figures/en-us_image_0000001223287672.gif)
>- For wearables, the input type can only be **button**, **radio**, or **checkbox**.
>- The settings of **checked** take effect only when the input type is set to **checkbox** or **radio**. The default value of **checked** is **false**.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - For wearables, the input type can only be button, radio, or checkbox.
>
> - The settings of checked take effect only when the input type is set to checkbox or radio. The default value of checked is false.
## Event Binding<a name="section44031114173719"></a>
Add the **search** and **translate** events to the **<input\>** component. ## Event Binding
Add the search and translate events to the <input> component.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -113,6 +123,7 @@ Add the **search** and **translate** events to the **<input\>** component. ...@@ -113,6 +123,7 @@ Add the **search** and **translate** events to the **<input\>** component.
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.content { .content {
...@@ -134,6 +145,7 @@ text{ ...@@ -134,6 +145,7 @@ text{
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt' import prompt from '@system.prompt'
...@@ -153,11 +165,13 @@ export default { ...@@ -153,11 +165,13 @@ export default {
} }
``` ```
![](figures/36.gif) ![en-us_image_0000001267647853](figures/en-us_image_0000001267647853.gif)
## Setting the Input Error Message<a name="section4314164631810"></a>
Add the **showError** method to the **<input\>** component to display an error message in the event of incorrect input. ## Setting the Input Error Message
Add the showError method to the <input> component to display an error message in the event of incorrect input.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -168,6 +182,7 @@ Add the **showError** method to the **<input\>** component to display an err ...@@ -168,6 +182,7 @@ Add the **showError** method to the **<input\>** component to display an err
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.content { .content {
...@@ -187,6 +202,7 @@ Add the **showError** method to the **<input\>** component to display an err ...@@ -187,6 +202,7 @@ Add the **showError** method to the **<input\>** component to display an err
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt' import prompt from '@system.prompt'
...@@ -203,13 +219,9 @@ import prompt from '@system.prompt' ...@@ -203,13 +219,9 @@ import prompt from '@system.prompt'
}, },
buttonClick(e){ buttonClick(e){
if(this.value.length > 6){ if(this.value.length > 6){
this.$element("input").showError({ this.$element("input").showError({ error: 'Up to 6 characters are allowed.' });
error: 'Up to 6 characters are allowed.'
});
}else if(this.value.length == 0){ }else if(this.value.length == 0){
this.$element("input").showError({ this.$element("input").showError({ error:this.value + 'This field cannot be left empty.' });
error:this.value + 'This field cannot be left empty.'
});
}else{ }else{
prompt.showToast({ prompt.showToast({
message: "success " message: "success "
...@@ -219,15 +231,18 @@ import prompt from '@system.prompt' ...@@ -219,15 +231,18 @@ import prompt from '@system.prompt'
} }
``` ```
![](figures/19.gif) ![en-us_image_0000001223127708](figures/en-us_image_0000001223127708.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - This method is available when the input type is set to text, email, date, time, number, or password.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>
>- This method is available when the input type is set to **text**, **email**, **date**, **time**, **number**, or **password**.
## Example Scenario<a name="section85617733119"></a> ## Example Scenario
Enter information by using the <input> component of the type that suits your needs.
Enter information by using the **<input\>** component of the type that suits your needs.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -257,6 +272,8 @@ Enter information by using the **<input\>** component of the type that suits y ...@@ -257,6 +272,8 @@ Enter information by using the **<input\>** component of the type that suits y
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -285,6 +302,8 @@ label { ...@@ -285,6 +302,8 @@ label {
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -301,5 +320,5 @@ export default { ...@@ -301,5 +320,5 @@ export default {
} }
``` ```
![](figures/4.gif)
![en-us_image_0000001222807760](figures/en-us_image_0000001222807760.gif)
# List<a name="EN-US_TOPIC_0000001156015762"></a> # &lt;list&gt; Development
The **<list\>** component provides a list container that presents a series of list items arranged in a column with the same width. Lists can be used for presenting the same type of data in a multiple and coherent row style. For details, see [list](../reference/arkui-js/js-components-container-list.md).
## Creating a <list\> Component<a name="section1994073214247"></a> The &lt;list&gt; component provides a list container that presents a series of list items arranged in a column with the same width. Lists can be used for presenting the same type of data in a multiple and coherent row style. For details, see [list](../reference/arkui-js/js-components-container-list.md).
## Creating a &lt;list&gt; Component
Create a &lt;list&gt; component in the .hml file under pages/index.
Create a **<list\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- index.hml --> <!-- index.hml -->
<div class="container"> <div class="container">
<list> <list> <list-item class="listItem"></list-item>
<list-item class="listItem"></list-item>
<list-item class="listItem"></list-item> <list-item class="listItem"></list-item>
<list-item class="listItem"></list-item> <list-item class="listItem"></list-item>
<list-item class="listItem"></list-item> <list-item class="listItem"></list-item>
...@@ -18,6 +20,7 @@ Create a **<list\>** component in the **.hml** file under **pages/index**. ...@@ -18,6 +20,7 @@ Create a **<list\>** component in the **.hml** file under **pages/index**.
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -32,15 +35,18 @@ Create a **<list\>** component in the **.hml** file under **pages/index**. ...@@ -32,15 +35,18 @@ Create a **<list\>** component in the **.hml** file under **pages/index**.
} }
``` ```
![](figures/5.png) ![en-us_image_0000001223287680](figures/en-us_image_0000001223287680.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - &lt;list-item-group&gt; is a child component of the &lt;list&gt; component and is used to group items in a list. It can have a &lt;list-item&gt; nested inside, but not &lt;list&gt;.
>
> - &lt;list-item&gt; is a child component of the &lt;list&gt; component and is used to display items in a list.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Adding a Scrollbar
>- **<list-item-group\>** is a child component of the **<list\>** component and is used to group items in a list. It can have a **<list-item\>** nested inside, but not **<list\>**.
>- **<list-item\>** is a child component of the **<list\>** component and is used to display items in a list.
## Adding a Scrollbar<a name="section178831773548"></a> To display a scrollbar on the right side of the screen, set scrollbar to on. The side scrollbar can be used to scroll a long list or the screen up or down.
To display a scrollbar on the right side of the screen, set **scrollbar** to **on**. The side scrollbar can be used to scroll a long list or the screen up or down.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -56,6 +62,7 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to ...@@ -56,6 +62,7 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -74,11 +81,13 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to ...@@ -74,11 +81,13 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to
} }
``` ```
![](figures/24.gif) ![en-us_image_0000001223287684](figures/en-us_image_0000001223287684.gif)
## Adding a Side Index Bar<a name="section592683718436"></a>
Set a custom **indexer** component to add an index bar at the right boundary of a list. By default, an alphabetical indexer is used. ## Adding a Side Index Bar
Set a custom indexer component to add an index bar at the right boundary of a list. By default, an alphabetical indexer is used.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -89,9 +98,10 @@ Set a custom **indexer** component to add an index bar at the right boundary o ...@@ -89,9 +98,10 @@ Set a custom **indexer** component to add an index bar at the right boundary o
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container{
flex-direction: column; flex-direction: column;
background-color: #F1F3F5; background-color: #F1F3F5;
} }
...@@ -102,15 +112,18 @@ Set a custom **indexer** component to add an index bar at the right boundary o ...@@ -102,15 +112,18 @@ Set a custom **indexer** component to add an index bar at the right boundary o
} }
``` ```
![](figures/00.png) ![en-us_image_0000001223127716](figures/en-us_image_0000001223127716.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - This indexer attribute is valid only when flex-direction is set to column and columns is set to 1.
>
> - You must include "\#" when using a customized indexer.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Collapsing or Expanding a List
>- This **indexer** attribute is valid only when **flex-direction** is set to **column** and **columns** is set to **1**.
>- You must include **"\#"** when using a customized indexer.
## Collapsing or Expanding a List<a name="section940022183115"></a> To allow a &lt;list&gt; component to collapse and expand, add groupcollapse and groupexpand events.
To allow a **<list\>** component to collapse and expand, add **groupcollapse** and **groupexpand** events.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -132,6 +145,7 @@ To allow a **<list\>** component to collapse and expand, add **groupcollapse* ...@@ -132,6 +145,7 @@ To allow a **<list\>** component to collapse and expand, add **groupcollapse*
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.doc-page { .doc-page {
...@@ -152,6 +166,7 @@ margin-top:30px; ...@@ -152,6 +166,7 @@ margin-top:30px;
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -183,21 +198,18 @@ export default { ...@@ -183,21 +198,18 @@ export default {
} }
``` ```
![](figures/8-4.gif) ![en-us_image_0000001267887845](figures/en-us_image_0000001267887845.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - The groupcollapse and groupexpand events can be used only by the list-item-group component.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>
>- The **groupcollapse** and **groupexpand** events can be used only by the **list-item-group** component.
## Example Scenario<a name="section1945019230211"></a> ## Example Scenario
Search for contacts by using an alphabetical indexer. Search for contacts by using an alphabetical indexer.
``` ```
<!-- index.hml --> <!-- index.hml -->
```
```
<div class="doc-page"> <div class="doc-page">
<text style="font-size: 35px; font-weight: 500; text-align: center; margin-top: 20px; margin-bottom: 20px;"> <text style="font-size: 35px; font-weight: 500; text-align: center; margin-top: 20px; margin-bottom: 20px;">
<span>Contacts</span> <span>Contacts</span>
...@@ -294,5 +306,5 @@ export default { ...@@ -294,5 +306,5 @@ export default {
} }
``` ```
![](figures/27.gif)
![en-us_image_0000001267767861](figures/en-us_image_0000001267767861.gif)
# Picker<a name="EN-US_TOPIC_0000001155695748"></a> # &lt;picker&gt; Development
The **<picker\>** component supports common, date, time, data and time, and multi-column text selectors. For details, see [picker](../reference/arkui-js/js-components-basic-picker.md).
## Creating a <picker\> Component<a name="section19696122895318"></a> The &lt;picker&gt; component supports common, date, time, data and time, and multi-column text selectors. For details, see [picker](../reference/arkui-js/js-components-basic-picker.md).
## Creating a &lt;picker&gt; Component
Create a &lt;picker&gt; component in the .hml file under pages/index.
Create a **<picker\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- index.hml --> <!-- index.hml -->
<div class="container"> <div class="container">
<picker> <picker> picker </picker>
picker
</picker>
<div> <div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -25,11 +27,13 @@ Create a **<picker\>** component in the **.hml** file under **pages/index** ...@@ -25,11 +27,13 @@ Create a **<picker\>** component in the **.hml** file under **pages/index**
} }
``` ```
![](figures/20211008-184455(welinkpc).gif) ![en-us_image_0000001223287716](figures/en-us_image_0000001223287716.gif)
## Setting the Picker Type<a name="section78391556183"></a> ## Setting the Picker Type
Set the type attribute of the &lt;picker&gt; component. For example, set it to date.
Set the **type** attribute of the **<picker\>** component. For example, set it to **date**.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -39,6 +43,7 @@ Set the **type** attribute of the **<picker\>** component. For example, set ...@@ -39,6 +43,7 @@ Set the **type** attribute of the **<picker\>** component. For example, set
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -52,6 +57,7 @@ Set the **type** attribute of the **<picker\>** component. For example, set ...@@ -52,6 +57,7 @@ Set the **type** attribute of the **<picker\>** component. For example, set
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -63,15 +69,18 @@ export default { ...@@ -63,15 +69,18 @@ export default {
} }
``` ```
![](figures/20211217-130837(welinkpc).gif) ![en-us_image_0000001267647893](figures/en-us_image_0000001267647893.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - When setting the value range of a common selector, you must use the data binding mode.
>
> - The lunarswitch attribute of the date selector is only supported on phones and tablets.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- When setting the value range of a common selector, you must use the data binding mode.
>- The **lunarswitch** attribute of the date selector is only supported on phones and tablets.
## Setting the Time Format<a name="section1971415321217"></a> ## Setting the Time Format
Set the hours attribute to specify the time format used by the time selector. Available values include 12 and 24, indicating the 12-hour format and 24-hour format, respectively.
Set the **hours** attribute to specify the time format used by the time selector. Available values include **12** and **24**, indicating the 12-hour format and 24-hour format, respectively.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -81,6 +90,7 @@ Set the **hours** attribute to specify the time format used by the time select ...@@ -81,6 +90,7 @@ Set the **hours** attribute to specify the time format used by the time select
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -96,15 +106,18 @@ Set the **hours** attribute to specify the time format used by the time select ...@@ -96,15 +106,18 @@ Set the **hours** attribute to specify the time format used by the time select
} }
``` ```
![](figures/25.gif) ![en-us_image_0000001222807808](figures/en-us_image_0000001222807808.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - When hours is set to 12, the time is displayed in 12-hour format and distinguished by a.m. and p.m.
>
> - When hours is set to 24, the time is displayed in 24-hour format.
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Adding Response Events
>- When **hours** is set to **12**, the time is displayed in 12-hour format and distinguished by a.m. and p.m.
>- When **hours** is set to **24**, the time is displayed in 24-hour format.
## Adding Response Events<a name="section20659132323820"></a> To confirm and cancel selection, add change and cancel events.
To confirm and cancel selection, add **change** and **cancel** events.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -114,6 +127,7 @@ To confirm and cancel selection, add **change** and **cancel** events. ...@@ -114,6 +127,7 @@ To confirm and cancel selection, add **change** and **cancel** events.
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -131,6 +145,7 @@ To confirm and cancel selection, add **change** and **cancel** events. ...@@ -131,6 +145,7 @@ To confirm and cancel selection, add **change** and **cancel** events.
} }
``` ```
``` ```
// xxx.js // xxx.js
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -150,11 +165,13 @@ export default { ...@@ -150,11 +165,13 @@ export default {
} }
``` ```
![](figures/26.gif) ![en-us_image_0000001223127748](figures/en-us_image_0000001223127748.gif)
## Example Scenario
## Example Scenario<a name="section36086283455"></a>
Implement a health check-in application by using the **<picker\>** component. Implement a health check-in application by using the &lt;picker&gt; component.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -277,5 +294,5 @@ export default { ...@@ -277,5 +294,5 @@ export default {
} }
``` ```
![](figures/qqqq.gif)
![en-us_image_0000001267887877](figures/en-us_image_0000001267887877.gif)
# Stepper<a name="EN-US_TOPIC_0000001156894290"></a> # &lt;stepper&gt; Development
When multiple steps are required to complete a task, you can use the **<stepper\>** component to navigate your users through the whole process. For details, see [stepper](../reference/arkui-js/js-components-container-stepper.md).
>![](../public_sys-resources/icon-note.gif) **NOTE:** When multiple steps are required to complete a task, you can use the &lt;stepper&gt; component to navigate your users through the whole process. For details, see [stepper](../reference/arkui-js/js-components-container-stepper.md).
>This component is supported since API version 5.
## Creating a <stepper\> Component<a name="section1820920264"></a>
Create a **<stepper\>** component in the **.hml** file under **pages/index**. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> This component is supported since API version 5.
## Creating a &lt;stepper&gt; Component
Create a &lt;stepper&gt; component in the .hml file under pages/index.
``` ```
<!-- index.hml --> <!-- index.hml -->
<div class="container"> <div class="container">
<stepper> <stepper> <stepper-item>
<stepper-item>
<text>Step 1</text> <text>Step 1</text>
</stepper-item> </stepper-item>
<stepper-item> <stepper-item>
...@@ -23,6 +26,7 @@ Create a **<stepper\>** component in the **.hml** file under **pages/index* ...@@ -23,6 +26,7 @@ Create a **<stepper\>** component in the **.hml** file under **pages/index*
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -38,11 +42,13 @@ text{ ...@@ -38,11 +42,13 @@ text{
} }
``` ```
![](figures/2-7.gif) ![en-us_image_0000001223287656](figures/en-us_image_0000001223287656.gif)
## Setting the Index<a name="section1696313408199"></a> ## Setting the Index
Set index to the index value of the step that you want to display by default.
Set **index** to the index value of the step that you want to display by default.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -61,6 +67,7 @@ Set **index** to the index value of the step that you want to display by defau ...@@ -61,6 +67,7 @@ Set **index** to the index value of the step that you want to display by defau
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -74,9 +81,10 @@ text{ ...@@ -74,9 +81,10 @@ text{
} }
``` ```
![](figures/10.gif) ![en-us_image_0000001267767837](figures/en-us_image_0000001267767837.gif)
Set the label attribute to customize the button text for the &lt;stepper-item&gt;.
Set the **label** attribute to customize the button text for the **<stepper-item\>**.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -98,6 +106,7 @@ Set the **label** attribute to customize the button text for the **<stepper-i ...@@ -98,6 +106,7 @@ Set the **label** attribute to customize the button text for the **<stepper-i
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -111,14 +120,12 @@ text{ ...@@ -111,14 +120,12 @@ text{
} }
``` ```
``` ```
/* index.js */ /* index.js */
export default { export default {
data: { data: {
label_1:{ label_1:{ nextLabel: 'NEXT', status: 'normal' },
nextLabel: 'NEXT',
status: 'normal'
},
label_2:{ label_2:{
prevLabel: 'BACK', prevLabel: 'BACK',
nextLabel: 'NEXT', nextLabel: 'NEXT',
...@@ -133,11 +140,12 @@ export default { ...@@ -133,11 +140,12 @@ export default {
} }
``` ```
![](figures/11-8.gif) ![en-us_image_0000001267767841](figures/en-us_image_0000001267767841.gif)
## Setting the Style<a name="section482815298502"></a>
By default, the **<stepper\>** component fills entire space of its container. The sample code below shows how to set the border and background color using the **border** and **background-color** attributes. ## Setting the Style
By default, the &lt;stepper&gt; component fills entire space of its container. The sample code below shows how to set the border and background color using the border and background-color attributes.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -152,6 +160,7 @@ By default, the **<stepper\>** component fills entire space of its container. ...@@ -152,6 +160,7 @@ By default, the **<stepper\>** component fills entire space of its container.
</div> </div>
``` ```
``` ```
/* index.css */ /* index.css */
.container { .container {
...@@ -165,8 +174,7 @@ By default, the **<stepper\>** component fills entire space of its container. ...@@ -165,8 +174,7 @@ By default, the **<stepper\>** component fills entire space of its container.
height: 300px; height: 300px;
} }
.stepperClass{ .stepperClass{
border:1px solid silver ; border:1px solid silver ; background-color: white;
background-color: white;
} }
text{ text{
width: 100%; width: 100%;
...@@ -175,14 +183,16 @@ text{ ...@@ -175,14 +183,16 @@ text{
} }
``` ```
![](figures/02.png) ![en-us_image_0000001223287668](figures/en-us_image_0000001223287668.png)
## Adding Events<a name="section331041121215"></a>
The **<stepper\>** component supports the **finish**, **change**, **next**, **back**, and **skip** events. ## Adding Events
- When the **change** and **next** or **back** events exist at the same time, the **next** or **back** event is executed before the **change** event. The &lt;stepper&gt; component supports the finish, change, next, back, and skip events.
- Before resetting the **index** attribute, you must remove the current value. Otherwise, the value change cannot be detected.
- When the change and next or back events exist at the same time, the next or back event is executed before the change event.
- Before resetting the index attribute, you must remove the current value. Otherwise, the value change cannot be detected.
``` ```
<!-- index.hml --> <!-- index.hml -->
...@@ -205,6 +215,7 @@ The **<stepper\>** component supports the **finish**, **change**, **next**, ...@@ -205,6 +215,7 @@ The **<stepper\>** component supports the **finish**, **change**, **next**,
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.doc-page { .doc-page {
...@@ -231,6 +242,7 @@ button{ ...@@ -231,6 +242,7 @@ button{
} }
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -272,13 +284,15 @@ export default { ...@@ -272,13 +284,15 @@ export default {
} }
``` ```
![](figures/37.gif) ![en-us_image_0000001267607869](figures/en-us_image_0000001267607869.gif)
## Example Scenario<a name="section1117302718531"></a> ## Example Scenario
Select the options displayed on the page. Your selection will be shown in real time. Click the next button to dynamically change the font color and font size on the page. Select the options displayed on the page. Your selection will be shown in real time. Click the next button to dynamically change the font color and font size on the page.
Use the **<stepper\>** component to navigate through the steps. Create a [**<toggle\>**](../reference/arkui-js/js-components-basic-toggle.md) component to implement the functions of selection and displaying the selection result. Then use the [**<select\>**](../reference/arkui-js/js-components-basic-select.md) component to dynamically change the font color or size of the selected options. Use the &lt;stepper&gt; component to navigate through the steps. Create a [&lt;toggle&gt;](../reference/arkui-js/js-components-basic-toggle.md) component to implement the functions of selection and displaying the selection result. Then use the [&lt;select&gt;](../reference/arkui-js/js-components-basic-select.md) component to dynamically change the font color or size of the selected options.
``` ```
<div class="container"> <div class="container">
...@@ -321,6 +335,7 @@ Use the **<stepper\>** component to navigate through the steps. Create a [**< ...@@ -321,6 +335,7 @@ Use the **<stepper\>** component to navigate through the steps. Create a [**<
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -340,6 +355,7 @@ Use the **<stepper\>** component to navigate through the steps. Create a [**< ...@@ -340,6 +355,7 @@ Use the **<stepper\>** component to navigate through the steps. Create a [**<
} }
``` ```
``` ```
/* index.js */ /* index.js */
import prompt from '@system.prompt'; import prompt from '@system.prompt';
...@@ -382,5 +398,4 @@ export default { ...@@ -382,5 +398,4 @@ export default {
} }
``` ```
![](figures/28.gif) ![en-us_image_0000001267887817](figures/en-us_image_0000001267887817.gif)
# Text<a name="EN-US_TOPIC_0000001157214238"></a> # &lt;text&gt; Development
The **<text\>** component is used to display a piece of textual information. For details, see [text](../reference/arkui-js/js-components-basic-text.md).
## Creating a <text\> Component<a name="section1466515586539"></a> The &lt;text&gt; component is used to display a piece of textual information. For details, see [text](../reference/arkui-js/js-components-basic-text.md).
## Creating a &lt;text&gt; Component
Create a &lt;text&gt; component in the .hml file under pages/index.
Create a **<text\>** component in the **.hml** file under **pages/index**.
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
<div class="container" style="text-align: center;justify-content: center; align-items: center;"> <div class="container" style="text-align: center;justify-content: center; align-items: center;">
<text> <text>Hello World</text>
Hello World
</text>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
width: 100%;
height: 100%;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
...@@ -25,96 +29,128 @@ Create a **<text\>** component in the **.hml** file under **pages/index**. ...@@ -25,96 +29,128 @@ Create a **<text\>** component in the **.hml** file under **pages/index**.
} }
``` ```
![](figures/01.png) ![en-us_image_0000001222807780](figures/en-us_image_0000001222807780.png)
## Setting the Text Style and Attributes<a name="section99161742155912"></a> ## Setting the Text Style and Attributes
- Adding a text style - Adding a text style
Set the **color**, **font-size**, and **allow-scale** attributes.
``` Set the color, font-size, allow-scale, word-spacing, and text-valign attributes to apply the color, size, zoom, spacing, and vertical alignment styles to the text.
<!-- xxx.hml -->
<div class="container" style="background-color:#F1F3F5;justify-content: center; align-items: center;"> ```
<!-- xxx.hml -->
<div class="container" style="background-color:#F1F3F5;flex-direction: column;justify-content: center; align-items: center;">
<text style="color: blueviolet; font-size: 40px; allow-scale:true"> <text style="color: blueviolet; font-size: 40px; allow-scale:true">
This is a passage This is a passage
</text> </text>
</div> <text style="color: blueviolet; font-size: 40px; margin-top: 20px; allow-scale:true;word-spacing: 20px;" >
``` This is a passage
</text>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
```
![](figures/01-0.png) ![en-us_image_0000001222967764](figures/en-us_image_0000001222967764.png)
- Adding a text modifier - Adding a text modifier
Set the **text-decoration** attribute to add an underline, overline, line-through, or a combination of lines to selected text. For values of **text-decoration**, see [Text Style](../reference/arkui-js/js-components-basic-text.md).
``` Set the text-decoration attribute to add a line to selected text. Set the text-decoration-color attribute to apply specific color to the added line. For values of text-decoration, see [Text Style](../reference/arkui-js/js-components-basic-text.md).
<!-- xxx.hml -->
<div class="container" style="background-color:#F1F3F5;"> ```
<!-- xxx.hml -->
<div class="container" style="background-color:#F1F3F5;">
<text style="text-decoration:underline"> <text style="text-decoration:underline">
This is a passage This is a passage
</text> </text>
<text style="text-decoration:line-through"> <text style="text-decoration:line-through;text-decoration-color: red">
This is a passage This is a passage
</text> </text>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
width: 100%;
height: 100%;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
text{ text{
font-size: 50px; font-size: 50px;
} }
``` ```
![](figures/3.png)
![en-us_image_0000001223287688](figures/en-us_image_0000001223287688.png)
- Hiding text content - Hiding text content
Set the **text-overflow** attribute to **ellipsis** so that overflowed text is displayed as an ellipsis.
``` Set the text-overflow attribute to ellipsis so that overflowed text is displayed as an ellipsis.
<!-- xxx.hml -->
<div class="container"> ```
<!-- xxx.hml -->
<div class="container">
<text class="text"> <text class="text">
This is a passage This is a passage
</text> </text>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
width: 100%;
height: 100%;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
background-color: #F1F3F5; background-color: #F1F3F5;
justify-content: center; justify-content: center;
} }
.text{ .text{
width: 200px; width: 200px;
max-lines: 1; max-lines: 1;
text-overflow:ellipsis; text-overflow:ellipsis;
} }
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - text-overflow must be used together with max-lines.
>
> - max-lines indicates the maximum number of lines in the text.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- **text-overflow** must be used together with **max-lines**.
>- **max-lines** indicates the maximum number of lines in the text.
![](figures/05.png) ![en-us_image_0000001267647865](figures/en-us_image_0000001267647865.png)
- Setting the text line breaking mode - Setting the text line breaking mode
Set the **word-break** attribute to specify how to break lines of text. For values of **word-break**, see [Text Styles](../reference/arkui-js/js-components-basic-text.md).
``` Set the word-break attribute to specify how to break lines of text. For values of word-break, see [Text Styles](../reference/arkui-js/js-components-basic-text.md).
<!-- xxx.hml -->
<div class="container"> ```
<!-- xxx.hml -->
<div class="container">
<div class="content"> <div class="content">
<text class="text1"> <text class="text1">
Welcome to the world Welcome to the world
...@@ -123,43 +159,44 @@ Set the **word-break** attribute to specify how to break lines of text. For va ...@@ -123,43 +159,44 @@ Set the **word-break** attribute to specify how to break lines of text. For va
Welcome to the world Welcome to the world
</text> </text>
</div> </div>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
background-color: #F1F3F5; background-color: #F1F3F5;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.content{ .content{
width: 50%; width: 50%;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.text1{ .text1{
height: 200px; height: 200px;
border:1px solid #1a1919; border:1px solid #1a1919;
margin-bottom: 50px; margin-bottom: 50px;
text-align: center; text-align: center;
word-break: break-word; word-break: break-word;
font-size: 40px; font-size: 40px;
} }
.text2{ .text2{
height: 200px; height: 200px;
border:1px solid #0931e8; border:1px solid #0931e8;
text-align: center; text-align: center;
word-break: break-all; word-break: break-all;
font-size: 40px; font-size: 40px;
} }
``` ```
![](figures/8.png) ![en-us_image_0000001267767865](figures/en-us_image_0000001267767865.png)
- Setting the [**<span\>**](../reference/arkui-js/js-components-basic-span.md) child component - Setting the [&lt;span&gt;](../reference/arkui-js/js-components-basic-span.md)child component
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -168,32 +205,29 @@ Set the **word-break** attribute to specify how to break lines of text. For va ...@@ -168,32 +205,29 @@ Set the **word-break** attribute to specify how to break lines of text. For va
This is a passage This is a passage
</text> </text>
<text style="font-size: 45px;"> <text style="font-size: 45px;">
<span style="color: aqua;">This </span> <span style="color: aqua;">This </span><span style="color: #F1F3F5;"> 1 </span> <span style="color: blue;"> is a </span> <span style="color: #F1F3F5;"> 1 </span> <span style="color: red;"> passage </span>
<span style="color: #F1F3F5;">
1
</span>
<span style="color: blue;"> is a </span>
<span style="color: #F1F3F5;">
1
</span>
<span style="color: red;"> passage </span>
</text> </text>
</div> </div>
``` ```
![](figures/01-1.png)
>![](../public_sys-resources/icon-note.gif) **NOTE:** ![en-us_image_0000001223127720](figures/en-us_image_0000001223127720.png)
>- When the **<span\>** child component is used to form a text paragraph, incorrect **<span\>** attribute settings \(for example, setting of **font-weight** to **1000**\) will result in abnormal display of the text paragraph.
>- When the **<span\>** child component is being used, do not include any text you want to show in the **<text\>** component, as such text will not be displayed if you do so.
## Example Scenario<a name="section7280164491412"></a>
Use the **<text\>** component to display text content through data binding. Use the **<span\>** child component to hide or display text content by setting the **show** attribute. > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> - When the &lt;span&gt; child component is used to form a text paragraph, incorrect &lt;span&gt; attribute settings (for example, setting of font-weight to 1000) will result in abnormal display of the text paragraph.
>
> - When the &lt;span&gt; child component is being used, do not include any text you want to show in the &lt;text&gt; component, as such text will not be displayed if you do so.
```
<!-- xxx.hml --> ## Example Scenario
<div class="container">
Use the &lt;text&gt; component to display text content through data binding. Use the &lt;span&gt; child component to hide or display text content by setting the show attribute.
```
<!-- xxx.hml -->
<div class="container">
<div style="align-items: center;justify-content: center;"> <div style="align-items: center;justify-content: center;">
<text class="title"> <text class="title">
{{ content }} {{ content }}
...@@ -207,8 +241,9 @@ Use the **<text\>** component to display text content through data binding. Us ...@@ -207,8 +241,9 @@ Use the **<text\>** component to display text content through data binding. Us
</span> </span>
<span style="color: #f76160">Hide clip </span> <span style="color: #f76160">Hide clip </span>
</text> </text>
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
...@@ -226,6 +261,7 @@ Use the **<text\>** component to display text content through data binding. Us ...@@ -226,6 +261,7 @@ Use the **<text\>** component to display text content through data binding. Us
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -240,5 +276,4 @@ export default { ...@@ -240,5 +276,4 @@ export default {
} }
``` ```
![](figures/1.gif) ![en-us_image_0000001267887849](figures/en-us_image_0000001267887849.gif)
# Custom Components<a name="EN-US_TOPIC_0000001063340553"></a> # Custom Components
The ArkUI that uses the JavaScript-based web-like development paradigm supports custom components for you to extend existing components. You can encapsulate custom private attributes and events into new components to reuse them multiple times in your project. This also improves code readability. The following is an example: The ArkUI that uses the JavaScript-based web-like development paradigm supports custom components for you to extend existing components. You can encapsulate custom private attributes and events into new components to reuse them multiple times in your project. This also improves code readability. The following is an example:
- **Building a custom component**
- Building a custom component
``` ```
<!-- comp.hml --> <!-- comp.hml -->
...@@ -13,6 +15,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -13,6 +15,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
</div> </div>
``` ```
``` ```
/* comp.css */ /* comp.css */
.item { .item {
...@@ -37,6 +40,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -37,6 +40,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
} }
``` ```
``` ```
// comp.js // comp.js
export default { export default {
...@@ -58,7 +62,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -58,7 +62,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
} }
``` ```
- **Introducing the custom component** - Introducing the custom component
``` ```
<!-- xxx.hml --> <!-- xxx.hml -->
...@@ -69,6 +73,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -69,6 +73,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
</div> </div>
``` ```
``` ```
/* xxx.css */ /* xxx.css */
.container { .container {
...@@ -79,6 +84,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -79,6 +84,7 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
} }
``` ```
``` ```
// xxx.js // xxx.js
export default { export default {
...@@ -93,8 +99,8 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports ...@@ -93,8 +99,8 @@ The ArkUI that uses the JavaScript-based web-like development paradigm supports
``` ```
In this example, the parent component passes the customized attribute through **title** to the child component, and the child component receives the attribute value in **props**. The child component passes **text** to the parent through the bound event, and the passed value is obtained via **e.detail**. To successfully bind the child component event to the parent component, ensure that the event name meet the requirements for event binding. For details, see [Basic Usage of Custom Components](../reference/arkui-js/js-components-custom-basic-usage.md). The following figures show how the custom component works. In this example, the parent component passes the customized attribute through title to the child component, and the child component receives the attribute value in props. The child component passes text to the parent through the bound event, and the passed value is obtained via e.detail. To successfully bind the child component event to the parent component, ensure that the event name meet the requirements for event binding. For details, see [Basic Usage of Custom Components](../reference/arkui-js/js-components-custom-basic-usage.md). The following figures show how the custom component works.
**Figure 1** Running effect<a name="fig12947164917208"></a> figure1 Running effect
![](figures/running-effect.png "running-effect")
![en-us_image_0000001222807816](figures/en-us_image_0000001222807816.png)
# Overview<a name="EN-US_TOPIC_0000001064068634"></a> # Overview
ArkUI with the JavaScript-based web-like development paradigm provides UI components \(basic, container, canvas, and more\) and standard CSS animation capabilities.
## Basic Capabilities<a name="section1393616301083"></a> The web-like development paradigm uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically updates with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications. It could be helpful if you are developing small- and medium-sized applications with simple UIs.
- **Web-like development paradigm**
ArkUI supports languages that are similar to those for web development, such as HTML and CSS. You can use them to describe the page layout and style, and use JavaScript \(conforming to the ECMAScript specification\) for page behavior. With ArkUI, you can configure the UI in an intuitive manner, eliminating the need to code for UI state switching. ## Overall Architecture
ArkUI with the JavaScript-based web-like development paradigm consists of the following layers: application layer, frontend framework layer, engine layer, and porting layer.
## Overall Structure<a name="section105231413161115"></a>
ArkUI with the JavaScript-based web-like development paradigm consists of the following layers: application layer, frontend framework layer, engine layer, and porting layer. ![en-us_image_0000001223127696](figures/en-us_image_0000001223127696.png)
![](figures/zh-cn_image_0000001077953992.png) - Application
- **Application**
Contains applications with FAs you developed. The FA application in this document refers to the application with FAs developed using JavaScript. Contains applications with FAs you developed. The FA application in this document refers to the application with FAs developed using JavaScript.
- **Framework** - Framework
Parses UI pages and provides the Model-View-ViewModel \(MVVM\), page routing, custom components and more for front end development. Parses UI pages and provides the Model-View-ViewModel (MVVM), page routing, custom components and more for front end development.
- **Engine** - Engine
Accomplishes animation parsing, Document Object Model \(DOM\) building, layout computing, rendering command building and drawing, and event management. Accomplishes animation parsing, Document Object Model (DOM) building, layout computing, rendering command building and drawing, and event management.
- **Porting Layer** - Porting Layer
Abstracts the platform layer to provide abstract interfaces to connect to the platform. For example, event interconnection, rendering pipeline interconnection, and lifecycle interconnection. Abstracts the platform layer to provide abstract interfaces to connect to the platform. For example, event interconnection, rendering pipeline interconnection, and lifecycle interconnection.
# Building a Food Category Grid Layout<a name="EN-US_TOPIC_0000001192745835"></a> # Building a Food Category Grid Layout
The diet application allows food on the home page to display in list or grid mode. You can implement switching between food categories through tabs in grid mode. The diet application allows food on the home page to display in list or grid mode. You can implement switching between food categories through tabs in grid mode.
1. Import the **Category** enumeration type to the **FoodCategoryList** page.
1. Import the Category enumeration type to the FoodCategoryList page.
``` ```
import { Category, FoodData } from '../model/FoodData' import { Category, FoodData } from '../model/FoodData'
``` ```
2. Create the **FoodCategoryList** and **FoodCategory** components. The **FoodCategoryList** component is used as the entry component of the new page, and the **initializeOnStartup** method is invoked in the entry component. 2. Create the FoodCategoryList and FoodCategory components. The FoodCategoryList component is used as the entry component of the new page, and the initializeOnStartup method is invoked in the entry component.
``` ```
@Component @Component
...@@ -37,7 +39,7 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -37,7 +39,7 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
3. Create the **showList** member variable in the **FoodCategoryList** component to control the rendering switchover between the list layout and grid layout. The conditional rendering statement **if...else...** is required. 3. Create the showList member variable in the FoodCategoryList component to control the rendering switchover between the list layout and grid layout. The conditional rendering statement if...else... is required.
``` ```
@Entry @Entry
...@@ -58,7 +60,7 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -58,7 +60,7 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
4. In the upper right corner of the page, create an icon for switching between the list and grid layouts. Set the stack alignment mode to **TopEnd**, top-bottom alignment. Create an image component, and set the click event, that is, negation of **showList**. 4. In the upper right corner of the page, create an icon for switching between the list and grid layouts. Set the stack alignment mode to TopEnd, top-bottom alignment. Create an image component, and set the click event, that is, negation of showList.
``` ```
@Entry @Entry
...@@ -86,7 +88,7 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -86,7 +88,7 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
5. Add the **@State** decorator. After you click the switch tab in the upper right corner, the page does not change. This is because the **showList** does not have state data and its change does not trigger the page refresh. You need to add the **@State** decorator to make it state data. The change of the **@State** decorator will cause re-rendering of the component where the decorator is located. 5. Add the @State decorator. After you click the switch tab in the upper right corner, the page does not change. This is because the showList does not have state data and its change does not trigger the page refresh. You need to add the @State decorator to make it state data. The change of the @State decorator will cause re-rendering of the component where the decorator is located.
``` ```
@Entry @Entry
...@@ -115,11 +117,11 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -115,11 +117,11 @@ The diet application allows food on the home page to display in list or grid mod
``` ```
When you click the switch icon, the **FoodList** component is displayed. When you click the switch icon again, the **FoodList** component is hidden. When you click the switch icon, the FoodList component is displayed. When you click the switch icon again, the FoodList component is hidden.
![](figures/video_2021-10-22_103503.gif) ![en-us_image_0000001222807800](figures/en-us_image_0000001222807800.gif)
6. Create a tab to display all food categories \(**All**\). Create the **<Tabs\>** component and its child component **TabContent** in the **FoodCategory** component, and set **tabBar** to **All**. Set the width of the **TabBars** to 280 and the layout mode to **Scrollable**. This means that the **TabBars** can be scrolled when the total length exceeds 280. The **<Tabs\>** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a **TabContent**. 6. Create a tab to display all food categories (All). Create the <Tabs> component and its child component TabContent in the FoodCategory component, and set tabBar to All. Set the width of the TabBars to 280 and the layout mode to Scrollable. This means that the TabBars can be scrolled when the total length exceeds 280. The <Tabs> component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a TabContent.
``` ```
@Component @Component
...@@ -137,9 +139,9 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -137,9 +139,9 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
![](figures/en-us_image_0000001204538065.png) ![en-us_image_0000001267647881](figures/en-us_image_0000001267647881.png)
7. Create the **FoodGrid** component to function as a child component of the **TabContent** component. 7. Create the FoodGrid component to function as a child component of the TabContent component.
``` ```
@Component @Component
...@@ -165,7 +167,7 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -165,7 +167,7 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
8. Implement a 2 x 6 grid layout \(12 food data resources in total\). Create a **Grid** component, and set **columnsTemplate** to **\('1fr 1fr'\)**, **rowsTemplate** to **\('1fr 1fr 1fr 1fr 1fr 1fr'\)**, and both **rowsGap** and **columnsGap** to **8**. Create a **Scroll** component so that it can be slid. 8. Implement a 2 x 6 grid layout (12 food data resources in total). Create a Grid component, and set columnsTemplate to ('1fr 1fr'), rowsTemplate to ('1fr 1fr 1fr 1fr 1fr 1fr'), and both rowsGap and columnsGap to 8. Create a Scroll component so that it can be slid.
``` ```
@Component @Component
...@@ -189,7 +191,7 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -189,7 +191,7 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
9. Create a **FoodGridItem** component to display the food image, name, and calories and implement the UI layout. The **FoodGridItem** component is a child component of the **GridItem** component. The height of each **FoodGridItem** is **184**, and the line spacing is **8**. The total height of the **Grid** component is calculated as follows: \(184 + 8\) x 6 – 8 = 1144. 9. Create a FoodGridItem component to display the food image, name, and calories and implement the UI layout. The FoodGridItem component is a child component of the GridItem component. The height of each FoodGridItem is 184, and the line spacing is 8. The total height of the Grid component is calculated as follows: (184 + 8) x 6 – 8 = 1144.
``` ```
@Component @Component
...@@ -245,9 +247,9 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -245,9 +247,9 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
![](figures/video_2021-10-21_105602.gif) ![en-us_image_0000001223287708](figures/en-us_image_0000001223287708.gif)
10. Create the **Category.Vegetable**, **Category.Fruit**, **Category.Nut**, **Category.SeaFood**, and **Category.Dessert** tabs. 10. Create the Category.Vegetable, Category.Fruit, Category.Nut, Category.SeaFood, and Category.Dessert tabs.
``` ```
@Component @Component
...@@ -287,9 +289,9 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -287,9 +289,9 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
11. Set the number of rows and height of grids for different food categories. Because the number of foods varies according to the category, the **''1fr 1fr 1fr 1fr 1fr 1fr '** constant cannot be used to set the number of rows to 6. 11. Set the number of rows and height of grids for different food categories. Because the number of foods varies according to the category, the ''1fr 1fr 1fr 1fr 1fr 1fr ' constant cannot be used to set the number of rows to 6.
Create member variables gridRowTemplate and HeightValue, and set the number of grid rows and height by using these member variables.
Create member variables **gridRowTemplate** and **HeightValue**, and set the number of grid rows and height by using these member variables.
``` ```
@Component @Component
...@@ -318,7 +320,8 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -318,7 +320,8 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
Invoke the **aboutToAppear** API to calculate the number of rows \(**gridRowTemplate**\) and height \(**heightValue**\). Invoke the aboutToAppear API to calculate the number of rows (gridRowTemplate) and height (heightValue).
``` ```
aboutToAppear() { aboutToAppear() {
...@@ -328,9 +331,10 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -328,9 +331,10 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
The custom component provides two lifecycle callbacks: **aboutToAppear** and **aboutToDisappear**. **aboutToAppear** is executed after the custom component is created and before the **build** method of the custom component is executed. **aboutToDisappear** is executed when the custom component is deinitialized. The custom component provides two lifecycle callbacks: aboutToAppear and aboutToDisappear. aboutToAppear is executed after the custom component is created and before the build method of the custom component is executed. aboutToDisappear is executed when the custom component is deinitialized.
![en-us_image_0000001267647885](figures/en-us_image_0000001267647885.png)
![](figures/en-us_image_0000001215113569.png)
``` ```
@Component @Component
...@@ -366,6 +370,4 @@ The diet application allows food on the home page to display in list or grid mod ...@@ -366,6 +370,4 @@ The diet application allows food on the home page to display in list or grid mod
} }
``` ```
![](figures/video_2021-10-21_105956.gif) ![en-us_image_0000001267887869](figures/en-us_image_0000001267887869.gif)
# Building a Food Category List Layout<a name="EN-US_TOPIC_0000001192705719"></a> # Building a Food Category List Layout
Use the **List** component and **ForEach** loop to build the food category list layout.
1. Create a page file named **FoodCategoryList.ets** in the **pages** directory, rename the **index.ets** file **FoodDetail.ets**, and add the renamed file to the **"pages"** tag in the **config.json** file. The first page under the tag is the home page. Use the List component and ForEach loop to build the food category list layout.
1. Create a page file named FoodCategoryList.ets in the pages directory, rename the index.ets file FoodDetail.ets, and add the renamed file to the "pages" tag in the config.json file. The first page under the tag is the home page.
``` ```
"js": [ "js": [
...@@ -14,7 +16,7 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -14,7 +16,7 @@ Use the **List** component and **ForEach** loop to build the food category l
] ]
``` ```
2. Create a **List** component named **FoodList** as the page entry point. Then, add a **ListItem** component named **FoodListItem** as its child component. The **List** component is used to display data of the same type. Its child component **<ListItem\>** is used to display specific items in the list. 2. Create a List component named FoodList as the page entry point. Then, add a ListItem component named FoodListItem as its child component. The List component is used to display data of the same type. Its child component <ListItem> is used to display specific items in the list.
``` ```
@Component @Component
...@@ -35,14 +37,14 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -35,14 +37,14 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
3. Import the **FoodData** class and **initializeOnStartup** method. 3. Import the FoodData class and initializeOnStartup method.
``` ```
import { FoodData } from '../model/FoodData' import { FoodData } from '../model/FoodData'
import { initializeOnStartup } from '../model/FoodDataModels' import { initializeOnStartup } from '../model/FoodDataModels'
``` ```
4. Configure the **FoodList** and **FoodListItem** components to pass values. Create a member variable named **foodItems** of the **FoodData\[\]** type in the **FoodList** component and invoke the **initializeOnStartup** method to assign a value to the variable. Create a member variable **foodItem** of the **FoodData** type in the **FoodListItem** component. Pass the **foodItems\[0\]** of the first element in the parent **foodItems** array as a parameter to **FoodListItem**. 4. Configure the FoodList and FoodListItem components to pass values. Create a member variable named foodItems of the FoodData[] type in the FoodList component and invoke the initializeOnStartup method to assign a value to the variable. Create a member variable foodItem of the FoodData type in the FoodListItem component. Pass the foodItems[0] of the first element in the parent foodItems array as a parameter to FoodListItem.
``` ```
import { FoodData } from '../model/FoodData' import { FoodData } from '../model/FoodData'
...@@ -68,7 +70,7 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -68,7 +70,7 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
5. Declare the UI layout of the **FoodListItem** child component. Create a **Flex** component, including the food image thumbnail, food name, and calories in the food. 5. Declare the UI layout of the FoodListItem child component. Create a Flex component, including the food image thumbnail, food name, and calories in the food.
``` ```
import { FoodData } from '../model/FoodData' import { FoodData } from '../model/FoodData'
...@@ -110,9 +112,9 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -110,9 +112,9 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
![](figures/en-us_image_0000001204776353.png) ![en-us_image_0000001267887833](figures/en-us_image_0000001267887833.png)
6. Create two **FoodListItem** objects. Create two **FoodListItem** objects in the **List** component and pass the first element **this.foodItems\[0\]** and the second element **foodItem: this.foodItems\[1\]** to the **FoodListItem**. 6. Create two FoodListItem objects. Create two FoodListItem objects in the List component and pass the first element this.foodItems[0] and the second element foodItem: this.foodItems[1] to the FoodListItem.
``` ```
import { FoodData } from '../model/FoodData' import { FoodData } from '../model/FoodData'
...@@ -157,9 +159,9 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -157,9 +159,9 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
![](figures/en-us_image_0000001204537865.png) ![en-us_image_0000001267767849](figures/en-us_image_0000001267767849.png)
7. Import **ForEach** so that you do not need to create **FoodListItem** objects one by one. 7. Import ForEach so that you do not need to create FoodListItem objects one by one.
``` ```
ForEach( ForEach(
...@@ -169,9 +171,10 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -169,9 +171,10 @@ Use the **List** component and **ForEach** loop to build the food category l
) )
``` ```
The **ForEach** group has three parameters. The first parameter is the array to be traversed, the second parameter is the lambda function for generating child components, and the third parameter is the key value generator. The third parameter is optional. Yet, for performance reasons, it is strongly recommended that you provide it. **keyGenerator** enables the development framework to better recognize array changes without having to rebuild all nodes after item changes. The ForEach group has three parameters. The first parameter is the array to be traversed, the second parameter is the lambda function for generating child components, and the third parameter is the key value generator. The third parameter is optional. Yet, for performance reasons, it is strongly recommended that you provide it. keyGenerator enables the development framework to better recognize array changes without having to rebuild all nodes after item changes.
Traverse the foodItems array to cyclically create the ListItem component. Pass each item in foodItems as a parameter to the FoodListItem component.
Traverse the **foodItems** array to cyclically create the **ListItem** component. Pass each item in **foodItems** as a parameter to the **FoodListItem** component.
``` ```
ForEach(this.foodItems, item => { ForEach(this.foodItems, item => {
...@@ -183,6 +186,7 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -183,6 +186,7 @@ Use the **List** component and **ForEach** loop to build the food category l
The code is as follows: The code is as follows:
``` ```
import { FoodData } from '../model/FoodData' import { FoodData } from '../model/FoodData'
import { initializeOnStartup } from '../model/FoodDataModels' import { initializeOnStartup } from '../model/FoodDataModels'
...@@ -225,7 +229,7 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -225,7 +229,7 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
8. Add a title for the **FoodList**. 8. Add a title for the FoodList.
``` ```
@Entry @Entry
...@@ -254,6 +258,4 @@ Use the **List** component and **ForEach** loop to build the food category l ...@@ -254,6 +258,4 @@ Use the **List** component and **ForEach** loop to build the food category l
} }
``` ```
![](figures/en-us_image_0000001169678922.png) ![en-us_image_0000001267607877](figures/en-us_image_0000001267607877.png)
# Building a Food Data Model<a name="EN-US_TOPIC_0000001146785866"></a> # Building a Food Data Model
On the created page, we use various items to describe food, such as food names, calories, proteins, fats, carbohydrates, and vitamin C. This form of coding is impractical in actual development. Therefore, you need to create food data models to store and manage data in a unified manner. On the created page, we use various items to describe food, such as food names, calories, proteins, fats, carbohydrates, and vitamin C. This form of coding is impractical in actual development. Therefore, you need to create food data models to store and manage data in a unified manner.
![](figures/en-us_image_0000001215433095.png)
1. Create a folder named **model** and create a file named **FoodData.ets** therein. ![en-us_image_0000001267767897](figures/en-us_image_0000001267767897.png)
![](figures/en-us_image_0000001195119619.png)
2. Define a food data storage model, **FoodData**, and an enum variable, **Category**. The **FoodData** class contains the food ID, name, category, image, calories, protein, fat, carbohydrates, and vitamin C attributes. 1. Create a folder named model and create a file named FoodData.ets therein.
![en-us_image_0000001223127760](figures/en-us_image_0000001223127760.png)
2. Define a food data storage model, FoodData, and an enum variable, Category. The FoodData class contains the food ID, name, category, image, calories, protein, fat, carbohydrates, and vitamin C attributes.
The eTS programming language is an extension of the TS language and also supports the TS syntax. The eTS programming language is an extension of the TS language and also supports the TS syntax.
``` ```
enum Category { enum Category {
Fruit, Fruit,
...@@ -47,13 +49,12 @@ On the created page, we use various items to describe food, such as food names, ...@@ -47,13 +49,12 @@ On the created page, we use various items to describe food, such as food names,
} }
``` ```
3. Store food image resources in the **resources** \> **phone** \> **media** directory. Use food names as the image names. 3. Store food image resources in the resources > phone > media directory. Use food names as the image names.
![en-us_image_0000001222967800](figures/en-us_image_0000001222967800.png)
![](figures/en-us_image_0000001195117633.png) 4. Create food resource data. Create FoodDataModels.ets in the model folder and declare a food composition array, FoodComposition on the page.
In this example, 12 pieces of food data are used. You can customize more data resources when needed. Use LazyForEach to load data if a large amount of food data is involved. The following nutritional data is sourced from the Internet.
4. Create food resource data. Create **FoodDataModels.ets** in the **model** folder and declare a food composition array, **FoodComposition** on the page.
In this example, 12 pieces of food data are used. You can customize more data resources when needed. Use **LazyForEach** to load data if a large amount of food data is involved. The following nutritional data is sourced from the Internet.
``` ```
const FoodComposition: any[] = [ const FoodComposition: any[] = [
...@@ -72,7 +73,7 @@ On the created page, we use various items to describe food, such as food names, ...@@ -72,7 +73,7 @@ On the created page, we use various items to describe food, such as food names,
] ]
``` ```
5. Create the **initializeOnStartUp** method to initialize the **FoodData** array. Export the **FoodData** class from **FoodData.ets**, and import **FoodData** and **Category** in **FoodDataModels.ets**. 5. Create the initializeOnStartUp method to initialize the FoodData array. Export the FoodData class from FoodData.ets, and import FoodData and Category in FoodDataModels.ets.
``` ```
// FoodData.ets // FoodData.ets
...@@ -96,4 +97,3 @@ On the created page, we use various items to describe food, such as food names, ...@@ -96,4 +97,3 @@ On the created page, we use various items to describe food, such as food names,
The data resources for the diet application are now ready. You can continue to create a food category list by loading the data. The data resources for the diet application are now ready. You can continue to create a food category list by loading the data.
# Web # Web
The **\<Web>** component can be used to display web pages. For details, see [Web API](../reference/arkui-ts/ts-basic-components-web.md). The \<Web> component can be used to display web pages. For details, see [Web API](../reference/arkui-ts/ts-basic-components-web.md).
## Creating a Component ## Creating a Component
Create a **\<Web>** component in the .ets file under **main/ets/MainAbility/pages**. Then, in the created component, use **src** to specify the web page URI to be referenced, and bind a controller to the component to call the component APIs. Create a \<Web> component in the .ets file under main/ets/MainAbility/pages. Then, in the created component, use src to specify the web page URI to be referenced, and bind a controller to the component to call the component APIs.
``` ```
// xxx.ets // xxx.ets
...@@ -22,7 +22,7 @@ Create a **\<Web>** component in the .ets file under **main/ets/MainAbility/page ...@@ -22,7 +22,7 @@ Create a **\<Web>** component in the .ets file under **main/ets/MainAbility/page
## Setting Styles and Attributes ## Setting Styles and Attributes
When using the **\<Web>** component, you need to specify the styles and attributes. The sample code is as follows. When using the \<Web> component, you need to specify the styles and attributes. The sample code is as follows.
``` ```
// xxx.ets // xxx.ets
...@@ -50,7 +50,7 @@ struct WebComponent { ...@@ -50,7 +50,7 @@ struct WebComponent {
``` ```
## Adding Events and Methods ## Adding Events and Methods
Add the **onProgressChange** event for the **\<Web>** component, which is triggered when the loading progress changes and returns the progress value in its callback. Assign the progress value to the **\<Progress>** component to control the status of the component. When the progress reaches 100%, the **\<Progress>** component is hidden, and the web page loading is complete. Add the onProgressChange event for the \<Web> component, which is triggered when the loading progress changes and returns the progress value in its callback. Assign the progress value to the \<Progress> component to control the status of the component. When the progress reaches 100%, the \<Progress> component is hidden, and the web page loading is complete.
``` ```
// xxx.ets // xxx.ets
...@@ -89,7 +89,7 @@ struct WebComponent { ...@@ -89,7 +89,7 @@ struct WebComponent {
} }
} }
``` ```
Add the **runJavaScript** method to the **onPageEnd** event. The **onPageEnd** event is triggered when the web page finishes loading. In this case, the **runJavaScript** method can be used to execute JavaScript scripts in the HTML file. In the sample code below, when the web page finishes loading, the **onPageEnd** event is triggered to call the **test** method in the HTML file and print information on the console. Add the runJavaScript method to the onPageEnd event. The onPageEnd event is triggered when the web page finishes loading. In this case, the runJavaScript method can be used to execute JavaScript scripts in the HTML file. In the sample code below, when the web page finishes loading, the onPageEnd event is triggered to call the test method in the HTML file and print information on the console.
``` ```
// xxx.ets // xxx.ets
...@@ -134,7 +134,7 @@ struct WebComponent { ...@@ -134,7 +134,7 @@ struct WebComponent {
} }
``` ```
Create an HTML file in **main/resources/rawfile**. Create an HTML file in main/resources/rawfile.
``` ```
<!-- index.html --> <!-- index.html -->
...@@ -153,7 +153,7 @@ Create an HTML file in **main/resources/rawfile**. ...@@ -153,7 +153,7 @@ Create an HTML file in **main/resources/rawfile**.
``` ```
## Scenario Example ## Scenario Example
In this example, you'll implement a **\<Web>** component where videos can be played dynamically. Embed a video resource into an HTML page, and then use the **\<Web>** component controller to invoke the **onActive** and **onInactive** methods to activate and pause page rendering, respectively. When the page is hidden, the **\<Web>** component stops rendering and the video playback pauses. When the page is displayed, the **\<Web>** component is activated and the video playback resumes. In this example, you'll implement a \<Web> component where videos can be played dynamically. Embed a video resource into an HTML page, and then use the \<Web> component controller to invoke the onActive and onInactive methods to activate and pause page rendering, respectively. When the page is hidden, the \<Web> component stops rendering and the video playback pauses. When the page is displayed, the \<Web> component is activated and the video playback resumes.
``` ```
// xxx.ets // xxx.ets
......
# Getting to Know Components<a name="EN-US_TOPIC_0000001192705717"></a> # Getting to Know Components
Before customizing a component, get to know what the [component and decorator](#section1094392618525) are and initialize the component. Then, [modify the component attributes and constructor parameters](#section19391124065216) to customize a component.
## Components and Decorators<a name="section1094392618525"></a> Before customizing a component, get to know what the [component and decorator](#components-and-decorators) are and initialize the component. Then, [modify the component attributes and constructor parameters](#modifying-component-attributes-and-constructor-parameters) to customize a component.
In a declarative UI, all pages are composed of components. The data structure of the component is **struct**, and the decorator [@Component](ts-component-based-component.md) is the component-based flag. The struct decorated by **@Component** indicates that the struct has the component capability.
## Components and Decorators
In a declarative UI, all pages are composed of components. The data structure of the component is struct, and the decorator [@Component](ts-component-based-component.md) is the component-based flag. The struct decorated by @Component indicates that the struct has the component capability.
The method for declaring a custom component is as follows: The method for declaring a custom component is as follows:
``` ```
@Component @Component
struct MyComponent {} struct MyComponent {}
``` ```
In an IDE project template, **MyComponent** is a custom component that can display text in the center. You can describe your UI structures in the **build** method of the component, by complying with the API constraints of the **Builder**. In an IDE project template, MyComponent is a custom component that can display text in the center. You can describe your UI structures in the build method of the component, by complying with the API constraints of the Builder.
``` ```
interface Builder { interface Builder {
...@@ -21,23 +25,24 @@ interface Builder { ...@@ -21,23 +25,24 @@ interface Builder {
} }
``` ```
The component decorated by [@Entry](ts-component-based-entry.md) indicates that the component is the main entry of the page and can also be considered as the root node of the page. Note that a page must have one and only one **@Entry**. Only the **@Entry** decorated component and its child components are displayed on the page. The component decorated by [@Entry](ts-component-based-entry.md) indicates that the component is the main entry of the page and can also be considered as the root node of the page. **NOTE** that a page must have one and only one @Entry. Only the @Entry decorated component and its child components are displayed on the page.
**@Component** and **@Entry** are basic and important decorators. To put it simply, a decorator assigns a capability to an object to be decorated. For example, **@Entry** assigns the capability of the page entry, and **@Component** assigns the component capability. @Component and @Entry are basic and important decorators. To put it simply, a decorator assigns a capability to an object to be decorated. For example, @Entry assigns the capability of the page entry, and @Component assigns the component capability.
With a basic knowledge of the component and decorator, you are ready to develop a diet application. With a basic knowledge of the component and decorator, you are ready to develop a diet application.
## Modifying Component Attributes and Constructor Parameters<a name="section19391124065216"></a>
When you create a system component, the default style is used. You can change the display of the component by changing its attributes and styles. ## Modifying Component Attributes and Constructor Parameters
1. Modify the **fontSize** attribute of the **<Text\>** component to change the font size of the component. In this example, the font size is set to 26 and font weight 500. Two configuration methods are available for setting the font weight: When you create a system component, the default style is used. You can change the display of the component by changing its attributes and styles.
1. The value of the number type ranges from 100 to 900. The default value is **400**. A larger value indicates a thicker font. 1. Modify the fontSize attribute of the <Text> component to change the font size of the component. In this example, the font size is set to 26 and font weight 500. Two configuration methods are available for setting the font weight:
2. **fontWeight** is a built-in enumeration type. Its value can be **Lighter**, **Normal**, **Bold**, or **Bolder**. 1. The value of the number type ranges from 100 to 900. The default value is 400. A larger value indicates a thicker font.
2. fontWeight is a built-in enumeration type. Its value can be Lighter, Normal, Bold, or Bolder.
The attribute method must follow the component and be connected by the operator ".". You can also configure multiple attributes of the component in method chaining mode. The attribute method must follow the component and be connected by the operator ".". You can also configure multiple attributes of the component in method chaining mode.
``` ```
@Entry @Entry
@Component @Component
...@@ -54,9 +59,9 @@ When you create a system component, the default style is used. You can change th ...@@ -54,9 +59,9 @@ When you create a system component, the default style is used. You can change th
} }
``` ```
![](figures/en-us_image_0000001168728272.png) ![en-us_image_0000001267767845](figures/en-us_image_0000001267767845.png)
2. Change the display content of the **<Text\>** component from **Hello World** to **Tomato** by modifying the constructor parameters of the **<Text\>** component. 2. Change the display content of the <Text> component from Hello World to Tomato by modifying the constructor parameters of the <Text> component.
``` ```
@Entry @Entry
...@@ -74,6 +79,4 @@ When you create a system component, the default style is used. You can change th ...@@ -74,6 +79,4 @@ When you create a system component, the default style is used. You can change th
} }
``` ```
![](figures/en-us_image_0000001168888224.png) ![en-us_image_0000001267887829](figures/en-us_image_0000001267887829.png)
# Creating a Declarative UI Project<a name="EN-US_TOPIC_0000001146785864"></a> # Creating a Declarative UI Project
Before creating a project, you need to install DevEco Studio. For details, see [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387).
1. Open DevEco Studio and click **Create Project**. If there is already a project, choose **File** \> **New** \> **New project**. Before creating a project, you need to install DevEco Studio.
![](figures/en-us_image_0000001168956332.png)
2. On the page for selecting an ability template, select **\[Standard\]Empty Ability**. 1. Open DevEco Studio and click Create Project. If there is already a project, choose File > New > New project.
![en-us_image_0000001267607861](figures/en-us_image_0000001267607861.png)
![](figures/en-us_image_0000001168059158.png) 2.
3. Install the OpenHarmony SDK.
![](figures/en-us_image_0000001213462329.png) On the page for selecting an ability template, select [Standard]Empty Ability.
4. On the project configuration page, set Project Name to **HealthyDiet**, **Project Type** to **Application**, **Device Type** to **Phone**, **Language** to **eTS**, and **Compatible API Version** to **SDK: API Version 7**. By default, DevEco Studio saves the project to drive C. You can change the save path by setting **Save Location**. When you are done, click **Finish**. ![en-us_image_0000001223127704](figures/en-us_image_0000001223127704.png)
![](figures/en-us_image_0000001167746622.png) 3.
Install the OpenHarmony SDK.
5. After the project is created, open the **app.ets** file. ![en-us_image_0000001223127700](figures/en-us_image_0000001223127700.png)
The **app.ets** file provides the **onCreate** and **onDestroy** methods for the application lifecycle. **onCreate** is called when an application is created, and **onDestroy** is called when an application is destroyed. Global variables can be declared in the **app.ets** file, wherein the declared data and methods are shared by the entire application. 4. On the project configuration page, set Project Name to HealthyDiet, Project Type to Application, Device Type to Phone, Language to eTS, and Compatible API Version to SDK: API Version 7. By default, DevEco Studio saves the project to drive C. You can change the save path by setting Save Location. When you are done, click Finish.
![en-us_image_0000001267647849](figures/en-us_image_0000001267647849.png)
5. After the project is created, open the app.ets file.
The app.ets file provides the onCreate and onDestroy methods for the application lifecycle. onCreate is called when an application is created, and onDestroy is called when an application is destroyed. Global variables can be declared in the app.ets file, wherein the declared data and methods are shared by the entire application.
``` ```
export default { export default {
...@@ -33,7 +38,7 @@ Before creating a project, you need to install DevEco Studio. For details, see ...@@ -33,7 +38,7 @@ Before creating a project, you need to install DevEco Studio. For details, see
} }
``` ```
6. In the project navigation tree, open **index.ets**. This page displays the current UI description. The declarative UI framework automatically generates a component-based **struct**, which complies with the **Builder** API declaration. The current layout and components are declared in the **build** method. 6. In the project navigation tree, open index.ets. This page displays the current UI description. The declarative UI framework automatically generates a component-based struct, which complies with the Builder API declaration. The current layout and components are declared in the build method.
``` ```
@Entry @Entry
...@@ -51,17 +56,14 @@ Before creating a project, you need to install DevEco Studio. For details, see ...@@ -51,17 +56,14 @@ Before creating a project, you need to install DevEco Studio. For details, see
} }
``` ```
7. Click **Previewer** on the right to open the **Previewer** window. In the **Previewer** window of the phone type, **Hello World** is displayed in the middle and in bold. 7. Click Previewer on the right to open the Previewer window. In the Previewer window of the phone type, Hello World is displayed in the middle and in bold.
If the Previewer button is unavailable, choose Settings > SDK Manager >OpenHarmony SDK > Tools to check whether the Previewer is installed.
If the **Previewer** button is unavailable, choose **Settings** \> **SDK Manager** \>OpenHarmony SDK \> **Tools** to check whether the **Previewer** is installed.
![](figures/en-us_image_0000001214595111.png)
8. Install the application on the phone and run the application. Connect the phone to the computer. After the IDE identifies the phone, click **Run'entry'**.
![](figures/en-us_image_0000001148858818.png) ![en-us_image_0000001222807756](figures/en-us_image_0000001222807756.png)
Before the installation, you must configure an application signature. For details, see [Configuring the OpenHarmony App Signature](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768). After the installation is complete, click the **Run** icon on the screen to open the application. **Hello World** is displayed in the center of the screen. 8. Install the application on the phone and run the application. Connect the phone to the computer. After the IDE identifies the phone, click Run'entry'.
![en-us_image_0000001267607865](figures/en-us_image_0000001267607865.png)
![](figures/en-us_image_0000001158896538.png) Before the installation, you must configure an application signature. For details, see [Configuring the OpenHarmony App Signature](../quick-start/configuring-the-openharmony-app-signature.md). After the installation is complete, click the Run icon on the screen to open the application. Hello World is displayed in the center of the screen.
![en-us_image_0000001267647841](figures/en-us_image_0000001267647841.png)
# Creating a Simple Page<a name="EN-US_TOPIC_0000001192745831"></a> # Creating a Simple Page
In this section, we will develop an infographic food details page, by building custom components through the container components **<Stack\>** and **<Flex\>** as well as basic components **<Image\>** and **<Text\>**.
## Building the Stack Layout<a name="section12782105345718"></a> In this section, we will develop an infographic food details page, by building custom components through the container components &lt;Stack&gt; and &lt;Flex&gt; as well as basic components &lt;Image&gt; and &lt;Text&gt;.
1. Create a food name.
Delete the code of the **build** method in the project template, create a **<Stack\>** component, and place the **<Text\>** component in the braces of the **<Stack\>** component so that the **<Text\>** component becomes a child component of the **<Stack\>** component. A **<Stack\>** component consists of one or more child components. The latter child component overwrites the former one. ## Building the Stack Layout
1. Create a food name.
Delete the code of the build method in the project template, create a &lt;Stack&gt; component, and place the &lt;Text&gt; component in the braces of the &lt;Stack&gt; component so that the &lt;Text&gt; component becomes a child component of the &lt;Stack&gt; component. A &lt;Stack&gt; component consists of one or more child components. The latter child component overwrites the former one.
``` ```
@Entry @Entry
...@@ -22,11 +23,10 @@ In this section, we will develop an infographic food details page, by building c ...@@ -22,11 +23,10 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001214128687.png) ![en-us_image_0000001222967780](figures/en-us_image_0000001222967780.png)
2. Display food pictures. 2. Display food pictures.
Create an &lt;Image&gt; component and specify a URL for it. The &lt;Image&gt; and &lt;Text&gt; components are mandatory. To display the &lt;Text&gt; component above the &lt;Image&gt; component, you need to declare the &lt;Image&gt; component first. Image resources are stored in the rawfile folder in resources. When referencing the resources in the rawfile folder, use the $rawfile('_filename_ loaded) format, where filename indicates the relative path of the file in the rawfile folder. Currently, $rawfile only allows the &lt;Image&gt; component to reference image resources.
Create an **<Image\>** component and specify a URL for it. The **<Image\>** and **<Text\>** components are mandatory. To display the **<Text\>** component above the **<Image\>** component, you need to declare the **<Image\>** component first. Image resources are stored in the **rawfile** folder in **resources**. When referencing the resources in the **rawfile** folder, use the **$rawfile\('_filename_ loaded\)** format, where **filename** indicates the relative path of the file in the **rawfile** folder. Currently, **$rawfile** only allows the **<Image\>** component to reference image resources.
``` ```
@Entry @Entry
...@@ -43,19 +43,19 @@ In this section, we will develop an infographic food details page, by building c ...@@ -43,19 +43,19 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001168410342.png) ![en-us_image_0000001267887861](figures/en-us_image_0000001267887861.png)
3. Access images through resources. 3. Access images through resources.
In addition to specifying the image path, you can also use the media resource symbol $r to reference resources based on the resource qualifier rules in the resources folder. Right-click the resources folder, choose New &gt; Resource Directory, set Resource Type to Media (image resource), and set the resource qualifier to Device-Phone (currently, phones are used).
In addition to specifying the image path, you can also use the media resource symbol **$r** to reference resources based on the resource qualifier rules in the **resources** folder. Right-click the **resources** folder, choose **New** \> **Resource Directory**, set **Resource Type** to **Media** \(image resource\), and set the resource qualifier to **Device-Phone** \(currently, phones are used\). ![en-us_image_0000001267887853](figures/en-us_image_0000001267887853.png)
![](figures/en-us_image_0000001168570318.png) Click OK. The phone.media folder is generated in the resources folder. Place Tomato.png in the folder.
Click **OK**. The **phone.media** folder is generated in the **resources** folder. Place **Tomato.png** in the folder. ![en-us_image_0000001222807784](figures/en-us_image_0000001222807784.png)
![](figures/en-us_image_0000001214330169.png) You can then can reference the application resource in the $r('app.type.name') format, that is, $r('app.media.Tomato').
You can then can reference the application resource in the **$r\('app.type.name'\)** format, that is, **$r\('app.media.Tomato'\)**.
``` ```
@Entry @Entry
...@@ -74,12 +74,12 @@ In this section, we will develop an infographic food details page, by building c ...@@ -74,12 +74,12 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
4. Set the width and height of the image, and set the **objectFit** attribute of the image to **ImageFit.Contain**, which means to keep the aspect ratio of the image to ensure that the image is completely displayed within the boundary. 4. Set the width and height of the image, and set the objectFit attribute of the image to ImageFit.Contain, which means to keep the aspect ratio of the image to ensure that the image is completely displayed within the boundary.
If the image fills the entire screen, the possible causes are as follows: If the image fills the entire screen, the possible causes are as follows:
1. The width and height of the image are not set. 1. The width and height of the image are not set.
2. The default attribute of **objectFit** of the image is **ImageFit.Cover**, that is, the image is zoomed in or zoomed out to fill the entire display boundary with the aspect ratio locked.
2. The default attribute of objectFit of the image is ImageFit.Cover, that is, the image is zoomed in or zoomed out to fill the entire display boundary with the aspect ratio locked.
``` ```
@Entry @Entry
...@@ -98,9 +98,9 @@ In this section, we will develop an infographic food details page, by building c ...@@ -98,9 +98,9 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001214210217.png) ![en-us_image_0000001223127732](figures/en-us_image_0000001223127732.png)
5. Set the food image and name layout. Set the alignment mode of the stack to bottom alignment. By default, the stack is center aligned. Set **alignContent** to **Alignment.BottomStart**. Similar to **FontWeight**, **Alignment** is a built-in enumeration type provided by the framework. 5. Set the food image and name layout. Set the alignment mode of the stack to bottom alignment. By default, the stack is center aligned. Set alignContent to Alignment.BottomStart. Similar to FontWeight, Alignment is a built-in enumeration type provided by the framework.
``` ```
@Entry @Entry
...@@ -119,12 +119,12 @@ In this section, we will develop an infographic food details page, by building c ...@@ -119,12 +119,12 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001168728872.png) ![en-us_image_0000001267647873](figures/en-us_image_0000001267647873.png)
6. You can change the background color of the food image by setting the background color of the stack. You can set the background color in either of the following ways: 6. You can change the background color of the food image by setting the background color of the stack. You can set the background color in either of the following ways:
1. By using the built-in enumeration value of Color provided by the framework. For example, backgroundColor(Color.Red) indicates that the background color is set to red.
2. By using the parameter of the string type. The supported color formats are rgb, rgba, and HEX. For example, you can set the background color to blue by setting backgroundColor(??\#0000FF??) and set the background color to white by setting backgroundColor(??rgb(255, 255, 255)??).
1. By using the built-in enumeration value of **Color** provided by the framework. For example, **backgroundColor\(Color.Red\)** indicates that the background color is set to red.
2. By using the parameter of the string type. The supported color formats are rgb, rgba, and HEX. For example, you can set the background color to blue by setting **backgroundColor\(??\#0000FF??\)** and set the background color to white by setting **backgroundColor\(??rgb\(255, 255, 255\)??\)**.
``` ```
@Entry @Entry
...@@ -144,12 +144,12 @@ In this section, we will develop an infographic food details page, by building c ...@@ -144,12 +144,12 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001168888822.png) ![en-us_image_0000001222967772](figures/en-us_image_0000001222967772.png)
7. Adjust the left and bottom margin of the **<Text\>** component. Margin is a shorthand attribute. You can specify the margins of the four edges in a unified manner or separately. The configuration method is as follows: 7. Adjust the left and bottom margin of the &lt;Text&gt; component. Margin is a shorthand attribute. You can specify the margins of the four edges in a unified manner or separately. The configuration method is as follows:
1. When the parameter is set to Length, the outer margins of the four edges are specified. For example, margin(20) indicates that the outer margins of the top, right, bottom, and left edges are all 20.
2. {top?: Length, right?: Length, bottom?: Length, left?:Length} specifies the margins of the four edges. For example, margin({ left: 26, bottom: 17.4 }) indicates that the left margin is 26 and the bottom margin is 17.4.
1. When the parameter is set to **Length**, the outer margins of the four edges are specified. For example, **margin\(20\)** indicates that the outer margins of the top, right, bottom, and left edges are all 20.
2. **\{top?: Length, right?: Length, bottom?: Length, left?:Length\}** specifies the margins of the four edges. For example, **margin\(\{ left: 26, bottom: 17.4 \}\)** indicates that the left margin is 26 and the bottom margin is 17.4.
``` ```
@Entry @Entry
...@@ -170,12 +170,12 @@ In this section, we will develop an infographic food details page, by building c ...@@ -170,12 +170,12 @@ In this section, we will develop an infographic food details page, by building c
} }
``` ```
![](figures/en-us_image_0000001213968747.png) ![en-us_image_0000001222967776](figures/en-us_image_0000001222967776.png)
8. Adjust the structure between components and semanticize component names. Create the **FoodDetail** page entry component, create a column in **FoodDetail**, and set the alignment to **alignItems\(HorizontalAlign.Center\)**. Change the name of the **MyComponent** component to **FoodImageDisplay**, which is a child component of the **FoodDetail** component.
8. Adjust the structure between components and semanticize component names. Create the FoodDetail page entry component, create a column in FoodDetail, and set the alignment to alignItems(HorizontalAlign.Center). Change the name of the MyComponent component to FoodImageDisplay, which is a child component of the FoodDetail component.
A column is a container component whose child components are vertically arranged. It is a linear layout in essence. Therefore, only the alignment in the cross axis direction can be set. A column is a container component whose child components are vertically arranged. It is a linear layout in essence. Therefore, only the alignment in the cross axis direction can be set.
``` ```
@Component @Component
struct FoodImageDisplay { struct FoodImageDisplay {
...@@ -206,11 +206,11 @@ In this section, we will develop an infographic food details page, by building c ...@@ -206,11 +206,11 @@ In this section, we will develop an infographic food details page, by building c
``` ```
## Building the Flex Layout<a name="section46084390581"></a> ## Building the Flex Layout
You can use the **Flex** layout to build a food composition table. In this way you do not need to worry about the width and height calculation. The size of different cells can be flexibly set based on the proportion. You can use the Flex layout to build a food composition table. In this way you do not need to worry about the width and height calculation. The size of different cells can be flexibly set based on the proportion.
1. Create a **ContentTable** component as a child component of the **FoodDetail** component. 1. Create a ContentTable component as a child component of the FoodDetail component.
``` ```
@Component @Component
...@@ -247,13 +247,13 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -247,13 +247,13 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
2. Create a **Flex** component to display two food composition categories in the tomato: Calories and Nutrition. 2. Create a Flex component to display two food composition categories in the tomato: Calories and Nutrition.
Calories contains information about calories. Nutrition contains information about protein, fat, carbohydrates, and vitamin C.
**Calories** contains information about calories. **Nutrition** contains information about protein, fat, carbohydrates, and vitamin C. Create the Calories class. Create a Flex component and set its height to 280, and the top, right, and left margins to 30. The Flex component contains three Text child components, which represent the category name (Calories), content name (Calories), and contain value (17 kcal), respectively. By default, child components in the Flex component are arranged horizontally.
Create the Calories class. Create a **Flex** component and set its height to **280**, and the top, right, and left margins to **30**. The **Flex** component contains three **Text** child components, which represent the category name \(**Calories**\), content name \(**Calories**\), and contain value \(**17 kcal**\), respectively. By default, child components in the **Flex** component are arranged horizontally. In the following example, code of FoodImageDisplay is omitted, and only code of ContentTable is provided.
In the following example, code of **FoodImageDisplay** is omitted, and only code of **ContentTable** is provided.
``` ```
@Component @Component
...@@ -286,9 +286,9 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -286,9 +286,9 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
![](figures/en-us_image_0000001169759552.png) ![en-us_image_0000001267767869](figures/en-us_image_0000001267767869.png)
3. Adjust the layout and set the proportion \(**layoutWeight**\) of each part. Set the proportion of the category name to 1, and the total proportion of content name and content value to **2**. The content name and content value are in a same **Flex**, and the content name occupies all remaining space **flexGrow\(1\)**. 3. Adjust the layout and set the proportion (layoutWeight) of each part. Set the proportion of the category name to 1, and the total proportion of content name and content value to 2. The content name and content value are in a same Flex, and the content name occupies all remaining space flexGrow(1).
``` ```
@Component @Component
...@@ -342,11 +342,11 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -342,11 +342,11 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
![](figures/en-us_image_0000001215079443.png) ![en-us_image_0000001267607901](figures/en-us_image_0000001267607901.png)
4. Create the **Nutrient** class in a similar process. **Nutrition** consists of four parts: **Protein**, **Fat**, **Carbohydrates**, and **VitaminC**. The names of the last three parts are omitted in the table and represented by spaces. 4. Create the Nutrient class in a similar process. Nutrition consists of four parts: Protein, Fat, Carbohydrates, and VitaminC. The names of the last three parts are omitted in the table and represented by spaces.
Set FlexDirection.Column, FlexAlign.SpaceBetween, and ItemAlign.Start.
Set **FlexDirection.Column**, **FlexAlign.SpaceBetween**, and **ItemAlign.Start**.
``` ```
@Component @Component
...@@ -442,18 +442,18 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -442,18 +442,18 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
5. Use the custom constructor **@Builder** to simplify the code. It can be found that the food groups in each food composition table are actually of the same UI structure. 5. Use the custom constructor @Builder to simplify the code. It can be found that the food groups in each food composition table are actually of the same UI structure.
![en-us_image_0000001223287704](figures/en-us_image_0000001223287704.png)
![](figures/en-us_image_0000001169599582.png) Currently, all food groups are declared, resulting in code duplication and redundancy. You can use @Builder to build a custom method and abstract the same UI structure declaration. The @Builder decorated method and the build method for the @Component decorated component are used to declare some UI rendering structures and comply with the same eTS syntax. You can define one or more methods decorated by @Builder, but a component decorated by @Component can have only one build method.
Currently, all food groups are declared, resulting in code duplication and redundancy. You can use **@Builder** to build a custom method and abstract the same UI structure declaration. The **@Builder** decorated method and the **build** method for the **@Component** decorated component are used to declare some UI rendering structures and comply with the same eTS syntax. You can define one or more methods decorated by **@Builder**, but a component decorated by **@Component** can have only one **build** method. Declare the IngredientItem method decorated by @Builder in ContentTable to declare the UI descriptions for the category name, content name, and content value.
Declare the **IngredientItem** method decorated by **@Builder** in **ContentTable** to declare the UI descriptions for the category name, content name, and content value.
``` ```
@Component @Component
struct ContentTable { struct ContentTable {
@Builder IngredientItem(title:string, colorValue: string, name: string, value: string) { @Builder IngredientItem(title:string, name: string, value: string) {
Flex() { Flex() {
Text(title) Text(title)
.fontSize(17.4) .fontSize(17.4)
...@@ -475,7 +475,8 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -475,7 +475,8 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
When the **IngredientItem** API is called in the **build** method of **ContentTable**, **this** needs to be used to invoke the method in the scope of the component to distinguish the global method call. When the IngredientItem API is called in the build method of ContentTable, this needs to be used to invoke the method in the scope of the component to distinguish the global method call.
``` ```
@Component @Component
...@@ -495,7 +496,8 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -495,7 +496,8 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
The overall code of the **ContentTable** component is as follows: The overall code of the ContentTable component is as follows:
``` ```
@Component @Component
...@@ -543,17 +545,14 @@ You can use the **Flex** layout to build a food composition table. In this way ...@@ -543,17 +545,14 @@ You can use the **Flex** layout to build a food composition table. In this way
} }
``` ```
![](figures/en-us_image_0000001215199399.png) ![en-us_image_0000001222807792](figures/en-us_image_0000001222807792.png)
You've learned how to build a simple food details page. Read on to learn how to define the page layout and connection. You've learned how to build a simple food details page. Read on to learn how to define the page layout and connection.
## Samples<a name="section1398393853412"></a> ## Samples
The following sample is provided to help you better understand how to use build a simple page: The following sample is provided to help you better understand how to use build a simple page:
- [eTSBuildCommonView](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSBuildCommonView) - [eTSBuildCommonView](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSBuildCommonView)
This sample shows how to build a common view to display the picture of tomatoes and nutrition information, with the stack layout and flex layout. This sample shows how to build a common view to display the picture of tomatoes and nutrition information, with the stack layout and flex layout.
# Experiencing the Declarative UI<a name="EN-US_TOPIC_0000001169595734"></a>
- **[Creating a Declarative UI Project](ui-ts-creating-project.md)**
- **[Getting to Know Components](ui-ts-components.md)**
- **[Creating a Simple Page](ui-ts-creating-simple-page.md)**
# Overview<a name="EN-US_TOPIC_0000001192705715"></a> # Overview
The TypeScript-based declarative development paradigm of ArkUI is a simplified, high-performance UI development framework for cross-device applications on OpenHarmony.
## Basic Capabilities<a name="section10519124516264"></a> The TypeScript-based declarative development paradigm of ArkUI is a simplified, high-performance UI development framework for cross-device applications.
## Basic Capabilities
In ArkUI that uses the TypeScript-based declarative development paradigm, the programming mode is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development. The UI capabilities are provided from three dimensions: component, animation, and state management. System capability APIs are also provided to allow for effortless invocation of system capabilities. In ArkUI that uses the TypeScript-based declarative development paradigm, the programming mode is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development. The UI capabilities are provided from three dimensions: component, animation, and state management. System capability APIs are also provided to allow for effortless invocation of system capabilities.
- **Out-of-the-box components**
- Out-of-the-box components
A wide range of preset system components are provided. You can set the rendering effect of these components in method chaining mode. You can combine system components to form custom components. In this way, page components are divided into independent UI units to implement independent creation, development, and reuse of different units on pages, making pages more engineering-oriented. A wide range of preset system components are provided. You can set the rendering effect of these components in method chaining mode. You can combine system components to form custom components. In this way, page components are divided into independent UI units to implement independent creation, development, and reuse of different units on pages, making pages more engineering-oriented.
- **A diverse array of animation APIs** - A diverse array of animation APIs
By drawing from the standard SVG drawing capability and various open animation APIs, you can customize animation tracks by encapsulating physical models or calling the provided APIs. By drawing from the standard SVG drawing capability and various open animation APIs, you can customize animation tracks by encapsulating physical models or calling the provided APIs.
- **State and data management** - State and data management
State data management provides clear page update and rendering processes and pipes through decorators with different functions. State management covers UI component states and application states. With these features, you are able to build an application-wide data update and UI rendering process. State data management provides clear page update and rendering processes and pipes through decorators with different functions. State management covers UI component states and application states. With these features, you are able to build an application-wide data update and UI rendering process.
- **System capability APIs** - System capability APIs
Development has never been so easy, with a diverse array of encapsulated system capability APIs, from UI design to system capability invoking. Development has never been so easy, with a diverse array of encapsulated system capability APIs, from UI design to system capability invoking.
## Overall Architecture<a name="section11428133282710"></a> ## Overall Architecture
![](figures/en-us_image_0000001169532276.png)
- **Declarative UI frontend**
Provides basic language specifications of the UI development paradigm, built-in UI components, layouts, and animations, and multiple state management mechanisms, with a wide array of APIs for you to call as required. ![en-us_image_0000001223287712](figures/en-us_image_0000001223287712.png)
- **Language runtime** - Declarative UI frontend
Provides basic language specifications of the UI development paradigm, built-in UI components, layouts, and animations, and multiple state management mechanisms, with a wide array of APIs for you to call as required.
- Language runtime
Provides the parsing capability for the UI paradigm syntax and allows for cross-language API calls for a high-performance running environment of the TS language. Provides the parsing capability for the UI paradigm syntax and allows for cross-language API calls for a high-performance running environment of the TS language.
- **Declarative UI backend engine** - Declarative UI backend engine
Provides UI rendering pipelines that are compatible with different development paradigms, multiple basic components, layout calculation, dynamic effects, and interaction events, with state management and drawing capabilities. Provides UI rendering pipelines that are compatible with different development paradigms, multiple basic components, layout calculation, dynamic effects, and interaction events, with state management and drawing capabilities.
- **Render engine** - Render engine
Provides efficient drawing capabilities, which enable rendering instructions collected by the rendering pipeline to be drawn to the screen. Provides efficient drawing capabilities, which enable rendering instructions collected by the rendering pipeline to be drawn to the screen.
- **Porting layer** - Porting layer
Provides abstract APIs to connect to different systems, such as system rendering pipelines and lifecycle scheduling. Provides abstract APIs to connect to different systems, such as system rendering pipelines and lifecycle scheduling.
# Defining Page Layout and Connection<a name="EN-US_TOPIC_0000001146626070"></a>
- **[Building a Food Data Model](ui-ts-building-data-model.md)**
- **[Building a Food Category List Layout](ui-ts-building-category-list-layout.md)**
- **[Building a Food Category Grid Layout](ui-ts-building-category-grid-layout.md)**
- **[Implementing Page Redirection and Data Transmission](ui-ts-page-redirection-data-transmission.md)**
# Implementing Page Redirection and Data Transmission<a name="EN-US_TOPIC_0000001146626072"></a> # Implementing Page Redirection and Data Transmission
This section describes how to implement page redirection and data transmission between pages: This section describes how to implement page redirection and data transmission between pages:
1. Page redirection: Click a food item on the food list page to go to the food details page. Click the back button on the food details page to go back to the food list page. 1. Page redirection: Click a food item on the food list page to go to the food details page. Click the back button on the food details page to go back to the food list page.
2. Data transmission between pages: After you click a food item, **FoodDetail** receives data from the previous page and renders the corresponding food details page.
## Page Redirection<a name="section14532666112"></a> 2. Data transmission between pages: After you click a food item, FoodDetail receives data from the previous page and renders the corresponding food details page.
## Page Redirection
The declarative UI paradigm provides two mechanisms for page redirection: The declarative UI paradigm provides two mechanisms for page redirection:
1. **Navigator**: encapsulates the page routing capability. After the page target is specified, all child components in the page target have the routing capability. 1. Navigator: encapsulates the page routing capability. After the page target is specified, all child components in the page target have the routing capability.
2. Router APIs: called to implement various operations of page routing. You'll need to import **router** before calling the router APIs.
2. Router APIs: called to implement various operations of page routing. You'll need to import router before calling the router APIs.
The procedure below uses these two mechanisms for redirection between the page list page and food details page. The procedure below uses these two mechanisms for redirection between the page list page and food details page.
1. Click **FoodListItem**. The **FoodDetail** page is displayed. Create a **Navigator** component in **FoodListItem** to enable its child components to have the routing function. The target page is **'pages/FoodDetail'**. 1. Click FoodListItem. The FoodDetail page is displayed. Create a Navigator component in FoodListItem to enable its child components to have the routing function. The target page is 'pages/FoodDetail'.
``` ```
@Component @Component
...@@ -42,9 +47,9 @@ The procedure below uses these two mechanisms for redirection between the page l ...@@ -42,9 +47,9 @@ The procedure below uses these two mechanisms for redirection between the page l
} }
``` ```
![](figures/listrouter.gif) ![en-us_image_0000001223127744](figures/en-us_image_0000001223127744.gif)
2. Click **FoodGridItem**. The **FoodDetail** page is displayed. Import the **router** module, and then call the **push** API of this module to push the **FoodDetail** page to the route stack to implement page redirection. 2. Click FoodGridItem. The FoodDetail page is displayed. Import the router module, and then call the push API of this module to push the FoodDetail page to the route stack to implement page redirection.
``` ```
import router from '@system.router' import router from '@system.router'
...@@ -65,9 +70,9 @@ The procedure below uses these two mechanisms for redirection between the page l ...@@ -65,9 +70,9 @@ The procedure below uses these two mechanisms for redirection between the page l
} }
``` ```
![](figures/routercategory.gif) ![en-us_image_0000001267607909](figures/en-us_image_0000001267607909.gif)
3. Add the icon for returning from the **FoodDetail** page to the food list page. Save the **Back.png** file to the **resources** \> **phone** \> **media** directory. Create a custom component **PageTitle**, which contains the back icon and Food Detail text. Call the **router.back\(\)** API of the router to display the top page of the route stack, that is, the upper-level page. 3. Add the icon for returning from the FoodDetail page to the food list page. Save the Back.png file to the resources > phone > media directory. Create a custom component PageTitle, which contains the back icon and Food Detail text. Call the router.back() API of the router to display the top page of the route stack, that is, the upper-level page.
``` ```
// FoodDetail.ets // FoodDetail.ets
...@@ -94,7 +99,7 @@ The procedure below uses these two mechanisms for redirection between the page l ...@@ -94,7 +99,7 @@ The procedure below uses these two mechanisms for redirection between the page l
} }
``` ```
4. Create the Stack component in the **FoodDetail** component, including the **FoodImageDisplay** and **PageTitle** child components. Set the alignment mode to **TopStart**. 4. Create the Stack component in the FoodDetail component, including the FoodImageDisplay and PageTitle child components. Set the alignment mode to TopStart.
``` ```
@Entry @Entry
...@@ -113,14 +118,14 @@ The procedure below uses these two mechanisms for redirection between the page l ...@@ -113,14 +118,14 @@ The procedure below uses these two mechanisms for redirection between the page l
} }
``` ```
![](figures/en-us_image_0000001214998349.png) ![en-us_image_0000001267767881](figures/en-us_image_0000001267767881.png)
## Data Transmission Between Pages<a name="section86431031144816"></a> ## Data Transmission Between Pages
We have implemented the redirection and going back of the **FoodCategoryList** and **FoodDetail** pages. At this point, the tomato details page is displayed no matter which **FoodListItem**/**FoodGridItem** is clicked. This is because the data transmission between pages is not yet configured. To configure data transmission between pages, set the routing with parameters as follows: We have implemented the redirection and going back of the FoodCategoryList and FoodDetail pages. At this point, the tomato details page is displayed no matter which FoodListItem/FoodGridItem is clicked. This is because the data transmission between pages is not yet configured. To configure data transmission between pages, set the routing with parameters as follows:
1. Set the **params** attribute in the **Navigator** of the **FoodListItem** component. The **params** attribute accepts the key-value object. 1. Set the params attribute in the Navigator of the FoodListItem component. The params attribute accepts the key-value object.
``` ```
// FoodList.ets // FoodList.ets
...@@ -136,7 +141,8 @@ We have implemented the redirection and going back of the **FoodCategoryList** ...@@ -136,7 +141,8 @@ We have implemented the redirection and going back of the **FoodCategoryList**
} }
``` ```
The router API called by **FoodGridItem** also has the capability of redirection with parameters. The method of using the router API is similar to that of using the **Navigator**. The router API called by FoodGridItem also has the capability of redirection with parameters. The method of using the router API is similar to that of using the Navigator.
``` ```
router.push({ router.push({
...@@ -145,7 +151,7 @@ We have implemented the redirection and going back of the **FoodCategoryList** ...@@ -145,7 +151,7 @@ We have implemented the redirection and going back of the **FoodCategoryList**
}) })
``` ```
2. Import the **FoodData** class to the **FoodDetail** page and add the **foodItem** member variable to the **FoodDetail** component. 2. Import the FoodData class to the FoodDetail page and add the foodItem member variable to the FoodDetail component.
``` ```
// FoodDetail.ets // FoodDetail.ets
...@@ -161,7 +167,7 @@ We have implemented the redirection and going back of the **FoodCategoryList** ...@@ -161,7 +167,7 @@ We have implemented the redirection and going back of the **FoodCategoryList**
} }
``` ```
3. Obtain the value of **foodData**. Call **router.getParams\(\).foodData** to obtain the data corresponding to **foodData** carried when the **FoodCategoryList** page is displayed. 3. Obtain the value of foodData. Call router.getParams().foodData to obtain the data corresponding to foodData carried when the FoodCategoryList page is displayed.
``` ```
@Entry @Entry
...@@ -175,7 +181,7 @@ We have implemented the redirection and going back of the **FoodCategoryList** ...@@ -175,7 +181,7 @@ We have implemented the redirection and going back of the **FoodCategoryList**
} }
``` ```
4. Re-build the components on the **FoodDetail** page. During building, the food information on the **FoodDetail** page is all directly declared constants. You need to use the passed **FoodData** data to assign a new value to the constants. The code is as follows: 4. Re-build the components on the FoodDetail page. During building, the food information on the FoodDetail page is all directly declared constants. You need to use the passed FoodData data to assign a new value to the constants. The code is as follows:
``` ```
@Component @Component
...@@ -267,13 +273,10 @@ We have implemented the redirection and going back of the **FoodCategoryList** ...@@ -267,13 +273,10 @@ We have implemented the redirection and going back of the **FoodCategoryList**
} }
``` ```
## Samples
## Samples<a name="section18889555307"></a>
The following sample is provided to help you better understand how to define the page layout and connection: The following sample is provided to help you better understand how to define the page layout and connection:
- [eTSDefiningPageLayoutAndConnection](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSDefiningPageLayoutAndConnection) - [eTSDefiningPageLayoutAndConnection](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSDefiningPageLayoutAndConnection)
This sample exemplifies the basic usage of the list layout, grid layout, and page routing, by building the food list page and food details page. This sample exemplifies the basic usage of the list layout, grid layout, and page routing, by building the food list page and food details page.
...@@ -6,25 +6,22 @@ ...@@ -6,25 +6,22 @@
1. 打开DevEco Studio,点击Create Project。如果已有一个工程,则点击File &gt; New &gt; New project。 1. 打开DevEco Studio,点击Create Project。如果已有一个工程,则点击File &gt; New &gt; New project。
![zh-cn_image_0000001168956332](figures/zh-cn_image_0000001168956332.png) ![zh-cn_image_0000001168956332](figures/zh-cn_image_0000001168956332.png)
2. 2.
进入选择ability template界面,选择[Standard]Empty Ability。 进入选择Ability Template界面,选择Empty Ability。
![zh-cn_image_0000001168059158](figures/zh-cn_image_0000001168059158.png) ![zh-cn_image_0000001168059158](figures/zh-cn_image_0000001168059158.png)
3. 4. 进入配置工程界面,将工程名字改为HealthyDiet,Project Type选择Application,Compile API选择8,UI Syntax选择eTS。DevEco Studio会默认将工程保存在C盘,如果要更改工程保存位置,点击Save Location的文件夹图标,自行指定工程创建位置。配置完成后点击Finish。
安装OpenHarmony SDK。
![zh-cn_image_0000001213462329](figures/zh-cn_image_0000001213462329.png)
4. 进入配置工程界面,将工程名字改为HealthyDiet,Project Type选择Application,Device Type选择Phone,Language选择eTS,选择兼容API Version 7。DevEco Studio会默认将工程保存在C盘,如果要更改工程保存位置,点击Save Location的文件夹图标,自行指定工程创建位置。配置完成后点击Finish。
![zh-cn_image_0000001167746622](figures/zh-cn_image_0000001167746622.png) ![zh-cn_image_0000001167746622](figures/zh-cn_image_0000001167746622.png)
5. 工程创建完成后,打开app.ets。 5. 工程创建完成后,打开app.ets。
app.ets提供了应用生命周期的接口:onCreate和onDestroy,分别在应用创建之初和应用被销毁时调用。在app.ets里可以声明全局变量,并且声明的数据和方法是整个应用共享的。 app.ets提供了应用生命周期的接口:onCreate和onDestroy,分别在应用创建之初和应用被销毁时调用。在app.ets里可以声明全局变量,并且声明的数据和方法是整个应用共享的。
``` ```
export default { export default {
onCreate() { onCreate() {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
![zh-cn_image_0000001214128687](figures/zh-cn_image_0000001214128687.png) ![zh-cn_image_0000001214128687](figures/zh-cn_image_0000001214128687.png)
2. 食物图片展示。 2. 食物图片展示。
创建Image组件,指定Image组件的url,Image组件和Text组件都是必选构造参数组件。为了让Text组件在Image组件上方显示,所以要先声明Image组件。图片资源放在resources下的rawfile文件夹内,引用rawfile下资源时使用```“$rawfile('filename')”```的形式,filename为rawfile目录下的文件相对路径。当前$rawfile仅支持Image控件引用图片资源。 创建Image组件,指定Image组件的url,Image组件和Text组件都是必选构造参数组件。为了让Text组件在Image组件上方显示,所以要先声明Image组件。图片资源放在resources下的rawfile文件夹内,引用rawfile下资源时使用“$rawfile('filename')”的形式,filename为rawfile目录下的文件相对路径。当前$rawfile仅支持Image控件引用图片资源。
``` ```
@Entry @Entry
@Component @Component
...@@ -47,11 +47,11 @@ ...@@ -47,11 +47,11 @@
![zh-cn_image_0000001168570318](figures/zh-cn_image_0000001168570318.png) ![zh-cn_image_0000001168570318](figures/zh-cn_image_0000001168570318.png)
点击OK后,resources文件夹下生成phone.media文件夹。将Tomato.png放入该文件夹内。 点击OK后,resources文件夹下生成phone文件夹,phone文件夹下生成media文件夹,将Tomato.png放入media文件夹内。
![zh-cn_image_0000001214330169](figures/zh-cn_image_0000001214330169.png) ![zh-cn_image_0000001214330169](figures/zh-cn_image_0000001214330169.png)
就可以通过```“$r('app.type.name')”```的形式引用应用资源,即$r('app.media.Tomato')。 就可以通过“$r('app.type.name')”的形式引用应用资源,即$r('app.media.Tomato')。
``` ```
@Entry @Entry
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册