ArkUI 学习之$$语法
✨ $$绑定的变量变化时,会触发UI的同步刷新。
🐹 用法一:内置组件双向同步
🔊:$$运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。顾名思义:就是说有些系统内置组件参数,传入状态变量时,需要在前面添加“$$”运算符才能行。
⚠️:内部状态具体指什么取决于组件。例如,TextInput组件的text参数。顾名思义:就是说不是所有系统的内置组件参数,传入状态变量时,都要在传入的状态变量前加“$$”运算符。哪些需要加,哪些不需要,华为系统API给列举了。
1. 使用规则
当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
当前$$支持的组件:
2. 使用示例
@Entry @Component struct TextInputPage { /** ! 状态变量 */ @State text: string = '' /** ! 普通变量 */ private controller: TextInputController = new TextInputController() /** ! 构建函数 */ build() { Column() { /** $$不支持的组件,所以不需要加 $$ */ Text(this.text) /** $$支持的组件,所以需要加 $$ */ TextInput({ text: $$this.text, placeholder: "input your word...", controller: this.controller }) .placeholderColor(Color.Grey) .placeholderFont({ size: 14, weight: 500 }) .caretColor(Color.Blue) .width(300) }.width('100%').height('100%') } }
❗️总结:感觉$$的用法,给Vue中的v-model指令有点类似。
🐹 用法二:@Builder装饰器的按引用传递参数
🔊 :在@builder装饰的自定义构建函数,传递状态变量参数时,需要通过按引用传递参数,才能在状态变量改变时,刷新内部UI,不然不能刷新。
顾名思义:我们需通过$$作为变量名的形式参数,来接受状态变量。这样才能在状态变量改变时,刷新@builder 内部的UI,不然不刷新@builder内部UI。
1. 按引用传递参数
🔊:按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。ArkUI提供$$作为按引用传递参数的范式。
@Entry @Component struct TextInputPage { /** ! 状态变量 */ @State text: string = '' /** ! 普通变量 */ private controller: TextInputController = new TextInputController() /** ! 构建函数 */ build() { Column() { /** 传入状态变量 */ textBuilder({ param1: this.text }) /** $$支持的组件,所以需要加 $$ */ TextInput({ text: $$this.text, placeholder: "input your word...", controller: this.controller }) .placeholderColor(Color.Grey) .placeholderFont({ size: 14, weight: 500 }) .caretColor(Color.Blue) .width(300) }.width('100%').height('100%') } } /** ! 全局自定义构建函数 */ //定义 $$ 参数类型 interface GeneratedTypeLiteralInterface_1 { param1: string; } //使用 $$ 作为形式参数 //这个时候就是按引用传递,不这样就是按值传递 @Builder function textBuilder($$: GeneratedTypeLiteralInterface_1) { Text($$.param1) }
2. 按值传递参数
🔊:用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。
@Entry @Component struct TextInputPage { /** ! 状态变量 */ @State text: string = '' /** ! 普通变量 */ private controller: TextInputController = new TextInputController() /** ! 构建函数 */ build() { Column() { /** 传入状态变量 */ textBuilder(this.text) /** $$支持的组件,所以需要加 $$ */ TextInput({ text: $$this.text, placeholder: "input your word...", controller: this.controller }) .placeholderColor(Color.Grey) .placeholderFont({ size: 14, weight: 500 }) .caretColor(Color.Blue) .width(300) }.width('100%').height('100%') } } /** ! 全局自定义构建函数 */ //不使用 $$ 作为形式参数,这个时候就是按值传递 @Builder function textBuilder(text: string) { Text(text) }
❗️总结:
1. 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
2. 在自定义构建函数内部,不允许改变参数值。如果需要改变参数值,且同步回调用点,建议使用@Link。
3. 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。