open harmony 项目实战:从 0 到 1 搭建一款语文学习 App
open harmony 项目实战:从 0 到 1 搭建一款语文学习 App
最近我用 OpenHarmony + ArkTS 做了一款语文学习类应用,名字叫“语文视界”。它不是一个单纯的 Demo,而是包含首页推荐、诗词鉴赏、阅读、字典、学习中心、收藏记录、个人中心等多个模块的小型完整项目。📚
这篇文章作为系列开篇,主要聊聊项目整体架构:一个 OpenHarmony 学习类 App 从功能规划到目录组织,再到页面流转,应该怎么搭起来。
一、项目定位
“语文视界”的核心目标是让用户可以在手机或平板上完成轻量语文学习:
- 首页:展示今日推荐、快速入口、学习数据。
- 诗词:支持年级、朝代筛选,进入详情页查看注释、译文、赏析。
- 阅读:提供名著、散文、古文、诗词鉴赏等阅读内容。
- 字典:支持汉字与成语查询。
- 学习:提供每日打卡、诗词默写、诗词配对、朝代排序。
- 我的:展示收藏数、阅读记录、学习天数和反馈入口。
这样的模块设计比较适合 OpenHarmony 入门进阶:既有页面 UI,也有状态管理、数据检索、交互反馈和响应式适配。
二、项目目录结构
项目核心代码集中在 entry/src/main/ets:
entry/src/main/ets
├── common
│ ├── components
│ ├── constants
│ └── utils
├── data
├── entryability
├── entrybackupability
├── model
├── pages
│ ├── dictionary
│ ├── home
│ ├── learn
│ ├── my
│ ├── poetry
│ └── reading
└── viewmodel
我个人很喜欢这种分层方式:页面归页面,数据归数据,公共组件和工具类单独放,后续维护时不会乱成一团。
三、主入口页面的职责
项目的主入口是 Index.ets。它不是只展示首页,而是承担了“轻量路由容器”的角色。
核心状态有两个:
@State currentTabIndex: number = 0;
@State currentView: string = 'home';
currentTabIndex 控制底部导航选中项,currentView 控制当前展示哪个页面。比如进入诗词详情页时,会把当前页面记录为上一页,再写入目标页面状态:
private navToPoetryDetail(poetryId: number): void {
AppStorage.setOrCreate('prev_view', this.currentView);
AppStorage.setOrCreate('nav_poetry_id', poetryId);
AppStorage.setOrCreate('current_view', 'poetry_detail');
this.currentView = 'poetry_detail';
}
这样做不需要引入很复杂的路由系统,也能满足中小型 App 的页面跳转需求。
四、六大一级页面
底部导航包含 6 个一级入口:
this.buildTabItem(0, '首页', $r('app.media.ic_home_normal'), $r('app.media.ic_home_selected'));
this.buildTabItem(1, '诗词', $r('app.media.ic_poetry_normal'), $r('app.media.ic_poetry_selected'));
this.buildTabItem(2, '阅读', $r('app.media.ic_reading_normal'), $r('app.media.ic_reading_selected'));
this.buildTabItem(3, '字典', $r('app.media.ic_dict_normal'), $r('app.media.ic_dict_selected'));
this.buildTabItem(4, '学习', $r('app.media.ic_learn_normal'), $r('app.media.ic_learn_selected'));
this.buildTabItem(5, '我的', $r('app.media.ic_my_normal'), $r('app.media.ic_my_selected'));
这 6 个模块基本覆盖了学习类 App 的主要流程:发现内容、学习内容、检索内容、练习巩固、查看个人数据。
五、数据层设计
项目的数据文件放在 data 目录下:
poetry_data.ets:诗词数据。reading_data.ets:阅读数据。dictionary_data.ets:成语数据。char_data.ets:汉字数据。learn_quiz_data.ets:学习题库。
本地数据的好处是启动快、离线可用、功能稳定。对于学习类 App 来说,早期不一定非要先接后端,先把内容结构和体验跑通更重要。
六、ViewModel 负责业务逻辑
诗词模块使用了 PoetryViewModel 统一管理收藏、历史、筛选、推荐等逻辑。
export class PoetryViewModel {
private favoriteIds: number[] = [];
private readHistoryIds: number[] = [];
private poetryCache: Map<number, Poetry> = new Map<number, Poetry>();
constructor() {
this.buildCache();
this.loadFavorites();
this.loadReadHistory();
}
}
这样页面层不用关心数据怎么存、怎么查,只需要调用 ViewModel 方法即可。页面会更干净,也更容易继续扩展。
七、视觉风格
项目整体采用暖色背景、圆角卡片、柔和图标和轻量动效。对于语文学习应用来说,这种风格比冷冰冰的工具型界面更适合。
比如主题色集中在 ThemeColors.ets 中:
get backgroundColor(): string {
return this.isDark ? '#1A1A2E' : '#FFF9F0';
}
get cardBackground(): string {
return this.isDark ? '#2D2D44' : '#FFFFFF';
}
统一主题后,页面就不需要到处写颜色值,后期调整风格也方便。
八、适合放的截图
建议在 CSDN 文章里放这些图:
- 首页截图:展示整体风格。
- 诗词详情页截图:展示内容阅读体验。
- 学习中心截图:展示打卡与学习模块。
- 我的页面截图:展示数据看板。
图文结合后,读者会更容易理解这个项目不是简单页面拼接,而是一个完整学习 App。
总结
这个项目的搭建思路可以概括为:先确定学习场景,再拆模块,再用 Index.ets 做页面容器,用 AppStorage 做轻量状态流转,用 ViewModel 管业务逻辑,最后通过主题系统和动效提升完成度。
对于想学习 OpenHarmony 的同学来说,这类项目非常适合练手:不依赖复杂服务端,却能覆盖 UI、状态、数据、交互、适配等多个知识点。🚀

更多推荐

所有评论(0)