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方法不支持参数,反例如下。
20
21  ```ts
22  // 反例: @Styles不支持参数
23  @Styles function globalFancy (value: number) {
24    .width(value)
25  }
26  ```
27
28- \@Styles可以定义在组件内或全局,在全局定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。
29
30> **说明:**
31>
32> 只能在当前文件内使用,不支持export。
33>
34> 如果想实现export功能,推荐使用[AttributeModifier](../ui/arkts-user-defined-extension-attributeModifier.md)
35
36  ```ts
37  // 全局
38  @Styles function functionName() { ... }
39
40  // 在组件内
41  @Component
42  struct FancyUse {
43    @Styles fancy() {
44      .height(100)
45    }
46  }
47  ```
48
49如果要实现跨文件操作的功能,可以参考使用[动态属性设置](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md)。
50
51  ```ts
52  // index.ets
53  import { MyButtonModifier } from './setAttribute'
54
55  @Entry
56  @Component
57  struct attributeDemo {
58    @State modifier: MyButtonModifier = new MyButtonModifier()
59
60    build() {
61      Row() {
62        Column() {
63          Button("Button")
64            .attributeModifier(this.modifier)
65            .onClick(() => {
66              this.modifier.isDark = !this.modifier.isDark
67            })
68        }
69        .width('100%')
70      }
71      .height('100%')
72    }
73  }
74  ```
75
76  ```ts
77  // setAttribute.ets
78  export class MyButtonModifier implements AttributeModifier<ButtonAttribute> {
79    isDark: boolean = false
80    applyNormalAttribute(instance: ButtonAttribute): void {
81      if (this.isDark) {
82        instance.backgroundColor(Color.Black)
83      } else {
84        instance.backgroundColor(Color.Red)
85      }
86    }
87  }
88  ```
89
90- 定义在组件内的\@Styles可以通过this访问组件的常量和状态变量,并可以在\@Styles里通过事件来改变状态变量的值,示例如下:
91
92  ```ts
93  @Component
94  struct FancyUse {
95    @State heightValue: number = 100
96    @Styles fancy() {
97      .height(this.heightValue)
98      .backgroundColor(Color.Yellow)
99      .onClick(() => {
100        this.heightValue = 200
101      })
102    }
103  }
104  ```
105
106- 组件内\@Styles的优先级高于全局\@Styles。
107  框架优先找当前组件内的\@Styles,如果找不到,则会全局查找。
108
109
110## 使用场景
111
112以下示例中演示了组件内\@Styles和全局\@Styles的用法。
113
114
115
116```ts
117// 定义在全局的@Styles封装的样式
118@Styles function globalFancy  () {
119  .width(150)
120  .height(100)
121  .backgroundColor(Color.Pink)
122}
123
124@Entry
125@Component
126struct FancyUse {
127  @State heightValue: number = 100
128  // 定义在组件内的@Styles封装的样式
129  @Styles fancy() {
130    .width(200)
131    .height(this.heightValue)
132    .backgroundColor(Color.Yellow)
133    .onClick(() => {
134      this.heightValue = 200
135    })
136  }
137
138  build() {
139    Column({ space: 10 }) {
140      // 使用全局的@Styles封装的样式
141      Text('FancyA')
142        .globalFancy()
143        .fontSize(30)
144      // 使用组件内的@Styles封装的样式
145      Text('FancyB')
146        .fancy()
147        .fontSize(30)
148    }
149  }
150}
151```
152