1
09 HarmonyOS NEXT 仿 uv-ui Tag 组件开发教程系列 (三)
作者:全栈若城
- 2025-03-06 北京
本文字数:4380 字
阅读完需:约 14 分钟
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!
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}
@Componentexport 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 渲染性能优化
@Componentstruct 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 拖拽排序
@Componentstruct 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 动画效果
@Componentstruct 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. 常见问题解决
状态同步问题
// 问题:子组件状态未同步到父组件// 解决:使用双向绑定@Componentstruct ParentComponent { @State tags: TagItem[] = []
build() { Column() { ChildTags({ tags: $tags }) } }}
@Componentstruct ChildTags { @Link tags: TagItem[] // ...}
复制代码
性能问题
// 问题:大量标签渲染卡顿// 解决:使用虚拟列表@Componentstruct VirtualTags { private virtualListController: VirtualListController = new VirtualListController()
build() { VirtualList({ controller: this.virtualListController }) { ForEach(this.tags, (tag) => { TagItem({ tag }) }) } }}
复制代码
总结
在 HarmonyOS NEXT 仿 uv-ui Tag 组件开发教程系列中我们从零开始开发了 Tag 组件, 他的扩展性其实还是存在的, 当然在开发过程中需要注意的是,一定要注意性能优化的问题, 其次在案例源码中接口类型其实定义在当前的文件中 ,在正式开发的过程中建议创建一个 Types 文件夹 将定义的接口接口放在该文件夹下进行统一管理
划线
评论
复制
发布于: 刚刚阅读数: 7
版权声明: 本文为 InfoQ 作者【全栈若城】的原创文章。
原文链接:【http://xie.infoq.cn/article/1813ad39ee9cb443bbe235c0c】。文章转载请联系作者。
全栈若城
关注
解读Python与前端技术,助你成为技术大牛 2023-06-28 加入
我是一名专注于 Python 和前端技术的技术讲解者。我擅长将复杂的技术概念转化为简单易懂的语言,帮助初学者快速入门,并满足高级开发者对更深入理解的需求。









评论