In HarmonyOS, ArkTS provides the ability to create custom components, allowing developers to encapsulate and reuse UI code. Below is a detailed introduction to custom components, including creating custom components, the lifecycle of pages and custom components, custom layouts for custom components, freezing functionality, and code case studies.
Creating Custom Components
Custom components are based onstruct
implemented using the@Component
decorator to identify it. Each custom component must implement thebuild()
method to describe the UI structure of the component.
@Component
struct HelloComponent {
@State message: string = 'Hello, World!';
build() {
Row() {
Text()
.onClick(() => {
= 'Hello, ArkUI!';
})
}
}
}
To use this custom component in other files, you need to use theexport
Keywords exported and used in the pageimport
Import the component .
Page and Custom Component Lifecycle
The page lifecycle is limited to pages that have been@Entry
components, and the lifecycle of a custom component is limited to the components decorated by the@Component
Decorated components.
-
onPageShow
: Triggered each time the page is displayed. -
onPageHide
: Triggered every time the page is hidden. -
onBackPress
: Triggered when the user clicks the back button. -
aboutToAppear
: Triggered when the component is about to appear. -
aboutToDisappear
: Triggered when the component is about to be destroyed.
Custom Layouts for Custom Components
If you need to layout the position of subcomponents within a custom component by measurement, you can use theonMeasureSize
cap (a poem)onPlaceChildren
Interface.
@Component
struct CustomLayout {
@Builder doNothingBuilder() {};
@BuilderParam builder: () => void = ;
@State startSize: number = 100;
result: SizeResult = { width: 0, height: 0 };
onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
let size = 100;
((child) => {
let result: MeasureResult = ({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size });
size += / 2;
});
= 100;
= 400;
return ;
}
onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
let startPos = 300;
((child) => {
let pos = startPos - ;
({ x: pos, y: pos });
});
}
build() {
();
}
}
In this example, theCustomLayout
The component is passed through theonMeasureSize
cap (a poem)onPlaceChildren
Sets the size and position of the subcomponent .
Customizing the Component Freeze Function
Starting with API version 12, the@ComponentV2
Decorated custom components support freeze functionality. The state variables will not respond to updates when the component is in an inactive state.
@Entry@ComponentV2({ freezeWhenInactive: true })
struct FirstTest {
build() {
Column() {
Text(`From first Page ${}`).fontSize(50)
Button('first page + 1').fontSize(30)
.onClick(() => {
+= 1;
})
Button('go to next page').fontSize(30)
.onClick(() => {
({ url: 'pages/Page' });
})
}
}
}
In this example, when page A jumps to page B, the state of page A changes to inactive, and updates to the component are frozen .
With these features, developers can create reusable, responsive custom components with complex layouts that enhance the development efficiency and user experience of HarmonyOS apps.
Custom Component Example: Order List Page
Suppose we need to develop a HarmonyOS application that contains an order listing page. This page will display a custom component for order items, each containing the order number, date and order status. We want this custom component to be reusable so that it can be used in other parts of the app as well.
Step 1: Create Custom Component
First, we create a file calledOrderItem
custom component, which will display detailed information about individual order items.
//
@Component
export struct OrderItem {
@Prop orderId: string;
@Prop orderDate: string;
@Prop status: string;
build() {
Row() {
Text().width(200).height(60).fontSize(16).alignItems();
Text().width(150).height(60).fontSize(14).alignItems();
Text().width(100).height(60).fontSize(14).alignItems();
}.padding(10).backgroundColor().border({ width: 1, color: });
}
}
In this component, we use the@Prop
decorator to define properties that will be passed by the parent component.build()
method defines the UI structure of the order item, using theRow
layout to horizontally align order numbers, dates, and statuses.
Step 2: Using Custom Components
Next, we use theOrderItem
component to display order data.
//
import { OrderItem } from './OrderItem';
@Entry
@Component
struct OrderList {
@State orders: Array<{ orderId: string; orderDate: string; status: string }> = [
{ orderId: '001', orderDate: '2024-04-01', status: 'Completed' },
{ orderId: '002', orderDate: '2024-04-02', status: 'Shipped' },
// More Orders...
];
build() {
Column() {
ForEach(, (order) => {
OrderItem({
orderId: ,
orderDate: ,
status: ,
});
});
}.spacing(10).padding(10);
}
}
existOrderList
component, we define a state variableorders
to store order data. In thebuild()
method, we use theForEach
loop to iterate through the array of orders, and for each order create aOrderItem
component instance, passing the appropriate properties.
elaborate
-
Definition of custom components:
OrderItem
The component is passed through the@Component
Decorator definition to make it a custom component. It accepts three properties:orderId
、orderDate
cap (a poem)status
。 -
UI Layout: in
OrderItem
(used form a nominal expression)build()
method, we use theRow
layout to horizontally align the threeText
component, which displays the order number, date, and status, respectively. EachText
Components are set with width, height, font size and alignment to ensure a neat and consistent layout. -
attribute passing:
OrderItem
The properties of the component are passed through the@Prop
defined by the decorator, which allows the parent component toOrderList
In the creation of theOrderItem
The values of these properties are passed at instance time. -
data-driven:
OrderList
Component state variablesorders
Contains order data. Use theForEach
loop, we create aOrderItem
component instance and passes the order data to it as a property. -
reusability:
OrderItem
component is reusable because it encapsulates the UI and logic of the order item that can be used in theOrderList
Used outside of the page, just pass the appropriate attributes.
Well, this example shows how to create and use custom components to build the UI of a HarmonyOS app, and how to implement data-driven UI updates through property passing and state management. Follow Wei loves programming and you'll find that in his world, coffee is the fuel, keyboard is the instrument, and code is his symphony. Whenever it's late at night, don't count the number of sheep, Wei brother counts the number of lines of code. 🌙👨💻🎶