鸿蒙Next 组件样式封装
2025-06-27 22:39:45
108次阅读
0个评论
封装!封装!封装!
不会封装的Coder不是一个好CV大师
当我们的布局中有比较多的重复样式需要设置时,会增加很多相同类似的代码,增加维护成本,组件的抽离和复用是非常重要的,记下来举个例子。 如果实现上面一个用户中心的卡片列表,先举一个反面例子
@Entry
@ComponentV2
struct User{
build() {
Column(){
Column(){
RelativeContainer(){
Row({space:20}){
Image($r('app.media.ic_my_card')).width(30).height(30).objectFit(ImageFit.Cover)
Text('我的名片').fontColor(Color.Black).fontSize(18)
}.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
}).margin({left:20})
Image($r('app.media.common_arrow'))
.width(30).height(20)
.objectFit(ImageFit.Contain)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
}.height(50).width('100%')
.onClick(()=>{
//处理点击事件
})
RelativeContainer(){
Row({space:20}){
Image($r('app.media.ic_my_face_info')).width(30).height(30).objectFit(ImageFit.Cover)
Text('人脸信息').fontColor(Color.Black).fontSize(18)
}.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
}).margin({left:20})
Image($r('app.media.common_arrow'))
.width(30).height(20)
.objectFit(ImageFit.Contain)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
}.height(50).width('100%')
.onClick(()=>{
//处理点击事件
})
RelativeContainer(){
Row({space:20}){
Image($r('app.media.ic_my_domain_account')).width(30).height(30).objectFit(ImageFit.Cover)
Text('我的订单').fontColor(Color.Black).fontSize(18)
}.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
}).margin({left:20})
Image($r('app.media.common_arrow'))
.width(30).height(20)
.objectFit(ImageFit.Contain)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
}.height(50).width('100%')
.onClick(()=>{
//处理点击事件
})
RelativeContainer(){
Row({space:20}){
Image($r('app.media.ic_my_archives')).width(30).height(30).objectFit(ImageFit.Cover)
Text('我的档案').fontColor(Color.Black).fontSize(18)
}.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
}).margin({left:20})
Image($r('app.media.common_arrow'))
.width(30).height(20)
.objectFit(ImageFit.Contain)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
}.height(50).width('100%')
.onClick(()=>{
//处理点击事件
})
RelativeContainer(){
Row({space:20}){
Image($r('app.media.ic_settings')).width(30).height(30).objectFit(ImageFit.Cover)
Text('设置').fontColor(Color.Black).fontSize(18)
}.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
}).margin({left:20})
Image($r('app.media.common_arrow'))
.width(30).height(20)
.objectFit(ImageFit.Contain)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
}.height(50).width('100%')
.onClick(()=>{
//处理点击事件
})
}
.margin({left:20,right:20,top:30})
.padding({top:10,bottom:10})
.backgroundColor(Color.White)
.borderRadius(10)
}.backgroundColor('#E1F5FE')
.width('100%')
.height('100%')
}
}
以上用了116行代码才实现了一个简单的5行信息的卡片,大部代码都是重复冗余的。相同属性和组件直接抽离封装,看结果:
//@Styles仅支持通用属性和通用事件
//个人信息card属性
@Styles function bgStyles () {
.backgroundColor('#E1F5FE')
.width('100%')
.height('100%')
}
//个人信息card属性
@Styles function cardStyles () {
.margin({left:20,right:20,top:30})
.padding({top:10,bottom:10})
.backgroundColor(Color.White)
.borderRadius(10)
}
//@Extend支持封装指定组件的私有属性、私有事件和自身定义的全局方法
@Extend(Image) function imageStyle(){
.width(30).height(30).objectFit(ImageFit.Cover)
}
//支持传参
@Extend(Text) function textStyle(fontSize: number){
.fontColor(Color.Black).fontSize(fontSize)
}
@Extend(Row) function rowStyle(){
.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start).alignRules(AlignParentLeft).margin({left:20})
}
let AlignParentLeft: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
'center': { 'anchor': '__container__', 'align': VerticalAlign.Center },
'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
}
let AlignParentRight: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
'center': { 'anchor': '__container__', 'align': VerticalAlign.Center },
'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
}
@Entry
@ComponentV2
struct test4{
@Builder
buildItem(imgS:ResourceStr,itemName:string,onClick: () => void){
RelativeContainer(){
Row({space:20}){
Image(imgS).imageStyle()
Text(itemName).textStyle(18)
}.rowStyle()
Image($r('app.media.common_arrow')).imageStyle().alignRules(AlignParentRight)
}.height(50).width('100%')
.onClick(onClick)
}
build() {
Column(){
Column(){
this.buildItem($r('app.media.ic_my_card'),'我的名片',()=>{
showToast('我的名片')
})
this.buildItem($r('app.media.ic_my_face_info'),'人脸信息',()=>{
showToast('人脸信息')
})
this.buildItem($r('app.media.ic_my_domain_account'),'我的订单',()=>{
showToast('我的订单')
})
this.buildItem($r('app.media.ic_my_archives'),'我的档案',()=>{
showToast('我的档案')
})
this.buildItem($r('app.media.ic_settings'),'设置',()=>{
showToast('设置')
})
}
.cardStyles()
}.bgStyles()
}
}
这样用很少代码就实现了相同的样式,如果再增加相同信息,只需要一两行代码即可实现,如果修改布局只需要修改一处就可以全局修改!
00
- 0回答
- 0粉丝
- 0关注
相关话题
- HarmonyOS NEXT实战:自定义封装多种样式导航栏组件
- 鸿蒙开发:组件样式的复用
- 鸿蒙开发中的组件样式复用
- 基于鸿蒙应用分层架构的ArkUI组件封装实践
- 28.Harmonyos Next仿uv-ui 组件NumberBox 步进器组件样式定制
- 跟着IBest-UI学HarmonyOS NEXT组件封装:Badge徽标
- 跟着IBest-UI学HarmonyOS NEXT组件封装:Watermark 水印
- 22.HarmonyOS Next CustomSlider组件样式自定义教程(四)
- 06.HarmonyOS Next UI进阶:Text组件与视觉样式完全指南
- HarmonyOs开发:导航tabs组件封装与使用
- 鸿蒙开发:权限授权封装
- 跟着IBest-UI学HarmonyOS NEXT组件封装:TextEllipsis 文本省略
- 117.HarmonyOS NEXT 跑马灯组件详解(五):布局与样式实现
- 鸿蒙开发:走进stateStyles多态样式
- 鸿蒙开发走进多态样式stateStyles