温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!
文章目录
- Tag组件实战应用与最佳实践
- 1. 复杂场景应用
- 1.1 标签筛选系统
- 2. 性能优化实践
- 2.1 状态管理优化
- 2.2 渲染性能优化
- 3. 实用功能扩展
- 3.1 拖拽排序
- 3.2 动画效果
- 4. 最佳实践总结
- 4.1 代码组织
- 4.2 测试建议
- 5. 常见问题解决
- 总结
Tag组件实战应用与最佳实践
1. 复杂场景应用
1.1 标签筛选系统
// 多选标签组实现
import { Tag } from "../components/AutoTags"
interface tagGroupClass {
groupId: string,
title: string,
tags: tagClass[]
}
interface tagClass {
id: string,
text: string,
type: string
groupId?: string
}
@Component
export struct FilterTags {
@State selectedTags: Set<string> = new Set()
@State tagGroups: tagGroupClass[] = [
{
groupId: 'g1',
title: '类型',
tags: [
{ id: '1', text: '重要', type: 'primary' },
{ id: '2', text: '普通', type: 'default' }
]
},
{
groupId: 'g2',
title: '状态',
tags: [
{ id: '3', text: '进行中', type: 'warning' },
{ id: '4', text: '已完成', type: 'success' }
]
}
]
build() {
Column({ space: 16 }) {
ForEach(this.tagGroups, (group) => {
Column({ space: 8 }) {
Text(group.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(group.tags, (tag:tagClass) => {
Tag({
text: tag.text,
type: tag.type ?? 'default'
}).onClick(() => {
this.handleTagClick(tag.id)
})
})
}
}
})
}
}
private handleTagClick(tagId: string) {
if (this.selectedTags.has(tagId)) {
this.selectedTags.delete(tagId)
} else {
this.selectedTags.add(tagId)
}
this.notifyFilterChange()
}
private notifyFilterChange() {
// 处理筛选逻辑
console.log(`筛选条件:${Array.from(this.selectedTags).join(',')}`)
}
}
2. 性能优化实践
2.1 状态管理优化
// 优化前
@State private tags: Array<string> = []
// 优化后:使用Set提高查找效率
@State private tagSet: Set<string> = new Set()
// 优化数据结构
interface TagItem {
id: string
text: string
type: string
selected?: boolean
}
// 使用Map优化查找
@State private tagMap: Map<string, TagItem> = new Map()
2.2 渲染性能优化
@Component
struct OptimizedTags {
// 使用@Builder抽取复用组件
@Builder
private TagItem(tag: TagItem) {
Tag({
text: tag.text,
type: tag.type,
closable: true
})
.margin(4)
}
// 使用懒加载优化大列表渲染
build() {
List({ space: 8 }) {
LazyForEach(this.dataSource, (tag: TagItem) => {
ListItem() {
this.TagItem(tag)
}
}, (tag: TagItem) => tag.id)
}
}
}
3. 实用功能扩展
3.1 拖拽排序
@Component
struct DraggableTags {
@State tags: TagClass[] = []
@State dragIndex: number = -1
build() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.tags, (tag, index) => {
Tag({
text: tag.text,
type: tag.type
})
.gesture(
PanGesture()
.onActionStart(() => {
this.dragIndex = index
})
.onActionUpdate((event: GestureEvent) => {
// 处理拖拽逻辑
})
.onActionEnd(() => {
this.dragIndex = -1
})
)
})
}
}
}
3.2 动画效果
@Component
struct AnimatedTag {
@State private isVisible: boolean = true
@State private scale: number = 1
build() {
Tag({
text: '动画标签',
closable: true,
onClose: () => {
animateTo({
duration: 300,
curve: Curve.EaseInOut,
onFinish: () => {
this.isVisible = false
}
}, () => {
this.scale = 0
})
}
})
.scale(this.scale)
.opacity(this.isVisible ? 1 : 0)
}
}
4. 最佳实践总结
4.1 代码组织
// 集中管理颜色配置
const TagColors = {
text: {
default: '#333333',
primary: '#2468f2',
// ...
},
background: {
default: '#ffffff',
primary: '#eef2ff',
// ...
},
// ...
} as const
// 抽取通用逻辑
class TagUtils {
static getColor(type: string, state: string): string {
return Reflect.get(TagColors[state], type) || TagColors[state].default
}
static validateType(type: string): boolean {
return ['default', 'primary', 'success', 'warning', 'danger'].includes(type)
}
}
4.2 测试建议
- 单元测试
// 测试颜色系统
describe('TagUtils', () => {
it('should return correct color', () => {
expect(TagUtils.getColor('primary', 'text')).toBe('#2468f2')
expect(TagUtils.getColor('invalid', 'text')).toBe('#333333')
})
it('should validate type correctly', () => {
expect(TagUtils.validateType('primary')).toBe(true)
expect(TagUtils.validateType('invalid')).toBe(false)
})
})
- 性能测试
- 大数据量下的渲染性能
- 频繁状态更新的响应速度
- 内存占用情况
5. 常见问题解决
- 状态同步问题
// 问题:子组件状态未同步到父组件
// 解决:使用双向绑定
@Component
struct ParentComponent {
@State tags: TagItem[] = []
build() {
Column() {
ChildTags({ tags: $tags })
}
}
}
@Component
struct ChildTags {
@Link tags: TagItem[]
// ...
}
- 性能问题
// 问题:大量标签渲染卡顿
// 解决:使用虚拟列表
@Component
struct VirtualTags {
private virtualListController: VirtualListController = new VirtualListController()
build() {
VirtualList({ controller: this.virtualListController }) {
ForEach(this.tags, (tag) => {
TagItem({ tag })
})
}
}
}
总结
在 HarmonyOS NEXT 仿uv-ui Tag组件开发教程系列中我们从零开始开发了Tag组件, 他的扩展性其实还是存在的, 当然在开发过程中需要注意的是,一定要注意性能优化的问题, 其次在案例源码中接口类型其实定义在当前的文件中 ,在正式开发的过程中建议创建一个 Types 文件夹 将定义的接口接口放在该文件夹下进行统一管理