为什么选记账本作为实战项目
很多人学完前端、后端、数据库,却不知道怎么把它们串起来。与其反复看教程,不如动手做一个真实可用的小应用。记账本是个不错的起点——功能清晰,数据模型简单,又能覆盖全栈的典型场景。比如你每天买杯咖啡都记一笔,这个动作背后,其实已经涉及表单提交、接口请求、数据存储和列表展示。
技术选型:轻量但完整
前端用 React,搭配 Ant Design 快速搭界面;后端选 Node.js + Express,写接口够灵活;数据库用 MongoDB,结构松散适合早期迭代。这三块组合起来,没有过度复杂,又足够体现全栈协作。
项目目录这样分:
project-root
├── client # 前端代码
├── server # 后端代码
├── package.json前端页面怎么做
先画个录入页面,两个输入框:金额和分类。用户点“记一笔”,就发请求到 /api/records。这里别急着联调,先 mock 数据,让列表能显示几条假记录。
<form onSubmit={handleSubmit}>
<input value={amount} onChange={(e) => setAmount(e.target.value)} />
<select value={type} onChange={(e) => setType(e.target.value)}>
<option value="food">餐饮</option>
<option value="traffic">交通</option>
</select>
<button type="submit">记一笔</button>
</form>后端接口怎么写
在 server 目录下起一个 Express 服务,监听 3001 端口。建个路由文件 api/records.js,处理 GET 和 POST。
const express = require('express');
const router = express.Router();
const Record = require('../models/Record');
router.post('/', async (req, res) => {
const { amount, type } = req.body;
const record = new Record({ amount, type, date: new Date() });
await record.save();
res.status(201).json(record);
});
router.get('/', async (req, res) => {
const records = await Record.find().sort({ date: -1 });
res.json(records);
});
module.exports = router;数据库设计不用想太复杂
就一张表(集合)records,字段就四个:金额、类型、日期、备注。MongoDB 的 schema 可以先宽松一点,后期再加验证规则。启动本地 mongod 或用 Atlas 免费集群都行。
连接数据库时,别把链接写死在代码里,用 .env 存 URI:
MONGODB_URI=mongodb://localhost:27017/accounting前后端联调常见坑
React 默认端口是 3000,Express 是 3001,跨域直接报错。解决方法是在 server 中引入 cors 中间件。
const cors = require('cors');
app.use(cors());另一个问题是 POST 提交的数据是 undefined。记得在 Express 入口文件加 bodyParser:
app.use(express.json());部署上线跑通全流程
前端 build 出静态文件,放到 Nginx 或 Vercel;后端用 PM2 托管在云服务器,数据库选 MongoDB Atlas。域名配好,HTTPS 搞定,你就能用手机访问自己的记账系统了。这时候再拿它真记几天开销,哪里体验卡顿改哪里。
比如发现列表加载慢,可以加个分页;输入时想自动补全分类,就前端缓存常用项。这些都不是一开始能想到的,只有真正用起来才会浮现。