自己管理内容:做一个简单的后台管理页面
25 分钟
每次想更新作品,都要去 Supabase 手动改数据库,太麻烦了。
这一关做一个简单的后台管理页面,让你可以直接在网站里添加、编辑、删除作品。
什么是 CRUD?
CRUD 是四个操作的缩写:
- Create(创建):添加新作品
- Read(读取):查看作品列表
- Update(更新):编辑已有作品
- Delete(删除):删除作品
几乎所有的内容管理系统(CMS)都是围绕 CRUD 构建的。WordPress 的文章管理、淘宝的商品管理、微博的内容管理,本质上都是 CRUD。
这一关你会实现一个完整的 CRUD 系统,这是全栈开发最核心的技能之一。
后台管理的设计原则
一个好的后台管理页面,需要考虑:
效率优先:后台是给你自己用的,不需要像前台那么精致,但要高效。表格布局比卡片布局更适合管理大量数据。
操作安全:删除操作必须有确认步骤,防止误操作。"此操作不可撤销"的提示很重要。
即时反馈:操作完成后,列表应该立刻更新,不需要手动刷新页面。
错误处理:网络请求可能失败,需要有友好的错误提示。
第一步:做作品管理页面
对 AI 说:
创建一个后台管理页面 /admin/works: - 显示所有作品的列表(表格形式) - 每行显示:封面缩略图、标题、标签、操作按钮(编辑、删除) - 右上角有"添加作品"按钮 - 页面顶部有简单的标题"作品管理" 暂时不需要登录验证,先把功能做出来。
第二步:做添加和编辑表单
对 AI 说:
给作品管理页面加上添加和编辑功能: 1. 点击"添加作品",弹出一个模态框(Modal),里面有表单: - 作品标题(必填) - 作品描述(多行文本) - 标签(可以输入多个,用逗号分隔) - 封面图片链接 - 项目链接 - GitHub 链接 2. 点击某个作品的"编辑"按钮,弹出同样的模态框,但预填了该作品的数据 3. 表单提交后: - 添加:调用 POST /api/works 接口 - 编辑:调用 PUT /api/works/[id] 接口 - 成功后关闭模态框,刷新作品列表 4. 更新 API 路由,支持 PUT 方法(更新作品)
第三步:实现删除功能
对 AI 说:
给作品管理页面加上删除功能: 1. 点击"删除"按钮,弹出确认对话框:"确定要删除《作品名称》吗?此操作不可撤销。" 2. 确认后调用 DELETE /api/works/[id] 接口 3. 删除成功后,从列表中移除该作品(不需要刷新整个页面) 4. 更新 API 路由,支持 DELETE 方法 5. 在 API 路由里创建 app/api/works/[id]/route.ts,处理单个作品的 GET、PUT、DELETE 请求
关于"模态框"(Modal)
模态框是一种弹出层,出现时会遮住背景,强制用户先处理当前操作。
模态框适合用于:
- 表单填写(添加/编辑)
- 确认操作(删除确认)
- 详情预览
模态框的关键交互:
- 点击背景遮罩关闭
- 按 Escape 键关闭
- 有明确的关闭按钮
关于动态路由 [id]
app/api/works/[id]/route.ts 里的 [id] 是动态路由参数。
当你访问 /api/works/123 时,id 的值就是 123。在 API 路由里可以这样获取:
export async function DELETE( request: Request, { params }: { params: { id: string } } ) { const { id } = params; // 删除 id 对应的作品 }
这个模式在 Next.js 里非常常见,你会在很多地方用到。
通关条件
完成以下三步即可通关:
/admin/works页面可以正常访问,显示作品列表- 可以通过表单添加新作品,添加后列表更新
- 可以删除作品,删除后列表更新
卡住了?
- 模态框不显示?让 AI 检查控制显示的状态变量是否正确
- API 返回 405 Method Not Allowed?检查 route.ts 里是否导出了对应的 HTTP 方法函数(GET/POST/PUT/DELETE)
- 删除后列表没更新?让 AI 在删除成功后重新调用获取列表的函数
- 编辑时表单没有预填数据?让 AI 检查打开模态框时是否正确传入了当前作品的数据
通关条件
完成以下三步即可通关:
/admin/works页面可以正常访问,显示作品列表- 可以通过表单添加新作品,添加后列表更新
- 可以删除作品,删除后列表更新
卡住了?
- 模态框不显示?让 AI 检查控制显示的状态变量是否正确
- API 返回 405 Method Not Allowed?检查 route.ts 里是否导出了对应的 HTTP 方法函数(GET/POST/PUT/DELETE)
- 删除后列表没更新?让 AI 在删除成功后重新调用获取列表的函数
- 编辑时表单没有预填数据?让 AI 检查打开模态框时是否正确传入了当前作品的数据