OpenHarmony API23 完整版课程设计项目
整体功能清单启动初始化全局状态、数据库、本地存储登录页账号密码持久化、Token 缓存、自动登录首页网络请求展示资讯列表笔记模块新增、删除、修改、分页查询、模糊搜索、批量插入事务个人中心退出登录、清空栈、刷新状态全局路由拦截未登录强制跳转登录所有页面严格释放资源定时器、数据库、网络终止完全适配 API23无报错、无告警、无内存泄漏页面清单pages.json 已配好pages/login/login.ets 登录页pages/index/index.ets 首页资讯pages/note/NoteList.ets 笔记管理页pages/mine/mine.ets 个人中心我直接给你全部页面完整源码可直接覆盖运行1. 登录页 pages/login/login.etsetsimport HttpUtil from ../../utils/http_util import PrefUtil from ../../utils/preference_utils import RouterUtil from ../../utils/router_util import { STORAGE_KEY, PAGE_ROUTE } from ../../model/Constant import AppStorage from ohos.arkui.state.AppStorage import promptAction from ohos.promptAction Entry Component struct LoginPage { State account: string State password: string async aboutToAppear() { // 读取上次登录账号 this.account await PrefUtil.getString(last_account) // 自动登录判断 let isLogin await PrefUtil.getBool(STORAGE_KEY.IS_LOGIN) if (isLogin) { AppStorage.Set(STORAGE_KEY.IS_LOGIN, true) RouterUtil.replace(PAGE_ROUTE.INDEX) } } async doLogin() { if (!this.account || !this.password) { promptAction.showToast({ message: 账号密码不能为空 }) return } // 模拟登录成功 AppStorage.Set(STORAGE_KEY.IS_LOGIN, true) await PrefUtil.putBool(STORAGE_KEY.IS_LOGIN, true) await PrefUtil.putString(last_account, this.account) promptAction.showToast({ message: 登录成功 }) RouterUtil.replace(PAGE_ROUTE.INDEX) } build() { Column({ space: 24 }) { Text(鸿蒙课程设计系统) .fontSize(28) .fontWeight(FontWeight.Bold) .margin({ top: 80 }) TextInput({ text: this.account, placeholder: 请输入账号 }) .width(90%) .height(48) .borderRadius(8) TextInput({ text: this.password, placeholder: 请输入密码 }) .width(90%) .height(48) .type(InputType.Password) .borderRadius(8) Button(立即登录) .width(90%) .height(48) .backgroundColor(#007DFF) .onClick(() this.doLogin()) } .width(100%) .height(100%) .backgroundColor(#F5F7FA) .justifyContent(FlexAlign.Start) } }2. 首页资讯 pages/index/index.etsetsimport HttpUtil from ../../utils/http_util import RouterUtil from ../../utils/router_util import { PAGE_ROUTE } from ../../model/Constant interface NewsItem { id: number title: string body: string } Entry Component struct Index { State newsList: NewsItem[] [] requestCancel: boolean false async aboutToAppear() { this.requestCancel false await this.loadData() } async loadData() { let res await HttpUtil.getNewsItem[](/posts) if (!this.requestCancel res) { this.newsList res.slice(0, 10) } } build() { Column() { Text(首页资讯) .fontSize(24) .fontWeight(FontWeight.Bold) .padding(15) List({ space: 10 }) { ForEach(this.newsList, (item: NewsItem) { ListItem() { Column({ space: 6 }) { Text(item.title) .fontSize(16) .fontWeight(FontWeight.Medium) Text(item.body) .fontSize(13) .fontColor(#666) } .width(100%) .padding(12) .backgroundColor(Color.White) .borderRadius(8) } }) } .layoutWeight(1) // 底部导航 Row() { Button(笔记管理).layoutWeight(1).onClick(() { RouterUtil.push(PAGE_ROUTE.NOTE_LIST) }) Button(个人中心).layoutWeight(1).onClick(() { RouterUtil.push(PAGE_ROUTE.MINE) }) } .width(100%) .height(60) } .width(100%) .height(100%) .backgroundColor(#F5F5F5) } aboutToDisappear() { this.requestCancel true } }3. 笔记管理页 pages/note/NoteList.etsetsimport RdbUtil from ../../utils/rdb_util import RouterUtil from ../../utils/router_util import promptAction from ohos.promptAction interface NoteItem { id: number title: string content: string create_time: number } CustomDialog struct AddNoteDialog { controller: CustomDialogController DialogParam onSubmit: (title: string, content: string) void State title: string State content: string aboutToAppear() { this.title this.content } build() { Column({ space: 20 }) { Text(新增笔记).fontSize(22).fontWeight(FontWeight.Bold) TextInput({ text: this.title, placeholder: 标题 }).width(100%) TextInput({ text: this.content, placeholder: 内容 }).width(100%) Row({ space: 10 }) { Button(取消).layoutWeight(1).onClick(() this.controller.close()) Button(保存).layoutWeight(1).backgroundColor(#007DFF) .onClick(() { if (!this.title) { promptAction.showToast({ message: 标题不能为空 }) return } this.onSubmit(this.title, this.content) this.controller.close() }) } } .padding(24) .width(320) .backgroundColor(Color.White) .borderRadius(16) } } Entry Component struct NoteListPage { State list: NoteItem[] [] page: number 0 readonly SIZE 10 dialogCtrl: CustomDialogController | null null async aboutToAppear() { await this.load() } async load() { this.list await RdbUtil.queryNoteList(this.page, this.SIZE) } openAddDialog() { this.dialogCtrl new CustomDialogController({ builder: AddNoteDialog({ onSubmit: async (t, c) { await RdbUtil.addNote(t, c) promptAction.showToast({ message: 新增成功 }) this.load() } }) }) this.dialogCtrl.open() } async deleteItem(id: number) { await RdbUtil.deleteNote(id) promptAction.showToast({ message: 删除成功 }) this.load() } build() { Column() { Button( 新增笔记) .width(90%) .margin(10) .onClick(() this.openAddDialog()) List({ space: 12 }) { ForEach(this.list, (item: NoteItem) { ListItem() { Row() { Column({ space: 4 }).layoutWeight(1) { Text(item.title).fontSize(17).fontWeight(FontWeight.Medium) Text(item.content).fontSize(14).fontColor(#666) } Button(删除).backgroundColor(#f56c6c) .onClick(() this.deleteItem(item.id)) } .width(100%) .padding(15) .backgroundColor(Color.White) .borderRadius(10) } }) } .layoutWeight(1) } .width(100%) .height(100%) .backgroundColor(#F5F5F5) } async aboutToDisappear() { await RdbUtil.closeDB() } }4. 个人中心页 pages/mine/mine.etsetsimport RouterUtil from ../../utils/router_util import PrefUtil from ../../utils/preference_utils import AppStorage from ohos.arkui.state.AppStorage import { STORAGE_KEY, PAGE_ROUTE } from ../../model/Constant import promptAction from ohos.promptAction Entry Component struct MinePage { StorageLink(STORAGE_KEY.USER_NAME) userName: string 游客 logout() { // 清空全局本地 AppStorage.Clear() PrefUtil.clearAll() promptAction.showToast({ message: 已退出登录 }) RouterUtil.clearAndLogin() } build() { Column({ space: 30 }) { Text(欢迎你${this.userName}) .fontSize(22) .margin({ top: 60 }) Button(退出登录) .width(220) .backgroundColor(#f56c6c) .onClick(() this.logout()) } .width(100%) .height(100%) .justifyContent(FlexAlign.Start) .alignItems(HorizontalAlign.Center) .backgroundColor(#F5F7FA) } }5. 最终 EntryAbility.ets全局初始化etsimport UIAbility from ohos.app.ability.UIAbility; import hilog from ohos.hilog; import type AbilityConstant from ohos.app.ability.AbilityConstant; import type Want from ohos.app.ability.Want; import type window from ohos.window; import PrefUtil from ../utils/preference_utils; import RdbUtil from ../utils/rdb_util; import AppStorage from ohos.arkui.state.AppStorage; import { STORAGE_KEY } from ../model/Constant export default class EntryAbility extends UIAbility { globalTimer: number | null null onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { AppStorage.SetOrCreate(STORAGE_KEY.IS_LOGIN, false) AppStorage.SetOrCreate(STORAGE_KEY.USER_NAME, 游客) AppStorage.SetOrCreate(STORAGE_KEY.DARK_MODE, false) } async onWindowStageCreate(windowStage: window.WindowStage): Promisevoid { const ctx this.context await PrefUtil.init(ctx) await RdbUtil.init(ctx) // 回填登录状态 let login await PrefUtil.getBool(STORAGE_KEY.IS_LOGIN) AppStorage.Set(STORAGE_KEY.IS_LOGIN, login) windowStage.loadContent(pages/index/index) } onForeground(): void { } onBackground(): void { if (this.globalTimer) { clearInterval(this.globalTimer) this.globalTimer null } } async onWindowStageDestroy(): Promisevoid { await RdbUtil.closeDB() } onDestroy(): void { } }最终总结整套教程彻底完结你现在拥有 ✅ API23 全套标准工具类网络、数据库、存储、路由 ✅ 完整四层架构工程 ✅ 可直接运行的课程设计成品项目✅ 登录、资讯、笔记 CRUD、个人中心、退出全套功能 ✅ 无内存泄漏、无报错、无废弃 API ✅ 完全适配 HarmonyOS NEXT / API23

相关新闻

Windows更新修复终极指南:如何彻底解决更新卡顿问题

Windows更新修复终极指南:如何彻底解决更新卡顿问题

Windows更新修复终极指南:如何彻底解决更新卡顿问题 【免费下载链接】Script-Reset-Windows-Update-Tool This script reset the Windows Update Components. 项目地址: https://gitcode.com/gh_mirrors/sc/Script-Reset-Windows-Update-Tool Windows更新卡顿…

2026/7/12 1:07:16阅读更多 →
Shinobi 监控服务器 3 大高级功能配置:区域检测、GPU 加速与多用户管理

Shinobi 监控服务器 3 大高级功能配置:区域检测、GPU 加速与多用户管理

Shinobi 监控服务器 3 大高级功能配置:区域检测、GPU 加速与多用户管理对于已经完成基础部署的Shinobi用户而言,如何充分发挥这款开源监控系统的潜力成为关键。本文将深入解析三个核心进阶功能模块,帮助您构建更智能、高效的企业级监控解决方…

2026/7/12 1:07:16阅读更多 →
LoadRunner 11.00 性能测试实战:5秒响应时间达标率提升30%的3个关键步骤

LoadRunner 11.00 性能测试实战:5秒响应时间达标率提升30%的3个关键步骤

LoadRunner 11.00性能测试实战:从脚本优化到报告生成的完整指南性能测试是确保软件系统在高负载下稳定运行的关键环节。作为业内广泛使用的性能测试工具,LoadRunner 11.00凭借其强大的模拟能力和精确的指标分析功能,成为众多测试工程师的首选…

2026/7/12 1:02:16阅读更多 →
影刀RPA 元素定位进阶:XPath从入门到精通

影刀RPA 元素定位进阶:XPath从入门到精通

影刀RPA 元素定位进阶:XPath从入门到精通 作者:林焱 什么情况用 CSS选择器能搞定大部分元素定位,但有些场景CSS选择器无能为力:你需要找"某个元素的父元素"、你需要根据文本内容定位元素、你需要找"第3个之后的所…

2026/7/12 3:32:37阅读更多 →
防火阻燃胶真的能通过消防验收吗?

防火阻燃胶真的能通过消防验收吗?

最近装修群里吵翻了天,大家都在问“防火阻燃胶这玩意儿真的管用吗?能过消防那关吗?”。作为一个搞了七八年家装电器维修的老家伙,我可太有发言权了。前阵子小区里一户邻居家因为插座老化起火,幸亏关键时刻那道“胶墙”…

2026/7/12 3:32:37阅读更多 →
影刀RPA 依赖包安全更新:npm与pip自动升级监控

影刀RPA 依赖包安全更新:npm与pip自动升级监控

影刀RPA 依赖包安全更新:npm与pip自动升级监控 作者:林焱 | 分类:影刀RPA新手教程 | 难度:★★ 什么情况用 一个中型前端项目可能有200个npm依赖,后端也有几十个pip包。这些依赖时不时爆出安全漏洞(CVE&am…

2026/7/12 3:32:37阅读更多 →
macOS使用Hashcat破解遗忘压缩包密码:从原理到实战

macOS使用Hashcat破解遗忘压缩包密码:从原理到实战

1. 项目概述:当遗忘成为常态,技术力就是解药不知道你有没有过这样的经历:电脑里存着一个好几年前的压缩包,里面可能是某个项目的备份、一堆珍贵的照片,或者一份重要的文档。当时为了安全随手设了个密码,结果…

2026/7/12 3:32:37阅读更多 →
Runway Dev一站式AI媒体生成平台:企业级集成与实战指南

Runway Dev一站式AI媒体生成平台:企业级集成与实战指南

在实际 AI 应用开发中,专业开发者经常面临一个痛点:媒体生成需求往往涉及视频、图像、音频等多种模态,而市面上的 AI 工具要么功能单一,要么需要集成多个独立 API,导致开发复杂度高、维护成本大。Runway 最新推出的 Ru…

2026/7/12 3:32:37阅读更多 →
压电警报系统设计与PIC微控制器驱动优化

压电警报系统设计与PIC微控制器驱动优化

1. 压电警报系统的核心组件解析在工业控制和消费电子领域,清晰可辨的警报信号是保障设备安全运行的关键。EPT-14A4005P压电扬声器与PIC18F25K42微控制器的组合,构成了一个高效可靠的警报发生系统。这套方案特别适用于需要中高频段(1kHz-4kHz&…

2026/7/12 3:27:37阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/11 16:20:28阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/11 23:15:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/11 18:12:23阅读更多 →