项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
1. 引言
在上一部分中,我们介绍了任务列表的基础结构、数据模型设计以及外层Column的实现。本教程将继续深入探讨TaskItem组件的内部结构,包括Row布局的实现、条件渲染的使用以及交互事件的处理,帮助开发者掌握更复杂的布局和交互技巧,创建功能丰富、用户体验良好的任务列表界面。
2. TaskItem组件设计
2.1 组件定义与状态管理
@Component
struct TaskItem {
@Prop task: string
@State showActions: boolean = false
build() {
// 组件内容
}
}
装饰器 | 属性 | 类型 | 初始值 | 说明 |
---|---|---|---|---|
@Component | - | - | - | 标识这是一个自定义组件 |
@Prop | task | string | - | 从父组件接收的任务文本,只读属性 |
@State | showActions | boolean | false | 组件内部状态,控制操作按钮的显示与隐藏 |
2.2 装饰器的作用与区别
2.2.1 @Component装饰器
@Component装饰器用于定义自定义组件,它告诉框架这是一个可复用的UI组件,具有自己的生命周期和渲染逻辑。
2.2.2 @Prop装饰器
@Prop装饰器用于定义从父组件接收的属性,特点包括:
- 单向数据流:父组件可以修改属性值,子组件只能读取不能修改
- 响应式:当父组件中的值变化时,子组件会自动更新
- 简单传递:适用于传递简单数据类型或只读对象
2.2.3 @State装饰器
@State装饰器用于定义组件的内部状态,特点包括:
- 组件私有:状态只在组件内部可见和修改
- 响应式:状态变化会触发组件重新渲染
- 状态持久:在组件生命周期内保持状态
在TaskItem组件中,我们使用@State装饰器定义了showActions状态,用于控制操作按钮的显示与隐藏,初始值为false(隐藏状态)。
3. Row布局实现
3.1 基本结构
Row({ space: 16 })
{
// 任务内容(垂直排列)
Column({ space: 4 }) {
// 文本组件
}
// 操作按钮(水平排列,悬停显示)
if (this.showActions) {
Row({ space: 8 }) {
// 按钮组件
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.padding({ left: 12,right:12, top: 16, bottom: 16 })
.backgroundColor(0xFFFFFF)
.borderRadius(8)
.shadow({ radius: 2, color: 0x05000000 })
.onHover((isHover: boolean, event: HoverEvent)=>{
// 悬停事件处理
})
每个任务项使用Row组件实现水平布局,将任务内容和操作按钮分别放置在左右两侧。
3.2 Row属性详解
属性/参数 | 值 | 作用 |
---|---|---|
space | 16 | 设置子组件之间的水平间距为16vp |
width | 100% | 设置Row宽度占父容器的100% |
padding | { left: 12,right:12, top: 16, bottom: 16 } | 设置内边距,上下16vp,左右12vp |
backgroundColor | 0xFFFFFF | 设置背景色为白色 |
borderRadius | 8 | 设置边框圆角为8vp |
shadow | { radius: 2, color: 0x05000000 } | 设置阴影效果,营造卡片视觉 |
3.3 卡片式设计的实现
.backgroundColor(0xFFFFFF)
.borderRadius(8)
.shadow({ radius: 2, color: 0x05000000 })
这三个属性的组合实现了卡片式设计:
- 白色背景提供了与页面背景的对比
- 圆角边框柔化了卡片的视觉边界
- 轻微的阴影效果增强了层次感,使卡片看起来略微悬浮
阴影参数解析:
参数 | 值 | 说明 |
---|---|---|
radius | 2 | 阴影扩散半径,值越大阴影越模糊 |
color | 0x05000000 | 阴影颜色,0x05表示透明度为5%的黑色阴影 |
4. 任务内容区域的Column布局
4.1 基本结构
Column({ space: 4 }) {
Text(this.task)
.fontSize(16)
.fontWeight(500)
Text('2025-05-30 14:00')
.fontSize(12)
.fontColor(0x666666)
}
任务内容区域使用Column组件垂直排列任务标题和日期信息。
4.2 Column属性详解
属性/参数 | 值 | 作用 |
---|---|---|
space | 4 | 设置子组件之间的垂直间距为4vp |
4.3 文本组件的实现
4.3.1 任务标题
Text(this.task)
.fontSize(16)
.fontWeight(500)
属性 | 值 | 作用 |
---|---|---|
构造参数 | this.task | 设置文本内容,来自@Prop装饰的task属性 |
fontSize | 16 | 设置字体大小为16vp |
fontWeight | 500 | 设置字体粗细为中等偏粗 |
4.3.2 任务日期
Text('2025-05-30 14:00')
.fontSize(12)
.fontColor(0x666666)
属性 | 值 | 作用 |
---|---|---|
构造参数 | '2025-05-30 14:00' | 设置文本内容为固定的日期时间文本 |
fontSize | 12 | 设置字体大小为12vp,小于标题字号 |
fontColor | 0x666666 | 设置字体颜色为深灰色,弱化视觉重要性 |
4.4 文本层次设计
任务内容区域的文本设计遵循了明确的视觉层次:
- 主要信息(任务标题):较大字号(16vp)、较粗字重(500)、默认黑色
- 次要信息(任务日期):较小字号(12vp)、默认字重、灰色(0x666666)
这种设计使用户能够快速识别重要信息,同时在需要时也能获取次要信息,提高了界面的可读性和信息层次感。
5. 操作按钮区域的条件渲染
5.1 条件渲染的实现
if (this.showActions) {
Row({ space: 8 }) {
Button('编辑')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xE0F5FF)
.fontColor(0x007DFF)
Button('删除')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xFFF0F0)
.fontColor(0xFF4D4F53)
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
条件渲染使用if语句实现,只有当showActions为true时,才会渲染操作按钮区域。
5.2 Row布局属性
属性/参数 | 值 | 作用 |
---|---|---|
space | 8 | 设置按钮之间的水平间距为8vp |
alignItems | VerticalAlign.Center | 设置子组件在垂直方向上居中对齐 |
justifyContent | FlexAlign.Center | 设置子组件在水平方向上居中对齐 |
5.3 按钮样式设计
5.3.1 编辑按钮
Button('编辑')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xE0F5FF)
.fontColor(0x007DFF)
属性 | 值 | 作用 |
---|---|---|
构造参数 | '编辑' | 设置按钮文本 |
width | 48 | 设置按钮宽度为48vp |
height | 28 | 设置按钮高度为28vp |
fontSize | 12 | 设置字体大小为12vp |
backgroundColor | 0xE0F5FF | 设置背景色为浅蓝色 |
fontColor | 0x007DFF | 设置文字颜色为蓝色 |
5.3.2 删除按钮
Button('删除')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xFFF0F0)
.fontColor(0xFF4D4F53)
属性 | 值 | 作用 |
---|---|---|
构造参数 | '删除' | 设置按钮文本 |
width | 48 | 设置按钮宽度为48vp |
height | 28 | 设置按钮高度为28vp |
fontSize | 12 | 设置字体大小为12vp |
backgroundColor | 0xFFF0F0 | 设置背景色为浅红色 |
fontColor | 0xFF4D4F53 | 设置文字颜色为红色 |
5.4 按钮的视觉差异化
两个按钮使用了不同的颜色方案来区分不同的操作类型:
- 编辑按钮:蓝色系(浅蓝背景 + 蓝色文字),表示中性操作
- 删除按钮:红色系(浅红背景 + 红色文字),表示危险操作
这种颜色编码符合用户的心理预期,使界面更加直观易用。
6. 交互事件处理
6.1 悬停事件的实现
.onHover((isHover: boolean, event: HoverEvent)=>{
if (isHover) {this.showActions = true}else{
this.showActions = false
}
})
onHover事件用于检测鼠标是否悬停在组件上,它接收一个回调函数,该函数有两个参数:
参数 | 类型 | 说明 |
---|---|---|
isHover | boolean | 表示鼠标是否悬停在组件上 |
event | HoverEvent | 包含事件详细信息的对象 |
6.2 状态管理与UI更新
if (isHover) {this.showActions = true}else{
this.showActions = false
}
这段代码根据悬停状态更新showActions状态变量:
- 当鼠标悬停在任务项上时(isHover为true),将showActions设为true,显示操作按钮
- 当鼠标离开任务项时(isHover为false),将showActions设为false,隐藏操作按钮
由于showActions是使用@State装饰器定义的响应式状态变量,当其值变化时,框架会自动重新渲染组件,实现操作按钮的动态显示与隐藏。
6.3 交互设计的优势
这种基于悬停的交互设计有以下优势:
- 界面简洁:默认情况下不显示操作按钮,减少视觉干扰
- 按需显示:只有当用户需要操作时(鼠标悬停),才显示相关按钮
- 直观反馈:提供即时的视觉反馈,增强用户体验
- 空间节省:在不牺牲功能的情况下,节省界面空间
7. 完整代码分析
让我们回顾完整的TaskItem组件代码:
@Component
struct TaskItem {
@Prop task: string
@State showActions: boolean = false
build() {
Row({ space: 16 })
{
// 任务内容(垂直排列)
Column({ space: 4 }) {
Text(this.task)
.fontSize(16)
.fontWeight(500)
Text('2025-05-30 14:00')
.fontSize(12)
.fontColor(0x666666)
}
// 操作按钮(水平排列,悬停显示)
if (this.showActions) {
Row({ space: 8 }) {
Button('编辑')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xE0F5FF)
.fontColor(0x007DFF)
Button('删除')
.width(48)
.height(28)
.fontSize(12)
.backgroundColor(0xFFF0F0)
.fontColor(0xFF4D4F53)
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.padding({ left: 12,right:12, top: 16, bottom: 16 })
.backgroundColor(0xFFFFFF)
.borderRadius(8)
.shadow({ radius: 2, color: 0x05000000 })
.onHover((isHover: boolean, event: HoverEvent)=>{
if (isHover) {this.showActions = true}else{
this.showActions = false
}
}) // 鼠标悬停显示操作按钮
}
}
7.1 代码结构分析
- 组件定义:使用@Component装饰器定义TaskItem自定义组件
- 属性与状态:定义@Prop属性接收任务文本,定义@State状态控制操作按钮显示
布局结构:
- 外层Row:水平排列任务内容和操作按钮
- 内层Column:垂直排列任务标题和日期
- 条件渲染Row:根据状态显示或隐藏操作按钮
- 样式设置:设置卡片式样式,包括背景色、圆角和阴影
- 交互处理:通过onHover事件实现鼠标悬停交互
7.2 布局嵌套层次
本案例展示了多层嵌套布局的实现方式:
- 第一层:TaskItem组件的Row(水平排列)
- 第二层:左侧Column(垂直排列)和右侧条件渲染Row(水平排列)
- 第三层:文本组件和按钮组件
这种多层嵌套的布局结构能够实现复杂的界面设计,同时保持代码的清晰和可维护性。
8. 总结
通过本教程的两个部分,我们详细讲解了如何使用Column和Row组件的嵌套组合,结合自定义组件和条件渲染,创建一个交互式任务列表
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。