Vue 3 + Canvas 便利贴实战:交互分层、本地存储与发布验证
一个可以直接打开的便利贴项目
「漂浮便利贴」是一个本地待办应用的 Web 展示版:创建不同颜色的便签,在画布上拖动位置,通过撕纸手势完成事项,再从历史页恢复。项目使用 Vue 3、TypeScript、Pinia 和 Canvas 2D,浏览器版本不需要注册账号,也不依赖后端服务。
这篇文章结合公开源码,记录交互、业务和存储分层的做法,以及发布前实际检查过的行为。它适合想把普通表单练习扩展成可操作小工具的前端开发者。
完整源码与在线体验入口见华为云开发者作品展览馆中的《漂浮便利贴》(作品编号:00816b70ce001000)。公开源码仓库为 M-C-Kai/sticky-note-gallery。
1. 先把画布反馈与业务操作分开
便利贴界面有两类变化。第一类是位置、阴影、漂浮和撕纸反馈;第二类是创建、编辑、完成和恢复记录。前者需要频繁绘制,后者需要更新业务状态并保存数据。
项目用 NoteCanvas 组件接收浏览器 Pointer 事件,再交给 CanvasEngine 处理布局、命中与动画。Vue 页面和组件负责编辑器、历史列表、设置面板等常规界面。这样不必把每一帧动画都变成表单状态更新,也便于分别检查「画面有没有动」和「事项是否真的完成」。
交互时还要区分点按、拖拽和撕纸。点按打开编辑器,拖拽改变便签锚点,从底部撕纸区域向下拉动达到阈值后才提交完成动作。这里的关键是让手势反馈和最终业务提交各有明确的位置,避免用户只是拖动便签就误完成事项。
项目的分层关系可以概括为:
Vue 页面与组件 → Pinia 状态、应用服务 → Repository 接口 → 存储适配器
NoteCanvas → CanvasEngine → 布局、手势、运动模块、Canvas 绘制
其中应用层的 NoteService 依赖 NoteRepository,而不直接访问 localStorage。源码中的创建和保存入口很简洁:
async create(input: CreateNoteInput): Promise<Note> {
return this.repo.create(input)
}
async save(id: string, patch: UpdateNoteInput): Promise<Note> {
return this.repo.update(id, patch)
}
这个例子展示的是调用边界,而不是把复杂操作藏进组件。存储实现发生变化时,页面不必同时改写读写细节。
2. 明确 Web 展示版的数据保存方式
仓库保留了平台适配接口,repositoryFactory 会根据 Capacitor.isNativePlatform() 选择实现。当前公开的 Web 演示走 LocalStorageNoteRepository,不能因为依赖里有 SQLite 就把浏览器版描述成 SQLite 应用。
LocalStorageNoteRepository 继承内存仓储,启动时从 stickynote.notes.v1 读取记录;创建、更新、完成、恢复与永久删除之后,再把内存记录序列化保存。持久化核心如下:
private persist(): void {
try {
localStorage.setItem(
STORAGE_KEY,
JSON.stringify([...this.notes.values()])
)
} catch {
// 存储不可用或超出配额时,当前状态仍保留在内存中
}
}
这个实现适合体量较小的本地工具,但有清晰的边界:浏览器站点数据被清理后,便签也会丢失;不同设备和不同浏览器之间不会自动同步;存储写入失败时,本次会话中的界面状态也不能证明刷新后仍能恢复。
因此,使用时应把重要事项另行备份。后续若继续完善,值得优先补充的是保存失败提示与数据导入导出,让用户知道数据处于什么状态。
3. 发布之前,验证用户能否走完一个循环
单元测试和浏览器操作解决的问题不同。测试可以帮助检查布局、手势判断、运动模块、业务服务和仓储;真实页面操作则用来检查这些部分组合后能否完成一项实际任务。
2026 年 11 月 9 日的发布准备中,7 个测试文件、43 项单元测试通过,生产类型检查与构建通过。浏览器里实际走过的流程是:
- 新增三张不同颜色的便签,编辑内容并保存。
- 刷新页面,确认便签记录重新加载。
- 拖动便签,检查位置变化。
- 使用底部撕纸手势完成一项事项。
- 进入历史页查看完成记录,再恢复到主画布。
- 打开设置页,确认 Web 端显示 LocalStorage 已就绪。
这些结果对应的是当前 Web 展示版。公开仓库没有包含 Android/iOS 原生工程,本文也不把这些浏览器检查扩展成原生安装包、桌面组件或云端同步的验收结论。
4. 本地运行与静态部署
建议安装 Node.js 22 或更新版本,然后在仓库根目录执行:
npm ci
npm run dev
检查和构建使用以下命令:
npm test
npm run build
npm run preview
build 脚本先执行 vue-tsc --noEmit,再执行 Vite 构建,产物输出到 dist。项目使用 History 路由,部署到普通静态服务器时,需要处理子路径访问并回退至 index.html。如果托管在类似 /sticky-note-gallery/ 的子目录,还要设置正确的构建 base,避免页面打开后资源路径出错。
这次整理项目最有用的经验,是把交互反馈、业务操作与持久化分别验证,再用「创建—编辑—完成—恢复—刷新」的实际操作把它们串起来。一个小工具的功能可以不多,但保存边界、运行方法和已验证范围应该让使用者看得清楚。
说明:本文由 AI 辅助整理,项目结构、代码片段及验收描述均依据当前公开仓库和本次实际操作记录核对。
- 点赞
- 收藏
- 关注作者
评论(0)