1# \@Styles装饰器:定义组件重用样式 2 3 4如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器\@Styles。 5 6 7\@Styles装饰器可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用。通过\@Styles装饰器可以快速定义并复用自定义样式。 8 9> **说明:** 10> 11> 从API version 9开始,该装饰器支持在ArkTS卡片中使用。 12> 13> 从API version 11开始,该装饰器支持在原子化服务中使用。 14 15## 装饰器使用说明 16 17- 当前\@Styles仅支持[通用属性](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md)和[通用事件](../reference/apis-arkui/arkui-ts/ts-universal-events-click.md)。 18 19- \@Styles可以定义在组件内或全局,在全局定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。 20 21> **说明:** 22> 23> 只能在当前文件内使用,不支持export。 24> 25> 如果想实现export功能,推荐使用[AttributeModifier](../ui/arkts-user-defined-extension-attributeModifier.md) 26 27 ```ts 28 // 全局 29 @Styles function functionName() { ... } 30 31 // 在组件内 32 @Component 33 struct FancyUse { 34 @Styles fancy() { 35 .height(100) 36 } 37 } 38 ``` 39 40如果要实现跨文件操作的功能,可以参考使用[动态属性设置](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md)。 41 42 ```ts 43 // index.ets 44 import { MyButtonModifier } from './setAttribute' 45 46 @Entry 47 @Component 48 struct AttributeDemo { 49 @State modifier: MyButtonModifier = new MyButtonModifier(); 50 51 build() { 52 Row() { 53 Column() { 54 Button("Button") 55 .attributeModifier(this.modifier) 56 .onClick(() => { 57 this.modifier.isDark = !this.modifier.isDark 58 }) 59 } 60 .width('100%') 61 } 62 .height('100%') 63 } 64 } 65 ``` 66 67 ```ts 68 // setAttribute.ets 69 export class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 70 isDark: boolean = false; 71 applyNormalAttribute(instance: ButtonAttribute): void { 72 if (this.isDark) { 73 instance.backgroundColor(Color.Black) 74 } else { 75 instance.backgroundColor(Color.Red) 76 } 77 } 78 } 79 ``` 80 81- 定义在组件内的\@Styles可以通过this访问组件的常量和状态变量,并可以在\@Styles里通过事件来改变状态变量的值,示例如下: 82 83 ```ts 84 @Entry 85 @Component 86 struct FancyUse { 87 @State heightValue: number = 100; 88 @Styles fancy() { 89 .height(this.heightValue) 90 .backgroundColor(Color.Yellow) 91 .onClick(() => { 92 this.heightValue = 200; 93 }) 94 } 95 } 96 ``` 97 98- 组件内\@Styles的优先级高于全局\@Styles。 99 框架优先找当前组件内的\@Styles,如果找不到,则会全局查找。 100 101 102## 限制条件 103 104- \@Styles方法不能有参数,编译期会报错,提醒开发者@Styles方法不支持参数。 105 106 ```ts 107 // 错误写法: @Styles不支持参数,编译期报错 108 @Styles function globalFancy (value: number) { 109 .width(value) 110 } 111 112 // 正确写法 113 @Styles function globalFancy () { 114 .width(value) 115 } 116 ``` 117 118- 不支持在\@Styles方法内使用逻辑组件,在逻辑组件内的属性不生效。 119 120 ```ts 121 // 错误写法 122 @Styles function backgroundColorStyle() { 123 if (true) { 124 .backgroundColor(Color.Red) 125 } 126 } 127 128 // 正确写法 129 @Styles function backgroundColorStyle() { 130 .backgroundColor(Color.Red) 131 } 132 ``` 133 134## 使用场景 135 136以下示例中演示了组件内\@Styles和全局\@Styles的用法。 137 138 139 140```ts 141// 定义在全局的@Styles封装的样式 142@Styles function globalFancy () { 143 .width(150) 144 .height(100) 145 .backgroundColor(Color.Pink) 146} 147 148@Entry 149@Component 150struct FancyUse { 151 @State heightValue: number = 100; 152 // 定义在组件内的@Styles封装的样式 153 @Styles fancy() { 154 .width(200) 155 .height(this.heightValue) 156 .backgroundColor(Color.Yellow) 157 .onClick(() => { 158 this.heightValue = 200 159 }) 160 } 161 162 build() { 163 Column({ space: 10 }) { 164 // 使用全局的@Styles封装的样式 165 Text('FancyA') 166 .globalFancy() 167 .fontSize(30) 168 // 使用组件内的@Styles封装的样式 169 Text('FancyB') 170 .fancy() 171 .fontSize(30) 172 } 173 } 174} 175``` 176