当前位置: 首页 > article >正文

09 HarmonyOS NEXT 仿uv-ui Tag组件开发教程系列(三)

温馨提示:本篇博客的详细代码已发布到 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: stringgroupId?: 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: stringtext: stringtype: stringselected?: boolean
}// 使用Map优化查找
@State private tagMap: Map<string, TagItem> = new Map()
2.2 渲染性能优化
@Component
struct OptimizedTags {// 使用@Builder抽取复用组件@Builderprivate 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 = -1build() {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 = 1build() {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 测试建议
  1. 单元测试
// 测试颜色系统
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)})
})
  1. 性能测试
  • 大数据量下的渲染性能
  • 频繁状态更新的响应速度
  • 内存占用情况

5. 常见问题解决

  1. 状态同步问题
// 问题:子组件状态未同步到父组件
// 解决:使用双向绑定
@Component
struct ParentComponent {@State tags: TagItem[] = []build() {Column() {ChildTags({ tags: $tags })}}
}@Component
struct ChildTags {@Link tags: TagItem[]// ...
}
  1. 性能问题
// 问题:大量标签渲染卡顿
// 解决:使用虚拟列表
@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 文件夹 将定义的接口接口放在该文件夹下进行统一管理

相关文章:

09 HarmonyOS NEXT 仿uv-ui Tag组件开发教程系列(三)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 文章目录 Tag组件实战应用与最佳实践1. 复杂场景应用1.1 标签筛选系统 2. 性能优化实践2.1 状态管理优化2.2 渲染性能优化 3. 实用功能扩展3.1 拖拽…...

【每日学点HarmonyOS Next知识】网页Scheme拉起应用、列表刷新、Web下载文件、根据子元素

1、HarmonyOS 目前 app 中是否支持网页Scheme拉起应用&#xff1f; 支持deeplink的&#xff0c;网页中添加按钮引导用户拉起应用。网页端直接提示打开应用按钮绑定点击事件window.open(tzptest://www.xxxxx.com?urlXXX)>,点击该按钮&#xff0c;打开网页web端收到的url为t…...

如何排查MySQL是否走索引

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…...

AF3 curry1函数解读

AlphaFold3 data_transforms 模块的 curry1 函数实现了一个经典的柯里化 (currying) 技术,具体是固定函数 f 的所有参数,除了第一个参数。换句话说,curry1 允许你在调用函数时,先提供除了第一个参数之外的所有参数,然后返回一个新的函数,这个新函数只等待第一个参数。 …...

摄像头应用编程(三):多平面视频采集

文章目录 1、前言2、环境介绍3、步骤4、应用程序编写5、测试5.1、编译应用程序5.2、运行应用程序 6、总结 1、前言 在查看摄像头类型时&#xff0c;大致可以分为两类&#xff1a;Video Capture 和 Video Capture Multiplanar。 本次应用程序主要针对类型为Video Capture Multi…...

【GoTeams】-2:项目基础搭建(下)

本文目录 1. 回顾2. Zap日志3. 配置4. 引入gprc梳理gRPC思路优雅关闭gRPC 1. 回顾 上篇文章我们进行了路由搭建&#xff0c;引入了redis&#xff0c;现在来看看对应的效果。 首先先把前端跑起来&#xff0c;然后点击注册获取验证码。 再看看控制台输出和redis是否已经有记录&…...

02-双指针-A-B 数对

题目 链接&#xff1a;P1102 A-B 数对 - 洛谷 思路 问题场景想象 我们可以把这个问题想象成在一个排队的队伍里找符合特定身高差的人对。给定的数列里的每个数就好比队伍里每个人的身高&#xff0c;而差值 C 就是我们要找的身高差。我们的目标是找出队伍里所有身高差恰好是 …...

2025年Cursor最新安装使用教程

Cursor安装教程 一、Cursor下载二、Cursor安装三、Cursor编辑器快捷键(1) 基础编辑快捷键(2) 导航快捷键(3) 其他常用快捷键 一、Cursor下载 Cursor官方网站&#xff08;https://www.cursor.com/ &#xff09; 根据自己电脑操作系统选择对应安装包 二、Cursor安装 下载完成后…...

Modbus TCP/IP 与 RS-485 接口的兼容性

Modbus TCP/IP 和 RS-485 接口的 直接兼容性 不存在,因为两者分属不同的网络层次(TCP/IP 基于以太网,RS-485 是物理层接口),但通过 协议转换和网络架构设计 可以实现互联互通。以下是详细的技术解析与实现方案: 一、协议差异对比 特性Modbus TCP/IPModbus RTU(RS-485)物…...

快速部署:在虚拟机上安装 CentOS 7 的详细步骤

CentOS是一个开源的基于Red Hat Enterprise Linux (RHEL) 的Linux发行版&#xff0c;它的主要目的是提供一个与RHEL相似的操作系统但不包含RHEL的商业支持和服务&#xff0c;完全免费。主要面向那些希望在企业环境中使用稳定、可靠的Linux系统但又不想支付RHEL许可证费用的用户…...

better-sqlite3之exec方法

在 better-sqlite3 中&#xff0c;.exec() 方法用于执行包含多个 SQL 语句的字符串。与预编译语句相比&#xff0c;这种方法性能较差且安全性较低&#xff0c;但有时它是必要的&#xff0c;特别是当你需要从外部文件&#xff08;如 SQL 脚本&#xff09;中执行多个 SQL 语句时。…...

NDT 代价函数

SLAM 中的 NDT 代价函数 在SLAM&#xff08;同步定位与地图构建&#xff09;中&#xff0c;NDT&#xff08;Normal Distributions Transform&#xff09;是一种常用的点云配准方法。NDT代价函数用于评估点云配准的质量。以下是NDT代价函数的详细介绍&#xff1a; NDT 代价函数…...

【有啥问啥】深入浅出:大模型应用工具 Ollama 技术详解

深入浅出&#xff1a;大模型应用工具 Ollama 技术详解 引言 近年来&#xff0c;大型模型&#xff08;Large Models&#xff0c;LLMs&#xff09;技术突飞猛进&#xff0c;在自然语言处理、计算机视觉、语音识别等领域展现出强大的能力。然而&#xff0c;部署和运行这些庞大的…...

【AI训练】如何提高LLM的训练速度

提高大型语言模型&#xff08;LLM&#xff09;的训练速度需要从算法优化、硬件加速、软件框架和基础设施等多个层面综合考虑。以下是一些关键方法&#xff0c;按类别分类说明&#xff1a; --- 一、硬件优化 1. 分布式训练 - 数据并行&#xff08;Data Parallelism&#xff09;…...

利用opencv_python(pdf2image、poppler)将pdf每页转为图片

1、安装依赖pdf2image pip install pdf2image 运行.py报错&#xff0c;因为缺少了poppler支持。 2、安装pdf2image的依赖poppler 以上命令直接报错。 改为手工下载&#xff1a; github: Releases oschwartz10612/poppler-windows GitHub 百度网盘&#xff1a; 百度网盘…...

大数据测试总结

总结测试要点&#xff1a; 参考产品文档&#xff0c;技术文档梳理以下内容 需求来源 业务方应用场景 数据源&#xff0c;数据格转&#xff0c;数据产出&#xff0c;数据呈现方式&#xff08;数据消亡史&#xff09;&#xff0c;数据量级&#xff08;增量&#xff0c;全量&am…...

pytorch高可用的设计策略和集成放大各自功能

在使用 PyTorch 编写模型时,为确保模型具备高可用性,可从模型设计、代码质量、训练过程、部署等多个方面采取相应的方法,以下为你详细介绍: 模型设计层面 模块化设计 实现方式:将模型拆分成多个小的、独立的模块,每个模块负责特定的功能。例如,在一个图像分类模型中,可…...

容器 /dev/shm 泄漏学习

容器 /dev/shm 泄漏的介绍 在容器环境中&#xff0c;/dev/shm 是一个基于 tmpfs 的共享内存文件系统&#xff0c;通常用于进程间通信&#xff08;IPC&#xff09;和临时数据存储。由于其内存特性&#xff0c;/dev/shm 的大小是有限的&#xff0c;默认情况下 Docker 容器的 /de…...

Redis面试常见问题——集群方案

Redis集群方案 在Redis中提供的集群方案总共有三种 主从复制 哨兵模式 分片集群 主从复制 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 主从数据同步原理 单节点Redis的并发能力是有…...

企业级Python后端数据库使用指南(简略版)

总述 企业级应用通常需要考虑扩展性、安全性、性能等因素。数据库的使用也不例外。连接数据库的第一步应该是建立连接&#xff0c;但企业环境中可能不会每次操作都新建连接&#xff0c;而是使用连接池来管理&#xff0c;这样可以提高效率&#xff0c;减少资源消耗。例如&#x…...

Qt:day4

一、作业 1&#xff1a;实现绘图的时候&#xff0c;颜色的随时调整&#xff1b; 2&#xff1a;追加橡皮擦功能&#xff1b; 3&#xff1a;配合键盘事件&#xff0c;实现功能&#xff1b; 当键盘按 ctrlz 的时候&#xff0c;撤销最后一次绘图。 【Headers / widget.h】&#xff…...

随机播放音乐 伪随机

import java.util.*;/*** https://cloud.tencent.com.cn/developer/news/1045747* 伪随机播放音乐*/ public class MusicPlayer {private List<String> allSongs; // 所有歌曲列表private List<String> playedSongs; // 已经播放过的歌曲列表private Map<String…...

vue3之echarts仪表盘

vue3之echarts仪表盘 效果如下&#xff1a; 版本 "echarts": "^5.5.1" 核心代码&#xff1a; <template><div ref"chartRef" class"circle"></div> </template> <script lang"ts" setup>…...

将PDF转为Word的在线工具

参考视频&#xff1a;外文翻译 文章目录 一、迅捷PDF转换器二、Smallpdf 一、迅捷PDF转换器 二、Smallpdf...

MWC 2025|紫光展锐联手美格智能发布5G通信模组SRM812

在2025年世界移动通信大会&#xff08;MWC 2025&#xff09;期间&#xff0c;紫光展锐携手美格智能正式推出了基于紫光展锐V620平台的第二代5G Sub6G R16模组SRM812&#xff0c;以超高性价比方案&#xff0c;全面赋能合作伙伴&#xff0c;加速5G规模化应用在各垂直领域的全面落…...

js操作数组的常用方法

1. 遍历方法 1.1 forEach 作用&#xff1a;遍历数组中的每个元素&#xff0c;并对每个元素执行回调函数。 是否改变原数组&#xff1a;不会改变原数组。 返回值&#xff1a;undefined。 1.1.1 基本用法 const arr [1, 2, 3]; arr.forEach((item) > console.log(item …...

前端基础之ajax

vue-cli配置代理服务器解决跨域问题 我们可以使用一个代理服务器8080&#xff0c;Vue项目8080发送请求向代理服务器8080发送请求&#xff0c;再由在理服务器转发给后端服务器 首先需要在vue.config.js中配置代理服务器 const { defineConfig } require(vue/cli-service) modul…...

Android车机DIY开发之软件篇(二十)立创泰山派android编译

准备工作 sudo apt-get update sudo apt-get install git -y sudo apt install repo -ysudo apt-get install python2.7sudo apt-get install python3sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1 sudo update-alternatives --install /u…...

ADB 和 Monkey 进行 Android 应用的测试和调试

ADB(Android Debug Bridge)和 Monkey 是 Android 开发和测试中常用的工具。ADB 用于与 Android 设备通信,而 Monkey 是一个压力测试工具,可以模拟用户随机操作。以下是它们的高级用法,帮助您更高效地进行 Android 应用测试和调试。 一、ADB 的高级用法 1. 设备管理 查看连…...

【无标题】FrmImport

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;四、项目展示五、资源链接 前言 我能抽象出整个世界&#xff0c;但是我不能抽象你。 想让你成为私有常量&#xff0c;这样外部函数就无法访问你。 又想让你成为全局常量&#xff0c;这样在我的…...