• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Repeat
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @liubihao-->
5<!--Designer: @keerecles-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @HelloCrease-->
8
9> **说明:**
10>
11> 本模块首批接口从API version 12开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
12
13Repeat基于数组类型数据来进行循环渲染,一般与容器组件配合使用。
14
15本文档仅为API参数说明。组件描述和使用说明见[Repeat开发者指南](../../../ui/state-management/arkts-new-rendering-control-repeat.md)。
16
17## 接口
18
19### Repeat: \<T\>(arr: Array\<T\>)
20
21**卡片能力:** 从API version 12开始,该接口支持在ArkTS卡片中使用。
22
23**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
24
25**系统能力:** SystemCapability.ArkUI.ArkUI.Full
26
27**参数:**
28
29| 参数名 | 类型       | 必填 | 说明      |
30| ------ | ---------- | -------- | -------- |
31| arr    | Array\<T\> | 是 | 数据源,为`Array<T>`类型的数组,由开发者决定数据类型。 |
32
33**示例:**
34```ts
35// arr是Array<string>类型的数组,以arr为数据源创建Repeat组件
36Repeat<string>(this.arr)
37```
38
39### Repeat: \<T\>(arr: RepeatArray\<T\>)<sup>18+</sup>
40
41> **说明:**
42>
43> 从API version 18开始,Repeat数据源支持RepeatArray类型。
44
45**卡片能力:** 从API version 18开始,该接口支持在ArkTS卡片中使用。
46
47**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
48
49**系统能力:** SystemCapability.ArkUI.ArkUI.Full
50
51**参数:**
52
53| 参数名 | 类型       | 必填 | 说明      |
54| ------ | ---------- | -------- | -------- |
55| arr    | [RepeatArray\<T\>](#repeatarrayt18) | 是 | 数据源,为`RepeatArray<T>`类型的数组,由开发者决定数据类型。 |
56
57## 属性
58
59**卡片能力:** 从API version 12开始,该接口支持在ArkTS卡片中使用。
60
61**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
62
63**系统能力:** SystemCapability.ArkUI.ArkUI.Full
64
65### each
66
67each(itemGenerator: (repeatItem: RepeatItem\<T\>) => void)
68
69组件生成函数。当所有`.template()`的type和`.templateId()`返回值不匹配时,将使用`.each()`处理数据项。
70
71> **说明**
72>
73> `each`属性必须有,否则运行时会报错。
74> `itemGenerator`的参数为`RepeatItem`,该参数将`item`和`index`结合到了一起,请勿将`RepeatItem`参数拆开使用。
75
76**卡片能力:** 从API version 12开始,该接口支持在ArkTS卡片中使用。
77
78**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
79
80**系统能力:** SystemCapability.ArkUI.ArkUI.Full
81
82**参数:**
83
84| 参数名 | 类型   | 必填 | 说明 |
85| ------ | ---------- | -------- | -------- |
86| repeatItem  | [RepeatItem](#repeatitemt)\<T\> | 否 | repeat数据项。 |
87
88**示例:**
89```ts
90// arr是Array<string>类型的数组,为每个数据创建一个Text组件
91Repeat<string>(this.arr)
92  .each((obj: RepeatItem<string>) => { Text(obj.item) })
93```
94
95### key
96
97key(keyGenerator: (item: T, index: number) => string)
98
99键值生成函数。
100
101**卡片能力:** 从API version 12开始,该接口支持在ArkTS卡片中使用。
102
103**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
104
105**系统能力:** SystemCapability.ArkUI.ArkUI.Full
106
107**参数:**
108
109| 参数名 | 类型   | 必填 | 说明  |
110| ------ | ---------- | -------- | -------- |
111| item  | T | 否 | `arr`数组中的数据项。 |
112| index  | number | 否 | `arr`数组中的数据项索引。 |
113
114**示例:**
115```ts
116// arr是Array<string>类型的数组,为每个数据创建一个Text组件
117// 并将字符串的值作为其键值
118Repeat<string>(this.arr)
119  .each((obj: RepeatItem<string>) => { Text(obj.item) })
120  .key((obj: string) => obj)
121```
122
123### virtualScroll
124
125virtualScroll(virtualScrollOptions?: VirtualScrollOptions)
126
127`Repeat`开启虚拟滚动。
128
129**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
130
131**系统能力:** SystemCapability.ArkUI.ArkUI.Full
132
133**参数:**
134
135| 参数名 | 类型   | 必填 | 说明  |
136| ------ | ---------- | -------- | -------- |
137| virtualScrollOptions  | [VirtualScrollOptions](#virtualscrolloptions)  | 否 | 虚拟滚动配置项。 |
138
139**示例:**
140```ts
141// arr是Array<string>类型的数组,为每个数据创建一个Text组件
142// 在List容器组件中使用Repeat,并打开virtualScroll
143List() {
144  Repeat<string>(this.arr)
145    .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }})
146    .virtualScroll()
147}
148```
149
150### template
151
152template(type: string, itemBuilder: RepeatItemBuilder\<T\>, templateOptions?: TemplateOptions)
153
154由template type渲染对应的template子组件。
155
156**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
157
158**系统能力:** SystemCapability.ArkUI.ArkUI.Full
159
160**参数:**
161
162| 参数名 | 类型   | 必填 | 说明  |
163| ------ | ---------- | -------- | -------- |
164| type | string | 是 | 当前模板类型。 |
165| itemBuilder  | [RepeatItemBuilder](#repeatitembuildert)\<T\> | 是 | 组件生成函数。 |
166| templateOptions | [TemplateOptions](#templateoptions对象说明) | 否 | 当前模板配置项。 |
167
168**示例:**
169```ts
170// arr是Array<string>类型的数组
171// 在List容器组件中使用Repeat,并打开virtualScroll
172// 创建模板temp,该模板为数据创建Text组件
173List() {
174  Repeat<string>(this.arr)
175    .each((obj: RepeatItem<string>) => {})
176    .virtualScroll()
177    .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }})
178}
179```
180
181### templateId
182
183templateId(typedFunc: TemplateTypedFunc\<T\>)
184
185为当前数据项分配template type。
186
187**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
188
189**系统能力:** SystemCapability.ArkUI.ArkUI.Full
190
191**参数:**
192
193| 参数名 | 类型   | 必填 | 说明  |
194| ------ | ---------- | -------- | -------- |
195| typedFunc | [TemplateTypedFunc](#templatetypedfunct)\<T\> | 是 | 生成当前数据项对应的template type。 |
196
197**示例:**
198```ts
199// arr是Array<string>类型的数组
200// 在List容器组件中使用Repeat,并打开virtualScroll
201// 创建模板temp,该模板为数据创建Text组件
202// 所有数据项都使用temp模板
203List() {
204  Repeat<string>(this.arr)
205    .each((obj: RepeatItem<string>) => {})
206    .virtualScroll()
207    .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }})
208    .templateId((item: string, index: number) => { return 'temp' })
209}
210```
211
212## RepeatArray\<T\><sup>18+</sup>
213
214type RepeatArray\<T\> = Array\<T\> | ReadonlyArray\<T\> | Readonly\<Array\<T\>\>
215
216Repeat数据源参数联合类型。
217
218**卡片能力:** 从API version 18开始,该接口支持在ArkTS卡片中使用。
219
220**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
221
222**系统能力:** SystemCapability.ArkUI.ArkUI.Full
223
224|  类型       | 说明      |
225| -------- | -------- |
226| Array\<T\> | 常规数组类型。 |
227| ReadonlyArray\<T\> | 只读数组类型,不允许数组对象变更。 |
228| Readonly\<Array\<T\>> | 只读数组类型,不允许数组对象变更。 |
229
230## RepeatItem\<T\>
231
232**卡片能力:** 从API version 12开始,该接口支持在ArkTS卡片中使用。
233
234**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
235
236**系统能力:** SystemCapability.ArkUI.ArkUI.Full
237
238| 名称 | 类型   | 必填 | 说明                                         |
239| ------ | ------ | ---- | -------------------------------------------- |
240| item   | T      | 是   | arr中每一个数据项。T为开发者传入的数据类型。 |
241| index  | number | 是   | 当前数据项对应的索引。                       |
242
243## VirtualScrollOptions
244
245**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
246
247**系统能力:** SystemCapability.ArkUI.ArkUI.Full
248
249| 名称     | 类型   | 必填 | 说明                                                         |
250| ---------- | ------ | ---- | ------------------------------------------------------------ |
251| totalCount | number | 否   | 加载的数据项总数,可以不等于数据源长度。<br>取值范围:[0, +∞)<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
252| reusable<sup>18+</sup> | boolean | 否   | 是否开启复用功能。true代表开启复用,false代表关闭复用。<br>默认值:true<br>**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 |
253| onLazyLoading<sup>19+</sup> | (index: number) => void | 否   | 数据懒加载函数,向指定的数据源index中写入数据。<br>**原子化服务API:** 从API version 19开始,该接口支持在原子化服务中使用。 |
254| onTotalCount<sup>19+</sup> | () => number | 否   | 数据项总数计算函数,返回值可以不等于数据源长度。推荐使用onTotalCount代替totalCount。同时设置totalCount与onTotalCount时,忽略totalCount。<br>取值范围:[0, +∞)<br>**原子化服务API:** 从API version 19开始,该接口支持在原子化服务中使用。 |
255
256### totalCount:期望加载的数据长度
257
258totalCount表示期望加载的数据长度,默认为原数组长度,可以大于已加载数据项的数量。arr.length表示数据源长度,以下为totalCount的处理规则:
259
260- totalCount缺省或是非自然数时,totalCount默认为arr.length,列表正常滚动。
261- 0 <= totalCount < arr.length时,界面中只渲染区间[0, totalCount - 1]范围内的数据。
262- totalCount > arr.length时,代表Repeat将渲染区间[0, totalCount - 1]范围内的数据,滚动条样式根据totalCount值变化。
263
264> **注意:**
265>
266> 当totalCount > arr.length时,在父组件容器滚动过程中,应用需要保证在列表即将滑动到数据源末尾时请求后续数据。开发者需要对数据请求的错误场景(如网络延迟)进行保护操作,直到数据源全部加载完成,否则列表滑动过程中会出现滚动效果异常。解决方案见[totalCount值大于数据源长度](../../../ui/state-management/arkts-new-rendering-control-repeat.md#totalcount值大于数据源长度)。
267
268### onLazyLoading<sup>19+</sup>:数据精准懒加载
269
270onLazyLoading从API version 19开始支持,需在懒加载场景下使用。开发者可设置自定义方法,用于向指定的数据源index中写入数据。以下为onLazyLoading的处理规则:
271
272- 在Repeat读取数据源中某一index处对应数据前,会先检查此index处是否存在数据。
273- 当不存在数据,但开发者提供了onLazyLoading方法,Repeat将调用此方法。
274- 在onLazyLoading方法中,开发者需要向Repeat指定的index中写入数据,方式如下:`arr[index] = ...`。需要注意的是,不允许使用除`[]`以外的数组操作,且不允许写入指定index以外的元素,否则系统将抛出异常。
275- onLazyLoading方法执行完成后,若指定index中仍无数据,将导致渲染异常。
276
277> **注意:**
278>
279> - 当使用onLazyLoading时,建议与onTotalCount配合使用,不建议使用totalCount。
280> - 若期望数据源长度大于实际数据源长度,推荐使用onLazyLoading。
281> - onLazyLoading方法中应避免高耗时操作。若数据加载耗时较长,建议先在onLazyLoading方法中为此数据创建占位符,再创建异步任务加载数据。
282> - 当使用onLazyLoading,并设置onTotalCount为`arr.length + 1`时,可实现数据的无限加载。需要注意,在此场景下,开发者需要提供首屏显示所需的初始数据,并建议设置父容器组件`cachedCount > 0`,否则将会导致渲染异常。若与Swiper-Loop模式同时使用,停留在`index = 0`处时将导致onLazyLoading方法被持续触发,建议避免与Swiper-Loop模式同时使用。此外,开发者需要关注内存消耗情况,避免因数据持续加载而导致内存过量消耗。
283
284### onTotalCount<sup>19+</sup>:计算期望的数据长度
285
286onTotalCount从API version 19开始支持,需在懒加载场景下使用。开发者可设置自定义方法,用于计算期望的数组长度。其返回值应当为自然数,可以不等于实际数据源长度arr.length。以下为onTotalCount的处理规则:
287
288- 当onTotalCount返回值为非自然数时,使用arr.length代替返回值,列表正常滚动。
289- 当0 <= onTotalCount返回值 < arr.length时,界面中只渲染区间[0, onTotalCount返回值 - 1]范围内的数据。
290- 当onTotalCount返回值 > arr.length时,代表Repeat将渲染区间[0, onTotalCount返回值 - 1]范围内的数据,滚动条样式根据onTotalCount返回值变化。
291
292> **注意:**
293>
294> - 相较于totalCount,Repeat可在需要时主动调用onTotalCount方法,更新期望数据长度。
295> - totalCount与onTotalCount最多设置一个。如果均未设置,则采用默认值arr.length;如果同时设置,则忽略totalCount。
296> - 当onTotalCount返回值 > arr.length时,建议配合使用onLazyLoading实现数据懒加载。
297
298### 示例
299
300```ts
301// arr是Array<string>类型的数组,在List容器组件中使用Repeat,并打开virtualScroll
302// 将加载的数据项总数设为数据源的长度,并开启复用功能
303List() {
304  Repeat<string>(this.arr)
305    .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }})
306    .virtualScroll( { totalCount: this.arr.length, reusable: true } )
307}
308
309// 假设数据项总数为100,首屏渲染需3项数据
310// 初始数组提供前3项数据(arr = ['No.0', 'No.1', 'No.2']),并开启数据懒加载功能
311List() {
312  Repeat<string>(this.arr)
313    .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }})
314    .virtualScroll({
315      onTotalCount: () => { return 100; },
316      onLazyLoading: (index: number) => { this.arr[index] = `No.${index}`; }
317    })
318}
319```
320
321## RepeatItemBuilder\<T\>
322
323type RepeatItemBuilder\<T\> = (repeatItem: RepeatItem\<T\>) => void
324
325**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
326
327**系统能力:** SystemCapability.ArkUI.ArkUI.Full
328
329**参数:**
330
331| 参数名     | 类型          | 必填      | 说明                                    |
332| ---------- | ------------- | --------------------------------------- | --------------------------------------- |
333| repeatItem | [RepeatItem](#repeatitemt)\<T\> | 否 | 将item和index结合到一起的一个状态变量。 |
334
335## TemplateOptions对象说明
336
337**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
338
339**系统能力:** SystemCapability.ArkUI.ArkUI.Full
340
341| 名称      | 类型   | 必填 | 说明                                                         |
342| ----------- | ------ | ---- | ------------------------------------------------------------ |
343| cachedCount | number | 否   | 当前template的缓存池中可缓存子组件节点的最大数量。取值范围是[0, +∞)。默认值为屏上节点与预加载节点的个数之和。当屏上节点与预加载节点的个数之和增多时,cachedCount也会对应增长。需要注意cachedCount数量不会减少。|
344
345当cachedCount值被设置为当前template在屏上显示的最大节点数量时,Repeat会做到最大程度的复用。然而当屏上没有当前template的节点时,缓存池不会释放的同时应用内存增大。需要开发者根据具体情况自行把控。
346
347- 当cachedCount缺省时,框架会分别对不同template,根据屏上节点+预加载节点的个数之和来计算cachedCount。当屏上节点+预加载节点的个数之和增多时,cachedCount也会对应增长。需要注意cachedCount数量不会减少。
348- 显式指定cachedCount,推荐设置成和屏幕上节点个数一致。需要注意,不推荐设置cachedCount小于2,因为这会导致在快速滑动场景下创建新的节点,从而造成性能劣化。
349
350> **注意:**
351>
352> 滚动容器组件属性`.cachedCount()`和Repeat组件属性`.template()`的参数`cachedCount`都是为了平衡性能和内存,但是含义是不同的。
353> - 滚动容器组件`.cachedCount()`:是指在可见范围外预加载的节点,这些节点会位于组件树上,但不是可见范围内。List/Grid等容器组件会额外渲染这些可见范围外的节点,从而达到其性能收益。Repeat会将这些节点视为“可见”的。
354> - `.template()`中的`cachedCount`: 是指Repeat视其为“不可见”的节点,这些空闲的节点框架会暂时保存,在需要使用时进行更新,从而实现复用。
355
356**示例:**
357```ts
358// arr是Array<string>类型的数组,在List容器组件中使用Repeat,并打开virtualScroll
359// 创建模板temp,该模板为数据创建Text组件,所有数据项都使用temp模板
360// 将temp模板的最大缓存节点数量设为2
361List() {
362  Repeat<string>(this.arr)
363    .each((obj: RepeatItem<string>) => {})
364    .virtualScroll()
365    .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}, { cachedCount: 2 })
366    .templateId((item: string, index: number) => { return 'temp' })
367}
368```
369
370## TemplateTypedFunc\<T\>
371
372type TemplateTypedFunc\<T\> = (item: T, index: number) => string
373
374**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
375
376**系统能力:** SystemCapability.ArkUI.ArkUI.Full
377
378**参数:**
379
380| 参数名 | 类型   | 必填 | 说明                                         |
381| ------ | ------ | ---- | -------------------------------------------- |
382| item   | T      | 否   | arr中每一个数据项。T为开发者传入的数据类型。 |
383| index  | number | 否   | 当前数据项对应的索引。                       |