鸿蒙中 @Styles装饰器:样式复用
摘要:HarmonyOS的@Styles装饰器是提升应用开发效率的样式复用工具,支持API version 9+。它允许将通用属性和事件封装为方法,通过组件内定义(优先级高)或全局定义实现样式复用。主要特点包括:支持访问组件状态变量、组合多个样式、封装事件处理,但不支持参数传递、逻辑语句和跨文件导出。与AttributeModifier相比,@Styles更适合单文件内的简单样式复用。开发时应注意
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
在HarmonyOS应用开发中,随着项目规模扩大,重复的样式设置会导致代码臃肿、维护困难。@Styles装饰器应运而生,它能够将多条样式设置提炼成一个方法,实现样式的快速定义和复用。
一、@Styles装饰器
@Styles装饰器是HarmonyOS提供的一种样式复用机制,允许将多个样式属性封装成一个方法,在组件声明位置直接调用,从而减少重复代码,提高开发效率。
支持版本
| 版本 | 支持范围 |
|---|---|
| API version 9 | 开始支持 |
| API version 9+ | 支持在ArkTS卡片中使用 |
| API version 11+ | 支持在元服务中使用 |
二、装饰器使用说明
2.1 支持范围
@Styles装饰器仅支持以下两类内容:
1. 通用属性
-
所有组件通用的属性,如宽高、背景色、边距等
2. 通用事件
-
所有组件通用的事件,如点击事件、触摸事件等
2.2 定义方式
@Styles有两种定义方式:组件内定义和全局定义。
| 定义位置 | 语法要求 | 使用范围 |
|---|---|---|
| 组件内 | 不需要function关键字 | 当前组件内使用 |
| 全局 | 需要在方法名前加function关键字 | 当前文件内使用 |
2.3 优先级规则
-
组件内@Styles优先级高于全局@Styles
-
框架查找顺序:先找当前组件内的@Styles → 找不到则全局查找
提示:@Styles只能在当前文件内使用,不支持export导出。如果需要实现样式导出,推荐使用AttributeModifier。
三、使用示例
3.1 基础用法示例
@Entry
@Component
struct FancyUse {
@State heightValue: number = 50;
// 组件内定义@Styles
@Styles
fancy() {
.height(this.heightValue)
.backgroundColor(Color.Blue)
.onClick(() => {
this.heightValue = 100;
})
}
build() {
Column() {
Button('change height')
.fancy() // 调用组件内样式
}
.height('100%')
.width('100%')
}
}
效果:
-
按钮初始高度为50,背景色为蓝色
-
点击按钮后,高度变为100
-
展示了@Styles中可以使用状态变量和事件
3.2 组件内与全局样式对比示例
// 定义在全局的@Styles封装的样式
@Styles
function globalFancy1() {
.width(150)
.height(100)
.backgroundColor(Color.Pink)
}
@Entry
@Component
struct GlobalFancy {
@State heightValue: number = 100;
// 定义在组件内的@Styles封装的样式
@Styles
fancy() {
.width(200)
.height(this.heightValue)
.backgroundColor(Color.Gray)
.onClick(() => {
this.heightValue = 200;
})
}
build() {
Column({ space: 10 }) {
// 使用全局的@Styles封装的样式
Text('FancyA')
.globalFancy1() // 调用全局样式
.fontSize(30)
// 使用组件内的@Styles封装的样式
Text('FancyB')
.fancy() // 调用组件内样式
.fontSize(30)
}
.width('100%')
}
}
效果对比:
-
FancyA:粉色背景,固定150*100尺寸,无交互
-
FancyB:灰色背景,宽度200,高度初始100,点击后变为200
四、限制条件
4.1 不支持参数传递
@Styles方法不能定义参数,这是最重要的限制条件。
// 错误:@Styles不支持参数,编译期报错
@Styles
function globalFancy(value: number) {
.width(value)
}
// 正确写法:必须使用固定值
@Styles
function globalFancy() {
.width(100)
}
// 组件内同样不支持参数
@Styles
fancy(value: number) { // 编译错误
.width(value)
}
// 组件内正确写法
@Styles
fancy() {
.width(100)
}
4.2 不支持逻辑组件
@Styles方法内不能使用条件语句、循环等逻辑组件。
// 错误写法:不能在@Styles内使用if语句
@Styles
function backgroundColorStyle() {
if (true) {
.backgroundColor(Color.Red)
}
}
// 正确写法:直接设置样式
@Styles
function backgroundColorStyle() {
.backgroundColor(Color.Red)
}
// 错误示例:也不能使用switch、for等
@Styles
function multipleStyles() {
for (let i = 0; i < 10; i++) { // 编译错误
.width(100)
}
}
4.3 其他限制
-
不支持导出(export)
-
只能定义在当前文件内使用
-
方法体内只能包含样式属性和事件
五、进阶使用
5.1 访问组件状态
组件内的@Styles可以通过this访问组件的常量和状态变量:
@Entry
@Component
struct StatefulStyle {
@State fontSizeValue: number = 16
@State colorValue: Color = Color.Blue
@Styles
dynamicStyle() {
.fontSize(this.fontSizeValue)
.fontColor(this.colorValue)
.onClick(() => {
this.fontSizeValue = 20
this.colorValue = Color.Red
})
}
build() {
Column() {
Text('点击改变样式')
.dynamicStyle()
}
}
}
5.2 组合多个样式
@Styles
function baseStyle() {
.width('100%')
.padding(10)
.margin(5)
}
@Styles
function themeStyle() {
.backgroundColor('#f5f5f5')
.borderRadius(8)
.border({ width: 1, color: '#e0e0e0' })
}
@Entry
@Component
struct CombinedStyles {
build() {
Column() {
Text('组合样式示例')
.baseStyle()
.themeStyle()
.fontSize(20)
}
}
}
5.3 事件处理封装
@Entry
@Component
struct EventStyleDemo {
@State count: number = 0
@Styles
interactiveStyle() {
.padding(10)
.backgroundColor('#0077FF')
.borderRadius(5)
.onClick(() => {
this.count++
console.log('点击次数:' + this.count)
})
.onTouch((event) => {
if (event.type === TouchType.Down) {
this.backgroundColor('#0055CC')
} else if (event.type === TouchType.Up) {
this.backgroundColor('#0077FF')
}
})
}
build() {
Column() {
Text(`点击计数:${this.count}`)
.interactiveStyle()
}
}
}
六、样式复用方案对比
| 复用方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| @Styles | 组件内/文件内样式复用 | 简单直接,支持状态和事件 | 不能传参,不能导出 |
| AttributeModifier | 跨文件样式复用 | 支持导出,灵活可扩展 | 使用相对复杂 |
| 复制粘贴 | 临时使用 | 简单粗暴 | 代码冗余,难以维护 |
建议
-
单文件内复用:优先使用@Styles
-
需要跨文件复用:使用AttributeModifier
-
需要参数化样式:考虑使用自定义组件或AttributeModifier
注意事项
-
参数传递:如果需要参数,考虑使用属性方法直接设置(不支持参数)
-
逻辑处理:复杂逻辑应该在build()方法中处理,而不是在@Styles内(不支持if/for等逻辑)
-
样式冲突:注意组件内样式会覆盖全局同名样式
-
性能考虑:合理复用样式,避免过度抽象
更多推荐


所有评论(0)