前言
在快节奏的数字时代,古诗词仿佛一缕清泉,润泽着浮躁的心灵。“墨韵诗笺”便是一款以水墨风格呈现的单机古诗词鉴赏应用,收录了从先秦到清代共 500 首经典诗词,旨在为用户打造一座掌上诗词桃源。它不仅提供了朝代分类浏览、卡片翻转译注、本地收藏书架等核心体验,更通过细腻的水墨视觉和流畅的交互,让古典之美在现代屏幕上复活。
本文将深入剖析“墨韵诗笺”的设计与架构,从整体蓝图到细枝末节,逐一解读技术选型背后的思考、数据流动的路径以及 UI 设计的美学逻辑,帮助开发者或技术爱好者建立起完整的认知框架。
完成后的效果如下图所示:





第一章 项目概述与核心特性
1.1 项目定位
“墨韵诗笺”是一款纯单机、离线可用的诗词鉴赏工具,支持 Web 端浏览和 Android APK 打包。它不依赖网络,所有诗词数据、收藏记录、用户偏好均存储在本地,充分保障了隐私和访问速度。
1.2 核心特性一览
- 500 首经典诗词:六大朝代(先秦、唐、宋、元、明、清)全覆盖,含原文、白话译文、字词注释。
- 水墨风视觉设计:宣纸米白底、青花瓷蓝与朱砂红点缀,搭配朝代徽章、3D 翻转卡片、竖排切换,沉浸感十足。
- 虚拟滚动列表:支持 500 首规模流畅浏览,不卡顿。
- 灵活筛选与搜索:关键词搜索、仅看收藏切换,快速定位心仪诗词。
- 本地收藏书架:支持批量管理,数据持久化于 LocalStorage。
- 单页应用(SPA):视图切换平滑,离线可用,可打包为 Android APK。
这些特性共同构成了一个轻量、优雅、功能完整的诗词应用,而这一切都建立在一个精心设计的系统架构之上。
第二章 系统架构总览
2.1 整体架构
“墨韵诗笺”采用经典的前后端分离(但后端极简)的架构,客户端基于 Next.js 构建,服务端仅提供静态服务或可选的轻量 API。整体架构如下图所示:
核心设计理念:
- 客户端为主:所有业务逻辑、数据管理、UI 渲染均在客户端完成,服务端仅作为可选的静态托管或 API 网关。
- 构建模式双轨制:通过环境变量
BUILD_APK控制输出模式——Web 部署使用standalone服务,APK 打包使用export静态导出。 - 数据本地优先:诗词数据通过 JSON 文件打包进应用,收藏和偏好存储在 LocalStorage,真正实现“开箱即用”。
2.2 构建模式详解
| 模式 | BUILD_APK | Next.js output | 适用场景 |
|---|---|---|---|
| Web 服务端 | 0 (默认) | standalone | 部署在服务器,支持 SSR/API,适合多用户 |
| APK 静态导出 | 1 | export | 生成纯静态 HTML/CSS/JS,供 Capacitor 打包为 Android 应用 |
这样的设计使得同一套代码可以适配两种截然不同的运行环境,且无需改动业务逻辑。
第三章 技术栈选型与理由
选择合适的技术栈是项目成功的关键。“墨韵诗笺”的选型兼顾了开发效率、运行性能和跨端能力,具体如下:
| 层级 | 技术 | 版本 | 选型理由 |
|---|---|---|---|
| 框架 | Next.js | 16.1.1 | 支持 SSR/SSG/静态导出,灵活应对 Web 和 APK 两种模式,内置路由和优化 |
| UI 库 | React | 19.0.0 | 函数组件 + Hooks,生态丰富,适合构建交互密集型 SPA |
| 语言 | TypeScript | 5.x | 类型安全,降低维护成本,提升代码可读性 |
| 样式 | Tailwind CSS | 4.x | 原子化 CSS,快速构建定制化 UI,配合 shadcn/ui 无缝协作 |
| 组件库 | shadcn/ui | latest | 基于 Radix 的无头组件,提供约 50+ 高质量的 UI 基元,完全可控 |
| 状态管理 | Zustand | 5.0.6 | 轻量、简单、无冗余,比 Redux 更易上手,适合中小型应用 |
| 动画 | Framer Motion | 12.23.2 | 强大的声明式动画库,轻松实现页面过渡和卡片翻转等微交互 |
| 数据查询 | @tanstack/react-query | 5.82.0 | 管理异步数据状态,缓存和重试机制完善,提升用户体验 |
| ORM | Prisma | 6.11.1 | 类型安全的数据库操作,配合 SQLite,便于后续扩展用户系统 |
| 移动端打包 | Capacitor | 8.4.1 | 将 Web 应用包装为原生 APK,保留 Web 技术栈,降低移动开发成本 |
| 包管理/运行时 | Bun | 1.3.4 | 快速安装和运行,替代 npm/yarn,提升开发环境体验 |
这些技术共同构建了一个稳健、可维护的现代前端应用,而它们的整合方式将在后续章节详述。
第四章 前端架构设计
前端是用户直接交互的界面,其架构设计直接决定了应用的流畅度和可维护性。
4.1 目录结构(核心部分)
src/
├── app/ # Next.js 路由层(实际采用单页模式)
│ ├── globals.css # 全局水墨主题变量
│ ├── layout.tsx # 根布局(字体、元数据)
│ └── page.tsx # 唯一页面,渲染 AppShell
├── components/
│ ├── poetry/ # 业务组件(视图组件)
│ │ ├── app-shell.tsx # 应用外壳(Header/Footer/视图路由)
│ │ ├── dynasty-overview.tsx # 首页朝代画廊
│ │ ├── poetry-list.tsx # 诗词列表(含搜索/筛选)
│ │ ├── poem-detail.tsx # 详情页(3D 翻转卡片)
│ │ ├── bookshelf.tsx # 收藏书架
│ │ └── virtual-list.tsx # 虚拟滚动实现
│ └── ui/ # shadcn/ui 基础组件(50+)
├── data/ # 数据层
│ ├── types.ts # Poem, Dynasty 等类型定义
│ ├── dynasties.ts # 朝代元数据及色彩映射
│ ├── index.ts # 数据加载器(懒加载 + 缓存)
│ └── *.json # 各朝代诗词数据
├── store/
│ └── poetry-store.ts # Zustand 全局状态
├── lib/ # 工具库
│ ├── storage.ts # LocalStorage 服务(防抖持久化)
│ └── poem-utils.ts # 诗词处理函数
└── hooks/ # 自定义 Hooks
这种结构清晰地将视图、数据、状态和工具分离,使得各模块职责单一,便于测试和协作。
4.2 视图系统与路由逻辑
应用采用单页四视图架构,通过 Zustand 中的 view 状态控制当前显示的组件,并利用 Framer Motion 的 AnimatePresence 实现平滑切换。
| 视图 | view 值 | 组件 | 功能 |
|---|---|---|---|
| 首页 | "home" | DynastyOverview | 展示朝代徽章、总数统计、快捷入口 |
| 列表 | "list" | PoetryList | 朝代 Tab 切换、搜索、虚拟滚动列表 |
| 详情 | "detail" | PoemDetail | 全屏覆盖层,3D 翻转卡片,字体/竖排调节 |
| 书架 | "bookshelf" | Bookshelf | 收藏网格展示,批量管理,搜索 |
路由逻辑(位于 app-shell.tsx)简洁明了:
4.3 组件树分解
为了更直观地理解页面层级,我们可以将 AppShell 下的组件树绘制如下:
该组件树清晰地展示了各视图的构成,保证了代码的组织性和可读性。
4.4 状态管理——Zustand 的巧妙运用
Zustand 作为全局状态管家,承担了应用所有可变数据的存储和更新。其核心状态结构如下:
interface PoetryState {
// 导航
view: 'home' | 'list' | 'detail' | 'bookshelf';
currentDynasty: Dynasty;
// 数据 (惰性加载)
lists: Record<Dynasty, Poem[]>;
loadingDynasty: Dynasty | null;
// 详情
currentPoemId: string | null;
detailList: Poem[]; // 当前详情页所在的列表,用于上下首切换
// 收藏
favorites: string[]; // 收藏的 poem id 数组
// 筛选
searchQuery: string;
onlyFavorites: boolean;
// UI 偏好
fontScale: number;
listScrollTop: number;
// 动作 (Actions)
goHome: () => void;
goBookshelf: () => void;
openDynasty: (dynasty: Dynasty) => void;
switchDynasty: (dynasty: Dynasty) => void;
openDetail: (id: string, list: Poem[]) => void;
closeDetail: () => void;
nextPoem: () => void;
prevPoem: () => void;
toggleFavorite: (id: string) => void;
removeFavorites: (ids: string[]) => void;
setSearchQuery: (q: string) => void;
setOnlyFavorites: (v: boolean) => void;
adjustFontScale: (delta: number) => void;
hydrate: () => void; // 从 localStorage 恢复状态
}
关键设计思考:
- 收藏写入防抖:
toggleFavorite触发后,并不会立即写入 LocalStorage,而是通过一个 300ms 防抖函数批量写入,避免频繁 I/O 影响性能。 - 页面卸载强制刷新:在
hydrate中注册beforeunload和pagehide事件,确保浏览器关闭或刷新时收藏数据已落盘。 - 列表滚动位置记忆:
listScrollTop用于在返回列表时恢复滚动位置,提升浏览连续性。
Zustand 的 selector 模式 也被广泛使用,组件仅订阅自己关心的状态片段,从而避免不必要的重新渲染。
第五章 数据架构与加载策略
5.1 数据模型
诗词数据是应用的核心资产,其模型定义如下:
interface Poem {
id: string; // 如 "T001" (T=唐)
title: string;
author: string;
dynasty: Dynasty; // "唐" | "宋" | ...
content: string; // 原文,\n 分隔
translation: string; // 白话译文
annotation?: string; // 字词注释
background_hint?: string; // 意境提示,用于背景色
sort_order?: number; // 按作者生卒年排序
}
type Dynasty = "唐" | "宋" | "元" | "明" | "清" | "先秦";
每个朝代均独立存储为一个 JSON 文件,文件命名与朝代对应,例如 tang.json 存放唐诗,song.json 存放宋词等。
5.2 存储策略矩阵
| 数据类别 | 存储介质 | 容量估算 | 写入时机 |
|---|---|---|---|
| 诗词正文 | JSON 文件(打包进应用) | ~300KB(6 个文件) | 编译时打包,运行时只读 |
| 收藏列表 | LocalStorage (poetry_favorites) | ~5KB | 防抖 300ms,页面卸载时强制刷新 |
| 字号偏好 | LocalStorage (poetry_font_scale) | ~10B | 用户调节时立即写入 |
| 上次浏览朝代 | LocalStorage (poetry_last_dynasty) | ~10B | 切换朝代时记录 |
| 用户扩展数据 | SQLite(db/custom.db,通过 Prisma) | 可变 | 预留未来扩展 |
5.3 数据加载流程——按需懒加载
为避免首屏加载全部 500 首诗词,我们设计了按朝代懒加载机制,其流程如下:
设计亮点:
- Dynamic Import:仅在需要时加载对应朝代的 JSON,降低首屏资源下载量。
- 内存缓存:加载一次后即存入
Map,后续访问无需重复请求。 - 排序预处理:JSON 文件中原有的
sort_order保证列表按作者生卒年排列,无需前端再计算。
5.4 数据集概览
| 朝代 | 文件 | 数量 | ID 范围 | 文件大小(约) |
|---|---|---|---|---|
| 唐 | tang.json | 180 首 | T001–T180 | 1,982 行 |
| 宋 | song.json | 155 首 | S001–S155 | 1,707 行 |
| 元 | yuan.json | 35 首 | Y001–Y035 | 387 行 |
| 明 | ming.json | 50 首 | M001–M050 | 551 行 |
| 清 | qing.json | 50 首 | C001–C050 | 551 行 |
| 先秦 | pre-qin-han.json | 30 首 | Q001–Q030 | 332 行 |
| 合计 | 500 首 | ~5,510 行 |
其中特别收录了《滕王阁序》《长恨歌》《琵琶行》等长篇名作,原文完整无删减。
第六章 UI 设计系统——水墨意境的数字表达
设计系统不仅是视觉规范,更是品牌情绪的传递。“墨韵诗笺”以水墨丹青为核心意象,将传统美学融入现代界面。
6.1 主题色彩
| 角色 | 色值 | 文化意象 |
|---|---|---|
| 背景 | #f4ecdb | 宣纸米白,温润质朴 |
| 前景 | #2b2620 | 墨黑,沉稳内敛 |
| 主色 | #1f4e66 | 青花瓷蓝,雅致端庄 |
| 强调色 | #b9493b | 朱砂红,点睛之笔 |
| 次要背景 | #e8dcc4 | 浅宣纸,层次过渡 |
| 边框 | #d8cab0 | 淡墨线,柔和勾勒 |
6.2 朝代专属配色——情绪化表达
每个朝代都有其独特的文化气质,我们通过配色渐变予以视觉暗示:
| 朝代 | 主题色 | 渐变方向 | 情绪基调 |
|---|---|---|---|
| 先秦 | #5a4a78 紫 | 古朴神秘 | 悠远苍茫 |
| 唐 | #1f4e66 青花蓝 | 大气开阔 | 盛世风华 |
| 宋 | #7a5e2e 赭色 | 素雅内敛 | 文人风骨 |
| 元 | #4a6a5a 青绿 | 旷达疏朗 | 洒脱不羁 |
| 明 | #8a4035 朱赭 | 沉郁厚重 | 复古典雅 |
| 清 | #34506a 墨青 | 清冷深邃 | 含蓄隽永 |
6.3 情绪色彩映射——让背景“说话”
详情页的卡片背景会根据诗词的 background_hint 字段匹配 15 种预设意境色,例如:
spring→ 春意盎然的#6a8a5anight→ 暗夜沉静的#1a1f2ewar→ 苍凉悲壮的#5a3a3a
这一细节极大增强了阅读的沉浸感。
6.4 字体与工具类
- 字体:
- 正文:
Noto Serif SC(衬线宋体,适合长文阅读) - 标题:
Ma Shan Zheng(毛笔行书,彰显水墨气质) - UI:
Geist(系统无衬线,现代简洁)
- 正文:
- 自定义 CSS 工具类(节选):
.paper-bg:宣纸纹理(多层纤维 + 墨晕).flip-card:3D 翻转容器.vertical-rl:竖排文字(writing-mode: vertical-rl).heart-pop:收藏按钮的心跳动画
这些工具类共同构建了“墨韵诗笺”独一无二的视觉语言。
第七章 小结
通过本章,我们系统了解了“墨韵诗笺”的设计与架构——从项目愿景到技术选型,从组件树到数据流,从配色方案到情绪映射。每一处设计都秉持着简洁、优雅、离线优先的原则,旨在为用户提供纯粹的古诗词欣赏体验。
在下一篇文章中,将深入探讨部署、构建、性能优化与运维细节,帮助您将这套架构真正落地运行。
2542

被折叠的 条评论
为什么被折叠?



