从空白页到可用成品:Qawkh の栖建站记录

3800 字
10 分钟
从空白页到可用成品:Qawkh の栖建站记录

从空白页到可用成品:Qawkh の栖建站记录

前言

折腾了快半个月,Qawkh の栖 终于从一个空白页面,慢慢长成了现在这个样子。

回头看,这个过程其实比一开始想的要复杂得多。前台页面要好看、后台要能管内容、接口要稳定、上传要能跑、主题切换和夜间模式要统一、留言、音乐、照片墙、万年历这些模块也都得一点点接起来。单独拎出来看,每一块都不算特别夸张,但真正把它们拼成一个完整的网站,细节是真的很多。

这篇文章就当作一次阶段性记录。主要想聊聊这个博客目前用了什么框架、什么语言、什么组件库,以及整个项目是怎么拆分、怎么实现、怎么一点点补齐功能的。如果你也想做一个属于自己的个人博客,希望这篇记录能给你一些参考。


技术栈一览

先放目前这个项目真实在用的一套技术栈。

层级我使用的技术说明
站点前台Vue 3 + TypeScript + Vite采用 Composition API,开发体验轻快,适合组件化页面组织
路由与状态Vue Router + Pinia负责页面导航、全局状态和交互联动
后端服务Spring Boot 3 + Java 21提供 REST API、业务逻辑与后台能力
数据访问MyBatis + MySQL负责内容数据存储与查询
鉴权方案JWT后台登录与接口访问控制
参数校验Spring Validation用于表单与接口参数校验
接口文档Knife4j / OpenAPI便于联调和接口管理
管理后台vue-pure-admin + Vue 3 + Element Plus快速搭建后台内容管理系统
对象存储阿里云 OSS存储图片、封面和其他上传资源
评论系统Waline用于留言板互动
功能组件lunar-javascript、highlight.js、GSAP农历黄历、代码高亮、页面动效
特色模块Live2D看板娘、欢迎语与互动效果

简单概括一下,就是:

我这次没有走 SSR 那套路线,而是选择了更适合当前开发节奏的前后端分离方案。前台专注页面和交互,后端专注接口和数据,后台专注内容管理,各自做自己最擅长的那部分。


为什么这么选

技术栈这件事,说到底还是看项目目标和开发习惯。

前台为什么用 Vue 3

前台我使用的是 Vue 3 + TypeScript + Vite

原因很直接:这一套我比较熟,也确实适合做这种页面多、卡片多、细节多、交互也不少的个人博客。像首页信息卡片、文章页、说说、照片墙、留言、个人中心、万年历这些模块,彼此之间结构独立,但又需要统一风格和状态联动,用 Vue 3 的 Composition API 来拆分会很自然。

TypeScript 的价值也很明显。接口字段、组件 props、工具函数、状态结构都能有更清楚的约束,联调的时候会少踩很多低级坑。

而 Vite 的优点就是轻和快。开发时热更新足够及时,打包也直接,对这种前端页面驱动型项目来说,体验非常舒服。

后端为什么用 Spring Boot

后端我使用的是 Spring Boot 3 + Java 21 + MyBatis + MySQL

这一套的优点主要是稳定、成熟、好维护。博客虽然不是一个超高并发项目,但它的数据类型并不少:文章、分类、公告、说说、照片墙、收藏夹、音乐、背景图、留言配置、关于页、特殊日期、上传资源……这些内容都需要比较稳定的 CRUD 和清晰的业务边界。

Spring Boot 负责整体框架能力,MyBatis 负责数据访问,MySQL 负责持久化存储。这样搭起来很踏实,也方便后续继续扩展管理功能。

后台为什么直接用 vue-pure-admin

后台我没有自己从零造,而是基于 vue-pure-admin 做二次开发。

原因也很现实:后台不是最值得重复造轮子的地方。像登录、菜单、路由、标签页、表格、分页、表单、弹窗这些通用能力,现成成熟模板已经做得很好了。直接拿来裁剪和改造,可以把时间省下来用在真正属于这个博客的功能上。

对我来说,最合适的方案不是“全都自己写”,而是“该自己写的认真写,不该重复造的就少造一点”。


项目结构

目前整个项目主要分成三部分:站点前台、后端服务、管理后台。

qawkh-blog/
├── qawkh-studio/ # 博客前台
│ ├── src/
│ │ ├── views/ # 页面视图
│ │ ├── components/ # 公共组件
│ │ ├── api/ # 前端接口封装
│ │ ├── router/ # 路由配置
│ │ ├── utils/ # 工具函数
│ │ └── types/ # TypeScript 类型声明
│ ├── public/ # 静态资源
│ └── package.json
├── qawkh-server/ # Spring Boot 后端
│ ├── src/main/java/com/qawkh/server/
│ │ ├── controller/ # 控制器层
│ │ ├── service/ # 业务逻辑层
│ │ ├── mapper/ # MyBatis 映射层
│ │ ├── domain/entity/ # 实体类
│ │ ├── model/dto/ # 请求 DTO
│ │ ├── model/vo/ # 返回 VO
│ │ └── config/ # 配置类
│ ├── src/main/resources/
│ │ ├── application.yml # 后端配置
│ │ └── db/schema.sql # 初始化 SQL
│ └── pom.xml
└── pure-admin-thin-i18n/ # 管理后台
├── src/
│ ├── views/ # 后台页面
│ ├── api/ # API 调用封装
│ ├── router/ # 后台路由
│ └── store/ # Pinia 状态管理
└── package.json

整个结构是比较标准的前后端分离:

  • qawkh-studio 负责博客前台展示
  • qawkh-server 负责接口、数据、鉴权、上传等后端能力
  • pure-admin-thin-i18n 负责后台内容管理

三部分之间通过 API 通信,职责边界比较清楚。这样后续无论是加功能还是改页面,都不会互相缠得太死。


前端:我使用了什么框架、语言和组件

核心框架和语言

前台核心使用的是:

  • Vue 3
  • TypeScript
  • Vite
  • Vue Router
  • Pinia

Vue 3 负责页面渲染和组件组织,TypeScript 负责类型约束,Vite 负责开发和构建,Vue Router 负责路由切换,Pinia 负责全局状态。

这种组合最大的好处就是“清晰”。页面逻辑、组件逻辑、数据逻辑、路由逻辑分层比较自然,代码不会很快陷入混乱。

前台页面模块

目前前台已经完成或接入的页面主要有:

  • 首页
  • 文章列表
  • 文章详情
  • 说说
  • 留言板
  • 收藏夹
  • 照片墙
  • 万年历
  • 归档
  • 个人中心
  • 关于页

这些页面不是靠一个大组件硬撑出来的,而是按功能拆成了很多独立模块,这样后面迭代起来更轻松。

我用到的前台功能组件

这个博客里前台组件数量不少,比较有代表性的有:

  • HomeBeijingTimeCard:北京时间卡片
  • HomeWeatherCard:天气卡片
  • HomeSpecialDateCalendarCard:首页特殊日期 / 节日卡片
  • GlobalMusicPlayer:全局音乐播放器
  • QuickAgeCalculatorPanel:年龄计算工具
  • QuickLunarConverterPanel:农历转换工具
  • QuickMetabolismPanel:基础代谢计算工具
  • AppIcon:统一图标组件

这些组件本质上都是围绕“首页信息展示”和“轻量工具增强”来做的。相比一个只有文章列表的普通博客,我更希望它看起来像一个真正有内容、有交互、有生活感的个人空间。

文章渲染和代码高亮

文章详情页支持 Markdown 内容展示,代码高亮使用的是 highlight.js

这部分的好处很明显:

  • 技术文章可以更自然地写代码块
  • 阅读体验比纯文本好很多
  • 后续扩展语言支持也比较方便

对于技术博客来说,代码高亮几乎算是基础设施。

留言板评论系统

留言页使用的是 Waline

我选择它主要是因为接入简单、交互完整,而且和个人博客这种场景非常契合。对于一个需要评论和互动的页面来说,自己从零写评论系统并不划算,能稳定用现成方案就够了。

万年历和农历黄历

万年历页面使用的是 lunar-javascript

这个库主要帮我解决了这些问题:

  • 公历转农历
  • 节气识别
  • 公历节日和农历节日识别
  • 干支、生肖、彭祖、星宿等黄历信息展示
  • 宜忌信息计算

这个模块是站点里辨识度比较高的一块。它不仅仅是一个简单日期面板,而是尽量做成一个完整可用的“月历 + 详情 + 黄历信息”页面。

动效与视觉增强

在前台视觉层面,我还用了这些能力:

  • GSAP:用于部分动效和过渡处理
  • Live2D:右下角看板娘、模型切换和欢迎语
  • 自定义卡片样式、主题切换、夜间模式适配

这些东西单独看都不算决定性功能,但组合在一起之后,确实能让页面更有质感,也更像一个“自己的站”。


后端:我使用了什么框架、语言和服务

核心框架和语言

后端主要使用的是:

  • Spring Boot 3.3.6
  • Java 21
  • MyBatis
  • MySQL

其中 Spring Boot 负责搭框架和接口能力,MyBatis 负责数据库访问,MySQL 负责数据存储。

我在后端做了哪些模块

目前后端已经拆分出比较完整的内容模块,包括:

  • 文章管理
  • 文章分类管理
  • 公告管理
  • 关于页信息管理
  • 说说管理
  • 照片墙分类与照片管理
  • 收藏夹分类与收藏项管理
  • 音乐歌曲管理
  • 站点背景图管理
  • 特殊日期管理
  • 留言板配置管理
  • 文件上传
  • 后台登录鉴权
  • 前台天气接口

接口层我按前台和后台分别做了拆分,比如:

  • 前台接口使用 User*Controller
  • 后台接口使用 Admin*Controller

这样做的好处是边界很清楚:

  • 前台只拿展示所需的数据
  • 后台只做管理和编辑所需的能力

不会把管理逻辑和展示逻辑混成一锅。

数据结构和代码组织

后端这一层我基本按照常见的分层方式来组织:

  • entity:数据库实体
  • dto:请求参数对象
  • vo:返回结果对象
  • mapper:数据库访问层
  • service:业务逻辑层
  • controller:接口控制层

这种写法虽然类会多一些,但业务清晰、职责分明。等模块慢慢变多以后,这种结构的好处会越来越明显。

鉴权、校验和接口文档

后台鉴权这块,我使用的是 JWT

登录成功后生成 token,后续后台接口携带 token 访问,服务端负责解析和校验。对个人博客后台来说,这已经是一套足够实用的方案。

参数校验我使用的是 Spring Validation,主要负责:

  • 必填项校验
  • 长度范围校验
  • 基本格式校验

接口文档我接入了 Knife4j / OpenAPI,这样联调的时候会方便很多,也更容易统一管理接口。

文件上传和对象存储

文件上传这块,我接入的是 阿里云 OSS

目前它主要负责这些资源:

  • 文章封面
  • 照片墙图片
  • 站点背景图
  • 其他媒体资源

这样做最大的好处就是不用把所有文件都压在服务器本地磁盘上,资源管理和后续迁移都会更轻松一些。


管理后台:我使用了什么后台框架和组件库

后台项目我使用的是:

  • vue-pure-admin
  • Vue 3
  • TypeScript
  • Vite
  • Element Plus
  • Pinia

这套东西本身就很适合做管理系统,特别是:

  • 表格
  • 表单
  • 分页
  • 弹窗
  • 菜单路由
  • 登录页
  • 标签页

这些内容如果全都自己写,成本其实不低。直接基于成熟后台模板做裁剪和扩展,效率会高很多。

后台目前已经支持的内容管理

我在后台里主要做了这些模块:

  • 文章管理
  • 文章分类管理
  • 公告管理
  • 说说管理
  • 照片墙分类管理
  • 照片墙图片管理
  • 收藏夹分类与条目管理
  • 音乐管理
  • 关于页信息管理
  • 留言板设置管理
  • 站点背景图管理
  • 特殊日期管理

数据量稍大一点的列表页,也都尽量做了服务端分页,不至于后面数据一多就直接卡成表格坟场。

后台这部分最大的价值,不是“页面有多炫”,而是它真的能让我把站点内容管理起来,而不是所有信息都写死在前端代码里。


这个博客里比较有意思的功能

除了常规的文章和后台管理,这个项目里我自己比较喜欢的模块还有几个。

1. 首页信息卡片

首页不只是放一排文章,而是做了多个信息卡片:

  • 北京时间
  • 天气
  • 节日 / 特殊日期
  • 音乐模块
  • 公告内容

这样首页不至于显得过空,也更有“个人站点首页”的感觉,而不是单纯的内容列表页。

2. 个人中心

个人中心页不只是一个简短的 About,而是集中展示了:

  • 头像和封面
  • 建站初衷
  • 兴趣日常
  • 个人简介
  • 页面跳转入口

它更像一个完整的个人展示页,而不是仅仅“补一个资料页”。

3. 照片墙

照片墙模块除了分类展示外,也做了大图预览和更偏展示型的布局。对个人博客来说,图片本身也是内容的一部分,不应该只是一个冷冰冰的管理列表映射页。

4. 万年历

万年历是目前站里功能性比较强的页面之一。它不是简单做个日期选择器就结束,而是把农历、节气、节日、宜忌和黄历详情都整合到了一个页面里,实用性和辨识度都还不错。

5. Live2D 看板娘

右下角的看板娘属于很典型的“没那么必要,但确实很有趣”的功能。

它目前支持:

  • 模型切换
  • 大小切换
  • 页面欢迎语
  • 点击互动
  • 位置记忆

对个人博客来说,这种小东西往往就是“个人风格”的一部分。


一路做下来的一些感受

做这个博客过程中,我最大的感受其实是:

真正花时间的,往往不是把某个功能“做出来”,而是把它“做顺眼、做完整、做统一”。

比如:

  • 页面白天和夜间模式是否统一
  • 留言区和正文区是不是都清楚可读
  • 卡片之间的风格是否一致
  • 后台改完内容后,前台是否真的能接住
  • 图片、音乐、特殊日期这些动态内容有没有真正从后台管理起来

这些事情每一件都不算惊天动地,但恰恰是它们堆起来,最后才决定这个站点看起来像不像一个完整产品。


结语

Qawkh の栖 到现在当然还远远算不上“彻底完成”,但至少它已经从一个空白页,走到了一个能看、能用、能继续迭代的阶段。

前台有了完整的页面结构,后端有了比较清晰的业务模块,后台也已经能真正接管内容维护。剩下的工作,不再是“从零开始”,而是继续把细节补得更完整,把体验做得更统一。

如果你也想做一个自己的博客,或者正在准备做一个前后端分离的小项目,我觉得最重要的不是一开始就追求多复杂的技术栈,而是先把结构搭稳,再一步步把内容、功能和细节补上。

技术栈从来没有唯一正确答案,最适合自己的,才是最值得一直做下去的那一套。

如果后面我继续给这个博客加更多模块,应该还会再写一篇,把后续的实现细节和踩坑记录继续补上。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
从空白页到可用成品:Qawkh の栖建站记录
https://www.qawkh.com/posts/15/
作者
站点管理员
发布于
2026-06-30
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Firefly
Hello, I'm Firefly.
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
最新动态
站点统计
文章
14
动态
15
分类
5
标签
6
总字数
0
运行时长
0
最后活动
0 天前
站点信息
构建平台
Unknown CI
博客版本
Firefly v6.14.3
文章许可
CC BY-NC-SA 4.0