ArkTS 中@Extend 和@Styles 装饰器总结
一、@Styles 装饰器
1.1 基本概念
@Styles 是一种用于提取公共样式的装饰器,可以将多个通用属性样式提取成一个方法,在组件中直接调用。
1.2 使用场景
- 提取重复使用的样式代码
- 简化代码,提高可维护性
- 支持全局和组件内定义
1.3 语法格式
全局@Styles
typescript
@Styles function globalFancyStyle() {
.width(200)
.height(100)
.backgroundColor(Color.Pink)
.borderRadius(10)
}
组件内@Styles
typescript
@Component
struct MyComponent {
@Styles localFancyStyle() {
.width(200)
.height(100)
.backgroundColor(Color.Blue)
}
build() {
Column() {
Text('示例')
.localFancyStyle()
}
}
}
1.4 使用示例
typescript
@Entry
@Component
struct StylesExample {
@Styles commonButtonStyle() {
.width(120)
.height(40)
.backgroundColor('#36D')
.borderRadius(8)
}
build() {
Column({ space: 10 }) {
Button('按钮1')
.commonButtonStyle()
Button('按钮2')
.commonButtonStyle()
Button('按钮3')
.commonButtonStyle()
.backgroundColor(Color.Red) // 可以覆盖样式
}
.width('100%')
.padding(20)
}
}
1.5 特点和限制
- ✅ 支持通用属性和事件方法
- ✅ 可以在组件内部或全局定义
- ✅ 支持状态变量
- ✅ 可以传递状态变量作为参数(但不支持普通参数)
- ❌ 不支持参数传递(常规参数)
- ❌ 不能针对特定组件扩展(只能用于通用属性)
- ❌ 优先级较低,可被后续样式覆盖
二、@Extend 装饰器
2.1 基本概念
@Extend 是一种用于扩展特定组件样式的装饰器,可以为指定的组件类型添加自定义样式方法,并且支持参数传递。
2.2 使用场景
- 为特定组件定义可复用的样式
- 需要动态传递参数改变样式
- 封装组件特有的属性设置
2.3 语法格式
typescript
@Extend(ComponentName) function functionName(param1: type1, param2: type2) {
.attribute1(param1)
.attribute2(param2)
// ... 其他属性
}
2.4 使用示例
基础示例
typescript
@Extend(Text) function fancyText(fontSize: number, fontColor: Color) {
.fontSize(fontSize)
.fontColor(fontColor)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
}
@Entry
@Component
struct ExtendExample {
build() {
Column({ space: 10 }) {
Text('标题')
.fancyText(24, Color.Red)
Text('副标题')
.fancyText(18, Color.Blue)
Text('正文')
.fancyText(14, Color.Black)
}
.width('100%')
.padding(20)
}
}
高级示例 - 支持状态变量
typescript
@Extend(Button) function stateButton(
bgColor: ResourceColor,
isEnabled: boolean
) {
.backgroundColor(bgColor)
.opacity(isEnabled ? 1 : 0.4)
.enabled(isEnabled)
.borderRadius(12)
.width(160)
.height(50)
}
@Entry
@Component
struct ExtendStateExample {
@State isLoginEnabled: boolean = false
build() {
Column({ space: 20 }) {
Button('登录')
.stateButton(Color.Orange, this.isLoginEnabled)
Button('切换状态')
.onClick(() => {
this.isLoginEnabled = !this.isLoginEnabled
})
}
.width('100%')
.padding(20)
}
}
2.5 特点和限制
- ✅ 支持参数传递(可以传递多个参数)
- ✅ 参数可以是状态变量
- ✅ 针对特定组件进行扩展
- ✅ 支持链式调用
- ✅ 只能在全局定义(不能在组件内定义)
- ❌ 必须定义在组件外部
- ❌ 只能扩展一个组件类型
三、@Extend vs @Styles 对比总结
对比项 | @Styles | @Extend |
---|---|---|
定义位置 | 全局或组件内 | 仅全局 |
参数支持 | ❌ 不支持参数 | ✅ 支持多个参数 |
组件限定 | ❌ 不限定组件类型 | ✅ 必须指定组件类型 |
使用方式 | .styleName() |
.extendName(params) |
状态变量 | ✅ 支持内部使用 | ✅ 支持作为参数传递 |
样式覆盖 | 可被后续样式覆盖 | 可被后续样式覆盖 |
适用场景 | 固定的公共样式 | 需要参数化的样式 |
灵活性 | 较低(不支持参数) | 较高(支持参数) |
代码复用 | 适合完全相同的样式 | 适合相似但有差异的样式 |
四、实际应用建议
4.1 使用@Styles 的场景
typescript
// 适合:完全固定的样式组合
@Styles function cardStyle() {
.backgroundColor(Color.White)
.borderRadius(16)
.padding(20)
.shadow({ radius: 10, color: '#00000020' })
}
4.2 使用@Extend 的场景
typescript
// 适合:需要根据参数调整的样式
@Extend(Text) function customText(size: number, weight: number, color: ResourceColor) {
.fontSize(size)
.fontWeight(weight)
.fontColor(color)
.lineHeight(size * 1.5)
}
4.3 组合使用示例
typescript
// 全局Extend
@Extend(Column) function cardContainer(bgColor: ResourceColor) {
.backgroundColor(bgColor)
.borderRadius(12)
.padding(16)
.width('90%')
}
// 全局Styles
@Styles function shadowEffect() {
.shadow({
radius: 20,
color: '#00000030',
offsetX: 0,
offsetY: 4
})
}
@Entry
@Component
struct CombinedExample {
@Styles innerTextStyle() {
.fontSize(14)
.fontColor('#666')
}
build() {
Column({ space: 20 }) {
// 组合使用
Column() {
Text('卡片标题')
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text('卡片内容')
.innerTextStyle()
}
.cardContainer(Color.White)
.shadowEffect()
Column() {
Text('另一张卡片')
.fontSize(18)
}
.cardContainer('#FFF8DC')
.shadowEffect()
}
.width('100%')
.height('100%')
.padding(20)
.backgroundColor('#F5F5F5')
}
}
五、最佳实践建议
5.1 选择原则
- 固定样式 → 使用
@Styles
- 需要参数 → 使用
@Extend
- 特定组件 → 使用
@Extend
- 通用样式 → 使用
@Styles
5.2 命名规范
typescript
// @Styles命名:描述性名称
@Styles function primaryButtonStyle() {}
@Styles function cardShadow() {}
// @Extend命名:组件类型 + 用途
@Extend(Button) function themeButton(color: ResourceColor) {}
@Extend(Text) function headerText(level: number) {}
5.3 注意事项
- 避免过度嵌套和复杂的样式组合
- 保持样式函数的单一职责
- 合理使用参数,不要传递过多参数
- @Extend 必须在组件外部定义
- 优先考虑代码可读性和可维护性
六、总结
- @Styles:适合提取完全相同的样式代码,使用简单,但不支持参数化
- @Extend:适合需要根据参数动态调整的样式,灵活性高,但必须指定组件类型
两者都是 ArkTS 中重要的样式复用机制,合理使用可以大大提高代码质量和开发效率。在实际开发中,可以根据具体需求选择合适的装饰器,甚至组合使用以达到最佳效果。