1# ArkTS语法使用常见问题
2
3
4## ArkUI如何通过代码动态创建组件(API 9)
5
6**解决措施**
7
8ArkUI使用ArkTS声明式开发范式,开发者无法持有组件实例,在声明时通过渲染控制语法以及动态构建UI元素的方式,控制组件的创建。
9
10**代码示例**
11
12```
13// 条件渲染语句创建组件
14if(this.isTrue) {
15  Text("创建文本组件").fontSize(30)
16}
17// 循环渲染语句创建组件
18ForEach(this.nums,(item) => {
19  Text(item + '').fontSize(30)
20},item => JSON.stringify(item))
21```
22
23**参考链接**
24
25[渲染控制语法](../quick-start/arkts-rendering-control-overview.md)
26
27
28## 使用\@Builder装饰器包含自定义组件的方法与普通方法的区别是什么(API 9)
29
30**解决措施**
31
32\@Builder装饰的方法中使用了自定义组件,那么该方法每次被调用时,对应的自定义组件均会重新创建,普通方法中不使用\@builder装饰,无法容纳自定义组件。
33
34**参考链接**
35
36[@BuilderParam](../quick-start/arkts-builderparam.md)
37
38
39## 如何使用\@BuilderParam装饰器进行组件传参(API 9)
40
41**解决措施**
42
43- 不带参数
44
45  对\@BuilderParam修饰的属性进行赋值时不带参数(如:content: this.specificParam),则此属性的类型需定义成无返回值的函数(如:\@BuilderParam content: () => void)。
46
47- 带参数
48
49  对\@BuilderParam修饰的属性进行赋值时带参数(如:callContent: this.specificParam1("111")),则此属性的类型需定义成any(如:\@BuilderParam callContent: any)。
50
51**参考链接**
52
53[@BuilderParam](../quick-start/arkts-builderparam.md)
54
55
56## 如何监听数组内对象属性变化(API 9)
57
58**问题现象**
59
60数组内存储对象示例,需要对对象的属性变化进行监听。
61
62**解决措施**
63
64通过\@Observed配合\@ObjectLink装饰符实现。\@Observed用于类,\@ObjectLink用于变量。
65
66**代码示例**
67
681. 在类上使用\@Observed。
69
70   ```
71   @Observed
72   class ClassA {
73     public name: string
74     public c: number
75     public id: number
76
77     constructor(c: number, name: string = 'OK') {
78       this.name = name
79       this.c = c
80     }
81   }
82   ```
83
842. 在组件变量使用\@ObjectLink。
85
86   ```
87   @Component
88   struct ViewA {
89     label: string = 'ViewA1'
90     @ObjectLink a: ClassA
91
92     build() {
93       Row() {
94         Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`)
95           .onClick(() => {
96             this.a.c += 1
97           })
98       }.margin({ top: 10 })
99     }
100   }
101   ```
102
103**参考链接**
104
105[Observed和ObjectLink数据管理](../quick-start/arkts-observed-and-objectlink.md)
106
107
108## 子组件使用\@Link修饰成员变量时,如何通过父组件传值(API 9)
109
110**解决措施**
111
112子组件使用\@Link接受父组件的值时,需要使用'$'建立变量之间的引用关系。才能实现同步。
113
114**代码示例**
115
116\@Link语义是从'$'操作符引出,即$isPlaying是this.isPlaying内部状态的双向数据绑定。当单击子组件PlayButton中的按钮时,\@Link变量更改,PlayButton与父组件中的Text和Button将同时进行刷新,同样地,当点击父组件中的Button修改this.isPlaying时,子组件PlayButton与父组件中的Text和Button也将同时刷新。
117
1181. 在父组件使用\@State装饰器,传递数据使用$符创建引用。
119
120   ```
121   @Entry
122   @Component
123   struct Player {
124     @State isPlaying: boolean = false
125     build() {
126       Column() {
127         PlayButton({ buttonPlaying: $isPlaying })
128         Text(`Player is ${this.isPlaying ? '' : 'not'} playing`).fontSize(18)
129         Button('Parent:' + this.isPlaying)
130           .margin(15)
131           .onClick(() => {
132             this.isPlaying = !this.isPlaying
133           })
134       }
135     }
136   }
137
138   ```
139
1402. 在子组件使用\@Link接受数据。
141
142   ```
143   @Component
144   struct PlayButton {
145     @Link buttonPlaying: boolean
146
147     build() {
148       Column() {
149         Button(this.buttonPlaying ? 'pause' : 'play')
150           .margin(20)
151           .onClick(() => {
152             this.buttonPlaying = !this.buttonPlaying
153           })
154       }
155     }
156   }
157   ```
158
159**参考链接**
160
161[@Link](../quick-start/arkts-link.md)
162
163
164## 父组件如何与孙子组件进行状态同步(API 9)
165
166**解决措施**
167
168- 方式一(推荐):使用\@Provide和\@Consume装饰器。在父组件使用\@Provide,在孙子组件使用\@Consume,可以实现父组件和孙子组件进行双向数据绑定。
169
170- 方式二:使用\@State和\@Link装饰器。在父组件使用\@State,在每一层子组件(子组件和孙子组件)都使用\@Link。
171
172**代码示例一**
173
1741. 父组件中使用子组件,通过Provide提供reviewVote参数,供跨级传递给孙子组件。
175
176   ```
177   @Entry
178   @Component
179   struct Father{
180     @Provide("reviewVote") reviewVotes: number = 0;
181
182     build() {
183       Column() {
184         Son()
185         Button(`Father: ${this.reviewVotes}`)
186           ...
187       }
188     }
189   }
190   ```
191
1922. 子组件中使用孙组件。
193
194   ```
195   @Component
196   struct Son{
197     build() {
198       Column() {
199         GrandSon()
200       }
201     }
202   }
203   ```
204
2053. 孙子组件中使用Consume来接受reviewVote的参数。
206
207   ```
208   @Component
209   struct GrandSon{
210     @Consume("reviewVote") reviewVotes: number
211
212     build() {
213       Column() {
214         Button(`GrandSon: ${this.reviewVotes}`)
215           ...
216       }.width('100%')
217     }
218   }
219   ```
220
221**代码示例二**
222
2231. 父组件Father使用\@State绑定数据reviewVote。
224
225   ```
226   @Entry
227   @Component
228   struct Father {
229     @State reviewVotes: number = 0;
230
231     build() {
232       Column() {
233         Son({reviewVotes:$reviewVotes})
234         Button(`Father: ${this.reviewVotes}`)
235           ...
236       }
237     }
238   }
239   ```
240
2412. 子组件Son中使用\@Link接受由父组件Father传递的参数reviewVote。
242
243   ```
244   @Component
245   struct Son{
246     @Link reviewVotes: number;
247     build() {
248       Column() {
249         Grandson({reviewVotes:$reviewVotes})
250       }
251     }
252   }
253
254   ```
255
2563. 孙子组件GrandSon使用\@Link接受由Son组件传递的参数reviewVote。
257
258   ```
259   @Component
260   struct Grandson{
261     @Link reviewVotes: number;
262
263     build() {
264       Column() {
265         Button(`Grandson: ${this.reviewVotes}`)
266           ...
267       }.width('100%')
268     }
269   }
270   ```
271
272
273## Js如何定义callback函数(API 9)
274
275**解决措施**
276
277定义个callback函数的样例,**示例如下:**
278
2791. 定义回调函数
280
281   ```
282   // 页面中定义个2个参数,空返回的callback函数
283   myCallback: (a:number,b:string) => void
284   ```
285
2862. 在使用时进行初始化赋值
287
288   ```
289   aboutToAppear() {
290     // callback函数初始化
291     this.myCallback= (a,b)=>{
292       console.info(`handle myCallback a=${a},b=${b}`)
293     }}
294   ```
295
296
297## 组件需要多次更新时如何优化性能(API 9)
298
299**解决措施**
300
301使用状态管理模块,目前已经支持最小化更新,当数据依赖变化时,不再是重新刷新整个自定义组件,而是只更新依赖数据的视图内容。
302
303
304## 对象中函数的this如何指向外层(API 9)
305
306**解决措施**
307
308通过箭头函数实现。
309
310**代码示例**
311
312```
313const obj = {
314  start:() => {
315    return this.num
316  }
317}
318```
319
320
321## 如何实现页面加载前从接口获取数据(API 9)
322
323**问题现象**
324
325页面生命周期相关问题,在页面渲染前从接口获取数据,渲染时将数据渲染到页面上。
326
327**解决措施**
328
329在声明周期函数aboutToAppear中使用异步接口获取页面数据,数据变量使用\@State修饰,数据获取完成后根据变量自动刷新页面。
330
331**代码示例**
332
333```
334@Entry
335@Component
336struct Test6Page {
337  // 数据获取成功,会自动刷新页面
338  @State message: string = 'loading.....'
339  aboutToAppear(){
340    // 模拟异步接口获取数据
341    setTimeout(()=>{
342      this.message = 'new msg'
343    },3000)
344  }
345  build() {
346    Row() {
347      Column() {
348        Text(this.message)
349          .fontSize(50)
350          .fontWeight(FontWeight.Bold)
351      }
352      .width('100%')
353    }
354    .height('100%')
355  }
356}
357```
358
359
360## 如何将传感器的数据实时显示在UI的Text中(API 9)
361
362**解决措施**
363
364传感器返回数据类型为double,可将double转为string,再显示在text中。
365
366
367## 如何监听屏幕旋转(API 9)
368
369**解决措施**
370
371屏幕旋转可使用媒体查询接口进行监听。
372
373```
374import mediaquery from '@ohos.mediaquery'
375let listener = mediaquery.matchMediaSync('(orientation: landscape)'); //监听横屏事件
376function onPortrait(mediaQueryResult) {
377  if (mediaQueryResult.matches) {
378   // do something here
379  } else {
380   // do something here
381  }
382}
383listener.on('change', onPortrait) // 注册回调
384listener.off('change', onPortrait) // 去注册回调
385```
386
387**参考链接**
388
389[媒体查询](../reference/apis-arkui/js-apis-mediaquery.md)
390
391
392## 创建的单例换了页面后不生效问题(API 9)
393
394**问题现象**
395
396单例只有在同一个流程中才有效,换了页面后之前的实例都全是undefined。
397
398**解决措施**
399
400对于每个Page都会生成一个js文件,定义的单例会在每个js中都生成一份,所以单例的作用范围只是Page的范围。
401
402如果想共享一个实例,创建范围需要提升至UIAbility或者App级别。
403
404
405## 如何将时间格式的字符串string转换为Date对象(API 9)
406
407**解决措施**
408
409如果字符string满足格式“yyyy-MM-dd”格式,则可直接使用函数new Date("yyyy-MM-dd")来获取对应的Date对象。
410
411```
412new Date("2021-05-23");
413new Date("2020/2/29");
414new Date("2020-14-03");
415new Date("14-02-2021");
416```
417
418其他格式字符串可使用new Date(year:number,month:number,day?:number,hour?:number,mintue?:number,second?:number,ms?:number)方法来获取Date对象。
419
420```
421// 根据参数创建日期的语法:
422new Date(yearValue, IndexOfMonth, dayValue, hours, minutes, seconds)
423```
424
425其中每一个参数换算为对应时间参数传入即可。
426
427- yearValue:应符合 ISO 8061 YYYY 格式。例如 2021。如果我们以 YY 格式指定一个值,它将会被错误地接受。例如,仅将 2021 提到 21 会被认为是 1921 年而不是 2021 年。
428
429- IndexOfMonth:从索引 0 开始。因此,从 Month 值中减去 1。例如,对于 3 月,该值为 3,但 monthIndex 将为 2(即 3-1 = 2)。本月指数通常应在 0-11 范围内
430
431- dayValue:表示一个月中的某天。它应在 1-31 范围内,具体取决于一个月中的天数。例如:对于 21-05-2021,日期值为 21
432
433- hours:一天中的小时。例如 10 点。
434
435- minutes:过去一个小时的分钟数
436
437- seconds:保留超过一分钟的秒数。
438
439
440## ArkTS如何把string转为byte数组(API 9)
441
442**解决措施**
443
444参考如下代码实现,示例:
445
446```
447stringToArray(str:string) {
448  var arr = [];
449  for(var i = 0,j = str.length;i<j;++i) {
450 arr.push(str.charCodeAt(i))
451  }
452  return arr;
453}
454```
455
456
457## ArkTS如何实现字符串编解码(API 9)
458
459**解决措施**
460
461通过util工具函数模块中的TextEncoder和TextDecoder进行解码。
462
463**参考链接**
464
465[TextEncoder](../reference/apis-arkts/js-apis-util.md#textencoder)、[TextDecoder](../reference/apis-arkts/js-apis-util.md#textdecoder)
466
467
468## 如何导入和导出namespace命名空间(API 9)
469
470**解决措施**
471
472通过export和import导入导出
473
474- namespace导数据库出
475
476  ```
477  namespace Util{
478      export function getTime(){
479          return Date.now()
480      }
481  }
482  export default Util
483  ```
484
485- namespace导入
486
487  ```
488  import Util from './util'
489  Util.getTime()
490  ```
491
492
493## worker线程中能否进行关系型数据库的操作(API 9)
494
495当前不支持将UI主线程中的rdb数据库对象发送给Worker线程后进行操作。Worker线程中使用rdb数据库,需要重新获取rdb数据库的对象。
496
497
498## 如何获取应用resource目录下的文件(API 9)
499
500**解决措施**
501
502- 方式一:使用$r或者$rawfile访问。适合静态访问,程序运行时不改变资源路径。
503
504- 方式二:使用ResourceManage访问。适合动态访问,程序运行时可动态改变资源路径。
505
506**参考链接**
507
508[资源访问](../quick-start/resource-categories-and-access.md)与[资源管理](../reference/apis-localization-kit/js-apis-resource-manager.md)
509
510
511## XML格式如何转为JSON格式(API 9)
512
513**问题现象**
514
515服务端返回的数据是通过base64编码后XML格式,需要转为JSON格式进行后续的处理。
516
517**解决措施**
518
519使用util工具中的base64相关接口进行解码操作,然后使用convertxml组件解析XML格式数据。
520
521**代码示例**
522
523```
524import convertxml from '@ohos.convertxml';
525import util from '@ohos.util';
526
527@Entry
528@Component
529struct Faq_4_31 {
530  @State message: string = 'base64转json'
531
532  build() {
533    Row() {
534      Column() {
535        Text(this.message)
536          .fontSize(50)
537          .fontWeight(FontWeight.Bold)
538          .onClick(() => {
539            /* 原数据,GBK编码
540            <?xml version="1.0" encoding="GBK"?>
541            <data>
542            <asset_no>xxxxx</asset_no>
543            <machine_sn>xxxx</machine_sn>
544            <bios_id>xxxx</bios_id>
545            <responsible_emp_name><![CDATA[xxxx]]></responsible_emp_name>
546            <responsible_account><![CDATA[xxxx xxxx]]></responsible_account>
547            <responsible_emp_no>xxxx</responsible_emp_no>
548            <responsible_dept><![CDATA[xxxx]]></responsible_dept>
549            <user_dept><![CDATA[xxxx]]></user_dept>
550            <user_name><![CDATA[xxx]]></user_name>
551            <cur_domain_account>xxxx</cur_domain_account>
552            <asset_loc><![CDATA[--]]></asset_loc>
553            <asset_loc_cur><![CDATA[]]></asset_loc_cur>
554            <asset_type>1</asset_type>
555            <asset_use>For Outsourcing Staff/xxxx</asset_use>
556            <overdue_date></overdue_date>
557            <asset_status>xxxx</asset_status>
558            <asset_period>xxxx</asset_period>
559            <license></license>
560            </data>
561             */
562            let src = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIj8+CjxkYXRhPgo8YXNzZXRfbm8+eHh4eHg8L2Fzc2V0X25vPgo8bWFjaGluZV9zbj54eHh4PC9tYWNoaW5lX3NuPgo8Ymlvc19pZD54eHh4PC9iaW9zX2lkPgo8cmVzcG9uc2libGVfZW1wX25hbWU+PCFbQ0RBVEFbeHh4eF1dPjwvcmVzcG9uc2libGVfZW1wX25hbWU+CjxyZXNwb25zaWJsZV9hY2NvdW50PjwhW0NEQVRBW3h4eHggeHh4eF1dPjwvcmVzcG9uc2libGVfYWNjb3VudD4KPHJlc3BvbnNpYmxlX2VtcF9ubz54eHh4PC9yZXNwb25zaWJsZV9lbXBfbm8+CjxyZXNwb25zaWJsZV9kZXB0PjwhW0NEQVRBW3h4eHhdXT48L3Jlc3BvbnNpYmxlX2RlcHQ+Cjx1c2VyX2RlcHQ+PCFbQ0RBVEFbeHh4eF1dPjwvdXNlcl9kZXB0Pgo8dXNlcl9uYW1lPjwhW0NEQVRBW3h4eF1dPjwvdXNlcl9uYW1lPgo8Y3VyX2RvbWFpbl9hY2NvdW50Pnh4eHg8L2N1cl9kb21haW5fYWNjb3VudD4KPGFzc2V0X2xvYz48IVtDREFUQVstLV1dPjwvYXNzZXRfbG9jPgo8YXNzZXRfbG9jX2N1cj48IVtDREFUQVtdXT48L2Fzc2V0X2xvY19jdXI+Cjxhc3NldF90eXBlPjE8L2Fzc2V0X3R5cGU+Cjxhc3NldF91c2U+Rm9yIE91dHNvdXJjaW5nIFN0YWZmL3h4eHg8L2Fzc2V0X3VzZT4KPG92ZXJkdWVfZGF0ZT48L292ZXJkdWVfZGF0ZT4KPGFzc2V0X3N0YXR1cz54eHh4PC9hc3NldF9zdGF0dXM+Cjxhc3NldF9wZXJpb2Q+eHh4eDwvYXNzZXRfcGVyaW9kPgo8bGljZW5zZT48L2xpY2Vuc2U+CjwvZGF0YT4='
563            let base64 = new util.Base64Helper();
564            // base解码
565            let src_uint8Array = base64.decodeSync(src);
566            // 解码为utf-8的字符串
567            let textDecoder = util.TextDecoder.create("utf-8",{ignoreBOM: true})
568            let src_str = textDecoder.decodeWithStream(src_uint8Array)
569            //替换encoding字段
570            src_str = src_str.replace("GBK","utf-8")
571            console.log('Test src_str: ' + JSON.stringify(src_str));
572            // 转换 xml-> json
573            let conv = new convertxml.ConvertXML();
574            let options = {trim : false, declarationKey:"_declaration",
575              instructionKey : "_instruction", attributesKey : "_attributes",
576              textKey : "_text", cdataKey:"_cdata", doctypeKey : "_doctype",
577              commentKey : "_comment", parentKey : "_parent", typeKey : "_type",
578              nameKey : "_name", elementsKey : "_elements"}
579            let src_json = JSON.stringify(conv.convertToJSObject(src_str, options));
580            console.log('Test json: ' + JSON.stringify(src_json));
581          })
582      }
583      .width('100%')
584    }
585    .height('100%')
586  }
587}
588```
589
590
591## 在生成器函数中编译TS语言有哪些使用限制(API 9)
592
593**解决措施**
594
595TS语言的使用在生成器函数中存在以下限制:
596
597- 表达式仅允许在字符串(${expression})、if条件、ForEach的参数和组件的参数中使用。
598
599- 这些表达式中的任何一个都不能导致任何应用程序状态变量(\@State、\@Link、\@Prop)的改变,否则会导致未定义和潜在不稳定的框架行为。
600
601- 生成器函数内部不能有局部变量。
602
603上述限制都不适用于事件处理函数(例如onClick)的匿名函数实现。
604
605
606## 如何设置一张图片上面四个角都分别有一个角标(API 9)
607
608**问题现象**
609
610应用需求,在一张图片上面四个角分别设置一个角标。
611
612**解决措施**
613
614可以使用绝对定位,设置元素锚点相对于父容器顶部起点的偏移位置。在布局容器中,设置该属性不影响父容器布局。
615
616示例:
617
618```
619@Entry
620@Component
621struct PositionExample2 {
622  build() {
623    Column({ space: 20 }) {
624      Stack({ alignContent: Alignment.TopStart }) {
625        Row()
626          .size({ width: '100', height: '100' })
627          .backgroundColor(0xdeb887)
628        Image($r('app.media.app_icon'))
629          .size({ width: 25, height: 25 })
630          .markAnchor({ x: 0, y: 0 })
631        Image($r('app.media.app_icon'))
632          .size({ width: 25, height: 25 })
633          .markAnchor({ x: 25, y: 25 })
634          .position({ x: '100%', y: '100%' })
635      }.margin({ top: 25 }).width('100').height('100')
636    }
637    .width('100%').margin({ top: 25 })
638  }
639}
640```
641
642
643## util.generateRandomUUID参数问题(API 9)
644
645**解决措施**
646
647generateRandomUUID底层使用Node.js crypto.randomUUID()接口,传递参数为false时会生成uuid,并缓存到系统里,参数为true时使用系统已缓存的UUID。
648
649**参考链接**
650
651参考文档:[util.generateRandomUUID](../reference/apis-arkts/js-apis-util.md#utilgeneraterandomuuid9)
652
653
654## worker线程与主线程是否运行在相同的全局上下文中(API 9)
655
656**解决措施**
657
658worker线程与主线程不在同一个上下文中,它们使用数据通信的方式交互。
659
660**参考链接**
661
662worker:[启动一个Worker](../reference/apis-arkts/js-apis-worker.md)
663
664
665## 应用图标一多设置(API 9)
666
667**问题现象**
668
669希望可以按照设备的不同类型,显示相应的应用图标
670
671**解决措施**
672
673借助资源限定词能力,可以实现应用图标的一多配置
674
675**示例代码**
676
6771.创建资源目录,并在资源目录中添加资源文件,以Tablet为例,在src/main/resources下创建tablet资源目录,在tablet目录下创建media资源文件夹
678
679```
680├─base
681│  ├─element
682│  ├─media
683│  └─profile
684├─rawfile
685├─tablet
686│  ├─element
687│  └─media
688```
689
6902.在1中创建的media文件夹下添加设备类型为tablet时希望显示的图标文件,在UI界面进行引用
691
692```
693@Entry @Component struct Index { build() {
694   Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
695     Text($r("app.string.my_string"))
696       .fontSize($r("app.float.my_float"))
697       .fontColor($r("app.color.my_color"))
698     Image($r("app.media.my_image"))
699       .width(100)
700       .height(100)
701   }
702   .width('100%')
703   .height('100%') } }
704```
705
706**参考链接**
707
708[资源使用](../key-features/multi-device-app-dev/resource-usage.md)
709
710
711## 调用方法的时候,如何解决方法内部的this变成undefined(API 9)
712
713**问题现象**
714
715ArkTS里的this指向
716
717**解决措施**
718
719方式一:在调用方法的时候加上.bind(this);
720
721方式二:使用箭头函数。
722
723
724## systemTime.getCurrentTime()接口和JS的new Date().getTime()有区别吗(API 9)
725
726**解决措施**
727
728systemTime.getCurrentTime(false)和new Date().getTime()一样,都是返回1970年1月1日至今的毫秒数;systemTime.getCurrentTime(true)返回1970年1月1日至今的纳秒数。两种方式都是系统时间。
729
730
731## 如何实现类似js中的slot插槽功能(API 9)
732
733**解决措施**
734
735该功能在ArkTS中使用\@Build和\@BuilderParam方式来实现。
736
737**参考链接**
738
739[@BuilderParam装饰器:引用@Builder函数](../quick-start/arkts-builderparam.md)
740
741
742## 加上lineHeight,Text垂直不居中的原因(API 9)
743
744**原因分析**
745
746Text组件不用设置lineHeight属性,默认就是居中的。绘制文本是从底部开始绘制的,设置合适的lineHeight可以让文本有居中效果,但如果lineHeight设置的过高,文本就会显得偏下一些,一般lineHeight属性用来联合padding属性调整Text内的上下行间距。
747
748**参考链接**
749
750[Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#示例1)
751
752
753## 使用什么接口进行url编码(API 9)
754
755**解决措施**
756
757使用全局函数encodeURI进行编码,使用decodeURI进行解码。例如空格字符““,编码后为%20。
758
759```
760let a = encodeURI(" ")
761console.log(a) // %20
762```
763
764
765## 如何解析xml(API 9)
766
767**解决措施**
768
769使用ConvertXML的convert接口可以将xml文本解析为JavaScript对象。
770
771**参考链接**
772
773[转换xml](../reference/apis-arkts/js-apis-convertxml.md)
774
775
776## 使用Styles装饰器,编译报错.stateStyles doesn't conform standard(API 9)
777
778**原因分析**
779
780Styles装饰器内部只支持通用属性,使用了非通用属性作为Style的代码
781
782**解决措施**
783
784去掉非通用属性,或者使用Builder来提取公共组件。
785
786
787## Radio组件$$双向绑定(API 9)
788
789**解决措施**
790
791Radio组件使用$$绑定的变量变更时,仅渲染当前组件,提高渲染速度。
792
793当Radio组件的状态发生改变时,不会自动修改绑定的变量。
794
795**参考链接**
796
797[内置组件双向同步](../quick-start/arkts-two-way-sync.md)
798
799## ForEach组件在真机上无法执行(API 9)
800
801**问题现象**
802
803ForEach组件预览器可以正常执行,但在真机上无法执行。
804
805**原因分析**
806
807真机上系统版本大于等于3.2beta5版本,真机会默认开启最小化更新策略。
808
809旧版IDE默认没有开启最小化更新,导致组件运行异常。
810
811**解决措施**
812
813module.json5添加"metadata"配置项:
814
815```
816{
817  "module": {
818    "metadata": [
819      {
820        "name": "ArkTSPartialUpdate",
821        "value": "true"
822      } ]
823  }
824}
825```
826
827## AppStorage是不是不支持线程间共享对象,为什么,推荐替代方案是什么(API 10)
828
829**解决措施**
830
831AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。
832
833AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。
834
835AppStorage是UI相关的数据,需要运行在UI线程,无法将对象共享到其他线程。目前暂无替代方案。
836
837**参考链接**
838
839[AppStorage:应用全局的UI状态存储](../quick-start/arkts-appstorage.md)
840
841## 自定义字体的注册方式有哪些,推荐的字体资源存放路径是哪里,如何从资源存放路径中取出字体资源(API 10)
842
843**解决措施**
844
845在工程中存放开发者自定义字体资源文件,代码中通过registerFont接口进行自定义字体注册,便可以在文本组件中使用fontFamily属性使用。
846推荐使用$rawfile方式引用自定义字体资源,资源可放在resources/rawfile目录下。
847
848**参考链接**
849
850[@ohos.font (注册自定义字体)](../reference/apis-arkui/js-apis-font.md)
851
852## Text组件如何加载Unicode字符(API 10)
853
854**解决措施**
855
856在Text组件入参content中使用字符串,在字符串中转义Unicode编码,示例代码如下:
857
858```ts
859@Entry
860@Component
861struct text {
862  build() {
863  Column(){
864    Text("\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F466}")
865      .width(100)
866      .height(100)
867      .fontSize(50)
868  }
869  }
870}
871```
872
873## 类似js中的slot插槽功能在ArkTS中如何实现(API 10)
874
875**解决措施**
876
877ArkUI还提供了一种更轻量的UI元素复用机制@Builder,@Builder所装饰的函数遵循build()函数语法规则,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用;
878另外,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符。
879参考@Builder 和@BuilderParam。
880
881**参考链接**
882
8831. [@Builder装饰器:自定义构建函数](../quick-start/arkts-builder.md)
8842. [@BuilderParam装饰器:引用@Builder函数](../quick-start/arkts-builderparam.md)