#跟着晓明学鸿蒙# HarmonyOS商品详情页规格选择区实现
·

目录
- 案例介绍
- 代码实现
- 代码详解
- 数据结构设计
- 规格选择区布局
- 交互实现
- 总结
案例介绍
在电商应用中,规格选择区是用户选择商品具体型号、颜色等属性的关键区域。本篇文章将详细讲解如何使用HarmonyOS NEXT的Column和Flex组件构建一个专业的商品详情页规格选择区,实现规格选项的动态渲染和交互效果。
代码实现
@Entry
@Component
struct ProductDetail {
// 商品信息
@State product: {
title: string,
price: number,
originalPrice: number,
sales: number,
description: string,
specs: Array<{
name: string,
options: Array<string>
}>
} = {
title: '2024新款智能手表',
price: 999.00,
originalPrice: 1299.00,
sales: 1580,
description: '高清大屏,续航持久,智能监测,运动计步',
specs: [
{
name: '颜色',
options: ['曜石黑', '星空银', '玫瑰金']
},
{
name: '尺寸',
options: ['41mm', '45mm']
}
]
}
// 选中的规格
@State selectedSpecs: Record<string, string> = {}
build() {
Column() {
// 规格选择区
Column() {
Text('规格选择')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ bottom: 15 })
ForEach(this.product.specs, (spec) => {
Column() {
Text(spec.name)
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 10 })
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(spec.options, (option) => {
Text(option)
.fontSize(14)
.padding(10)
.backgroundColor(this.selectedSpecs[spec.name] === option ? '#FFE4E4' : '#F5F5F5')
.fontColor(this.selectedSpecs[spec.name] === option ? '#FF0000' : '#333333')
.borderRadius(5)
.margin({ right: 10, bottom: 10 })
.onClick(() => {
this.selectedSpecs[spec.name] = option
})
})
}
}
.margin({ bottom: 20 })
})
}
.width('100%')
.padding(15)
.backgroundColor(Color.White)
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
代码详解
数据结构设计
我们使用两个关键的状态变量来管理规格选择区:
-
商品规格数据:
@State product: { // 其他属性... specs: Array<{ name: string, // 规格名称(如颜色、尺寸) options: Array<string> // 规格选项(如黑色、白色) }> } -
选中规格状态:
@State selectedSpecs: Record<string, string> = {}这是一个键值对对象,键为规格名称,值为选中的选项。例如:
{"颜色": "曜石黑", "尺寸": "41mm"}
规格选择区布局
Column() {
Text('规格选择')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ bottom: 15 })
ForEach(this.product.specs, (spec) => {
Column() {
Text(spec.name)
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 10 })
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(spec.options, (option) => {
Text(option)
.fontSize(14)
.padding(10)
.backgroundColor(this.selectedSpecs[spec.name] === option ? '#FFE4E4' : '#F5F5F5')
.fontColor(this.selectedSpecs[spec.name] === option ? '#FF0000' : '#333333')
.borderRadius(5)
.margin({ right: 10, bottom: 10 })
.onClick(() => {
this.selectedSpecs[spec.name] = option
})
})
}
}
.margin({ bottom: 20 })
})
}
.width('100%')
.padding(15)
.backgroundColor(Color.White)
.margin({ top: 10 })
-
标题区域:
- 使用Text组件显示"规格选择"标题
- 字体大小16,中等粗细,底部外边距15像素
-
规格项循环:
- 使用ForEach循环遍历product.specs数组
- 为每个规格创建一个Column容器
-
规格名称:
- 显示规格名称(如"颜色"、"尺寸")
- 字体大小14,颜色为深灰色(#666666),底部外边距10像素
-
规格选项布局:
- 使用Flex组件实现流式布局,设置
wrap: FlexWrap.Wrap使选项可以自动换行 - 当选项过多时,会自动换行显示,避免溢出屏幕
- 使用Flex组件实现流式布局,设置
-
规格选项样式:
- 使用Text组件显示每个选项
- 内边距10像素,圆角5像素
- 右侧和底部外边距10像素,确保选项之间有适当间距
交互实现
Text(option)
.fontSize(14)
.padding(10)
.backgroundColor(this.selectedSpecs[spec.name] === option ? '#FFE4E4' : '#F5F5F5')
.fontColor(this.selectedSpecs[spec.name] === option ? '#FF0000' : '#333333')
.borderRadius(5)
.margin({ right: 10, bottom: 10 })
.onClick(() => {
this.selectedSpecs[spec.name] = option
})
-
点击事件处理:
- 使用
.onClick()方法为每个选项添加点击事件 - 当用户点击选项时,更新selectedSpecs对象,将当前规格名称作为键,选中的选项作为值
- 使用
-
动态样式变化:
- 背景色:选中时为浅红色(#FFE4E4),未选中时为浅灰色(#F5F5F5)
- 文字颜色:选中时为红色(#FF0000),未选中时为深灰色(#333333)
- 使用三元运算符根据选中状态动态切换样式
-
状态判断逻辑:
this.selectedSpecs[spec.name] === option:判断当前选项是否被选中- 通过比较selectedSpecs对象中存储的值与当前选项是否相同来确定
总结
本篇文章详细讲解了如何使用HarmonyOS NEXT的Column和Flex组件构建商品详情页的规格选择区。通过合理的数据结构设计和组件嵌套,我们实现了规格选项的动态渲染和交互效果。
关键实现点:
- 数据结构设计:使用嵌套数组存储规格信息,使用Record对象存储选中状态
- 流式布局:使用Flex组件的FlexWrap.Wrap属性实现规格选项的自动换行
- 动态样式:根据选中状态动态切换背景色和文字颜色
- 事件处理:通过onClick事件更新选中状态
这种实现方式具有以下优势:
- 灵活性:可以轻松适应不同数量和类型的规格选项
- 可维护性:数据与UI分离,便于后期维护和扩展
- 用户体验:清晰的视觉反馈,帮助用户了解当前选择状态
更多推荐



所有评论(0)