鸿蒙开发架构设计:模块拆分 + 组件通信
一、好的架构不是一开始就设计出来的很多新手拿到需求就直接写页面从第一个组件开始堆代码写到一半发现组件之间传参乱成一团、数据流无法追踪、换个需求要改十几个文件。问题不在编码能力而在起点——没有先想清楚数据和界面怎么组织。架构设计的本质是回答三个问题数据存在哪里、组件之间怎么通信、状态变化后界面怎么更新。把这三个问题理清楚再动笔代码自然有条理后期维护也轻松很多。二、模块化拆分按职责还是按功能模块拆分有两种思路按职责分和按功能分。按职责分是把应用分成数据层、业务层、界面层所有数据操作放在一起、所有业务逻辑放在一起、所有 UI 组件放在一起。这种方式适合逻辑复杂、团队分工明确的大型项目但中小型应用容易出现数据层和界面层之间的调用链路过长问题。按功能分是把相关的数据、逻辑、界面打包成一个完整的模块比如笔记模块包含笔记的数据结构、增删改查逻辑、列表和详情页面。这种方式更直观改一个功能只需要在一个模块内工作适合快速迭代的中小型应用。实际项目中两种思路可以结合用按功能分的大框架用按职责分的思路设计每个功能模块内部。鸿蒙应用的标准工程结构已经给出了这个分层entry/src/main/ets/ ├── entryability/ # 入口Ability负责应用生命周期 ├── pages/ # 页面一个页面一个文件 ├── components/ # 可复用UI组件 ├── models/ # 数据模型和TypeScript接口 ├── services/ # 业务逻辑层API调用、数据处理 ├── utils/ # 工具函数 └── store/ # 跨组件共享的状态管理三、数据模型先定义形状再写逻辑很多开发者习惯边写边定义数据结构这很容易导致数据形状散落在代码各处改一个字段要全局搜索。正确的做法是先把所有数据模型集中定义在models目录下形成一份全局的类型契约。// models/NoteModel.ets// 笔记主体数据exportinterfaceNoteData{id:numbertitle:stringcontent:stringtags:string[]isPinned:booleanisArchived:booleancreatedAt:numberupdatedAt:number}// 笔记列表筛选条件exportinterfaceNoteFilter{keyword:stringtag:string|nullshowArchived:boolean}// 导出任务配置exportinterfaceExportConfig{format:markdown|json|txtincludeArchived:boolean}// 用户配置exportinterfaceUserSettings{theme:light|dark|autofontSize:numberautoSave:boolean}在 ArkTS 中接口定义放在单独文件里需要用的地方import进来。这种集中定义的方式带来一个额外的好处TypeScript 的智能提示会完整覆盖所有数据字段写代码时不容易拼错字段名。四、服务层把业务逻辑从 UI 中抽离业务逻辑不应该写在组件内部。组件的职责是渲染界面和处理用户交互业务规则、数据校验、API 调用都应该抽到服务层。这样同一个业务逻辑可以被多个页面复用测试时也更容易单独验证逻辑是否正确。// services/NoteService.etsimport{NoteData,NoteFilter,ExportConfig}from../models/NoteModel.etsclassNoteService{// 从存储读取笔记列表getNoteList():NoteData[]{constrawAppStorage.getstring(note_list)if(!raw)return[]try{returnJSON.parse(raw)asNoteData[]}catch{return[]}}// 根据筛选条件过滤笔记filterNotes(notes:NoteData[],filter:NoteFilter):NoteData[]{returnnotes.filter(note{// 关键词匹配标题和内容if(filter.keyword){constqfilter.keyword.toLowerCase()if(!note.title.toLowerCase().includes(q)!note.content.toLowerCase().includes(q)){returnfalse}}// 标签过滤if(filter.tag!note.tags.includes(filter.tag)){returnfalse}// 归档笔记if(!filter.showArchivednote.isArchived){returnfalse}returntrue})}// 创建新笔记createNote(title:string):NoteData{constnote:NoteData{id:Date.now(),title:title||无标题,content:,tags:[],isPinned:false,isArchived:false,createdAt:Date.now(),updatedAt:Date.now()}returnnote}// 导出笔记为 MarkdownexportToMarkdown(notes:NoteData[],config:ExportConfig):string{constfilteredthis.filterNotes(notes,{keyword:,tag:null,showArchived:config.includeArchived})returnfiltered.map(n#${n.title}\n\n**标签**:${n.tags.join(, )||无}\n**更新时间**:${newDate(n.updatedAt).toLocaleString()}\n\n${n.content}\n\n---\n).join(\n)}}exportconstnoteServicenewNoteService()业务逻辑抽离之后组件代码变得非常简洁只需要调用服务方法并更新状态// pages/NoteList.etsimport{noteService}from../services/NoteService.etsEntryComponentstruct NoteList{Statenotes:NoteData[][]Statefilter:NoteFilter{keyword:,tag:null,showArchived:false}aboutToAppear(){this.notesnoteService.getNoteList()}getfilteredNotes():NoteData[]{returnnoteService.filterNotes(this.notes,this.filter)}addNote(){constnewNotenoteService.createNote(新笔记)this.notes.unshift(newNote)AppStorage.setOrCreate(note_list,JSON.stringify(this.notes))}}五、组件通信从父子到跨层级ArkUI 的组件通信有几种典型场景父子组件通过属性和方法通信、兄弟组件通过父组件中转、跨层级的深层组件通信。父子通信最简单父组件给子组件传数据用Prop子组件通知父组件用回调函数// 父组件StateselectedId:number0ListItem({note:note,isSelected:this.selectedIdnote.id,onTap:(){this.selectedIdnote.id}})// 子组件Propnote:NoteDataPropisSelected:booleanonTap:()void// 子组件内部触发父组件回调.onClick(()this.onTap())跨层级通信有两种方案。方案一是状态提升把需要共享的状态放到最近的公共祖先组件中通过层层传递到达目标组件。这种方式简单直接但层级深了之后传参链变得很长代码维护困难。方案二是用AppStorage或LocalStorage作为全局状态容器任何组件都可以直接读写不需要层层传递。缺点是状态来源不够直观调试时需要追踪哪里改了值。// 方案二在任意组件中直接访问全局状态aboutToAppear(){constsettingsAppStorage.getUserSettings(user_settings)if(settings)this.settingssettings}// 任何地方修改全局生效AppStorage.setOrCreate(user_settings,this.settings)推荐的做法是分层管理页面级状态用State管理跨页面共享但不需要持久化的状态用AppStorage需要持久化的数据放存储服务中。六、完整工程示例把上述思路整合起来一个最小可用的笔记应用架构如下// models/NoteModel.ets exportinterfaceNoteData{id:number;title:string;content:stringtags:string[];isPinned:boolean;isArchived:booleancreatedAt:number;updatedAt:number}// services/NoteService.ets import{NoteData}from../models/NoteModel.etsclassNoteService{getList():NoteData[]{constrawAppStorage.getstring(notes)returnraw?JSON.parse(raw)asNoteData[]:[]}save(notes:NoteData[]){AppStorage.setOrCreate(notes,JSON.stringify(notes))}}exportconstnoteServicenewNoteService()// pages/NoteList.ets import{noteService}from../services/NoteService.etsEntryComponentstruct NoteList{Statenotes:NoteData[][]aboutToAppear(){this.notesnoteService.getList()}build(){Column(){Row(){Text(共${this.notes.length}条).fontSize(14).fontColor(#888)Blank()Button(新建).onClick((){this.notes.unshift({id:Date.now(),title:新笔记,content:,tags:[],isPinned:false,isArchived:false,createdAt:Date.now(),updatedAt:Date.now()})noteService.save(this.notes)})}.padding(16)List({space:8}){ForEach(this.notes,(note:NoteData){ListItem().child(Row({space:12}){Column(){Text(note.title).fontSize(16).fontWeight(FontWeight.Medium)}.layoutWeight(1)Text(note.tags.join(,)||无标签).fontSize(12).fontColor(#007DFF)}.padding(14).backgroundColor(#FFF).borderRadius(10))})}.padding({left:16,right:16})}.width(100%).height(100%).backgroundColor(#F5F5F5)}}七、实战建议架构没有标准答案只有适合和不适合。中小型应用不需要过度设计三个模块models、services、pages足够支撑日常迭代。业务变复杂后再按需拆分服务层、引入状态管理库。判断要不要抽成一个服务的标准很简单如果这个逻辑会被两个以上的地方调用就应该抽出来。孤立的页面逻辑放在组件里即可不必强行模块化。组件拆分不是越细越好。把一个组件拆成十个原子组件名称取来取去开发体验反而变差。优先拆复用率最高的公共部分比如笔记卡片、列表项、操作按钮组其他业务耦合强的部分保持内聚。基于 HarmonyOS NEXTAPI 12。

相关新闻

【Springboot毕设全套源码+文档】基于springboot云南省旅游信息平台设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于springboot云南省旅游信息平台设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/10 1:07:52 阅读更多 →
JGB37-520 电机选型与TB6612驱动:3种减速比实测与12V供电方案对比

JGB37-520 电机选型与TB6612驱动:3种减速比实测与12V供电方案对比

JGB37-520 电机选型与TB6612驱动:3种减速比实测与12V供电方案对比在平衡小车开发中,电机选型和驱动电路设计是决定系统性能的关键因素。JGB37-520作为一款带霍尔编码器的直流减速电机,凭借其紧凑结构和精准转速反馈,成为许多开发者…

2026/7/10 1:03:51 阅读更多 →
Windows 11电池续航终极指南:如何用EnergyStarX轻松延长30%使用时间

Windows 11电池续航终极指南:如何用EnergyStarX轻松延长30%使用时间

Windows 11电池续航终极指南:如何用EnergyStarX轻松延长30%使用时间 【免费下载链接】EnergyStarX 🔋 Improve your Windows 11 devices battery life. A WinUI 3 GUI for https://github.com/imbushuo/EnergyStar. 项目地址: https://gitcode.com/gh_…

2026/7/10 1:01:51 阅读更多 →

最新新闻

OpenCode:本地AI编程工作流的重新定义

OpenCode:本地AI编程工作流的重新定义

1. OpenCode不是“另一个VS Code插件”,而是本地AI编程工作流的重新定义 OpenCode 这个名字最近在开发者圈子里冒得很快,但很多人点开 GitHub 仓库第一眼就愣住:它既不是 VS Code 的扩展,也不依赖任何云端 API,甚至不…

2026/7/10 2:06:05 阅读更多 →
行测逻辑论证 4 大题型:归因、质疑、支持、解释类题目 10 分钟速通技巧

行测逻辑论证 4 大题型:归因、质疑、支持、解释类题目 10 分钟速通技巧

行测逻辑论证四大题型速通指南:归因、质疑、支持、解释类题目实战解析考场上的每一秒都弥足珍贵,尤其是面对行测中烧脑的逻辑论证题时。经历过三次公考的老张曾告诉我:"逻辑论证题就像迷宫,掌握了地图的人总能先找到出口。&q…

2026/7/10 2:06:05 阅读更多 →
网工毕业设计2026方向大全

网工毕业设计2026方向大全

1 引言 毕业设计是大家学习生涯的最重要的里程碑,它不仅是对四年所学知识的综合运用,更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要,它应该既能体现你的专业能力,又能满足实际应用需求&#xf…

2026/7/10 2:04:05 阅读更多 →
华为防火墙双机热备 HRP 协议深度解析:从心跳报文到状态同步的5个关键机制

华为防火墙双机热备 HRP 协议深度解析:从心跳报文到状态同步的5个关键机制

华为防火墙双机热备 HRP 协议深度解析:从心跳报文到状态同步的5个关键机制在企业级网络安全架构中,防火墙的高可用性设计直接关系到业务连续性。华为HRP(Huawei Redundancy Protocol)作为双机热备的核心协议,通过精细化…

2026/7/10 2:04:05 阅读更多 →
EulerCopilot Web核心功能解析:智能对话、知识检索与应用中心全攻略

EulerCopilot Web核心功能解析:智能对话、知识检索与应用中心全攻略

EulerCopilot Web核心功能解析:智能对话、知识检索与应用中心全攻略 【免费下载链接】euler-copilot-web The web frontend of EulerCopilot 项目地址: https://gitcode.com/openeuler/euler-copilot-web 前往项目官网免费下载:https://ar.openeu…

2026/7/10 2:02:05 阅读更多 →
2026注塑工厂水电气选型白皮书_合肥工厂合规降本实战指南

2026注塑工厂水电气选型白皮书_合肥工厂合规降本实战指南

2026注塑工厂水电气选型白皮书:合肥工厂合规降本实战指南 合肥注塑工厂在新建或扩产时,水电气系统的选型失误会直接拉高5年综合成本30%以上。合肥作为长三角西翼制造中心和安徽省会,享受安徽省工业节能技改补贴政策,但夏季高温内陆…

2026/7/10 2:00:04 阅读更多 →

日新闻

STM32与LTC1864高精度ADC的SPI通信实现

STM32与LTC1864高精度ADC的SPI通信实现

1. 项目背景与核心需求在工业控制和嵌入式系统开发中,模拟信号与数字系统的无缝集成一直是工程师面临的关键挑战。LTC1864作为一款16位高精度ADC转换器,配合STM32F101ZG这类主流微控制器,能够构建高性能的模拟信号采集系统。这种组合特别适合…

2026/7/10 0:03:07 阅读更多 →
猫抓插件:浏览器资源嗅探与视频下载的终极解决方案

猫抓插件:浏览器资源嗅探与视频下载的终极解决方案

猫抓插件:浏览器资源嗅探与视频下载的终极解决方案 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为网页视频无法下载而烦恼吗&am…

2026/7/10 0:05:09 阅读更多 →
直流有刷电机驱动方案:TC78H653FTG与MKV46F256VLH16应用

直流有刷电机驱动方案:TC78H653FTG与MKV46F256VLH16应用

1. 直流有刷电机驱动方案概述在工业自动化和消费电子领域,直流有刷电机因其结构简单、控制方便、成本低廉等优势,仍然是许多应用场景的首选驱动方案。TC78H653FTG作为东芝推出的新一代H桥驱动器,与MKV46F256VLH16微控制器配合使用&#xff0c…

2026/7/10 0:05:09 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/9 13:46:46 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/9 21:41:05 阅读更多 →

月新闻