资讯动态

AI辅助编码实战:从零搭建宠物生命周期管理全栈项目

发布时间:2026/10/22 12:08:37 来源:尧图企业网站定制
1. 项目缘起与整体设计思路1.1 为什么选“宠物生命周期管理”这个场景宠物生命周期管理这个选题乍看像是个小众的垂直领域但真正拆开来看它其实是一个天然的“全栈练手项目”。一只宠物从被领养、日常喂养、疫苗接种、体检记录、体重曲线、驱虫提醒到生病就诊、用药记录再到老年期护理、临终关怀甚至离世后的纪念这条时间线几乎覆盖了一个完整应用需要处理的所有典型问题结构化数据存储、时间轴事件、周期提醒、文件附件、统计图表、多端同步。我选它作为从零搭建的演示项目核心原因是它足够“真实”。很多教程喜欢拿待办清单、博客系统做例子但这些场景太抽象做到后面容易失去动力。宠物生命周期管理不一样它天然带着情感属性功能边界清晰而且每一个模块都能对应到现实中的具体需求。你做完之后哪怕不商用自己养宠物也能直接用起来。另一个考量是数据模型的复杂度适中。它不像电商系统那样涉及订单、库存、支付、物流等一大堆关联表也不像社交产品那样要处理复杂的关注关系和消息推送。它的核心就是“一只宠物 一条时间线 若干事件类型”这个模型既能让初学者理解关系型数据库的基本设计又不会一上来就被复杂的表关联劝退。1.2 用AI辅助编码的定位与边界这个项目全程用AI辅助编码来完成但我必须先说清楚一件事AI不是替你思考而是替你打字。很多人对AI写代码有误解觉得只要把需求丢过去代码就自动出来了。实际用下来AI最擅长的是三件事生成样板代码、补全重复性逻辑、在你卡住的时候提供思路。它不擅长的是理解你项目的整体架构意图、判断业务逻辑的合理性、处理边界条件。所以我在这个项目里的做法是架构我来定模块我来拆接口我来设计具体的函数实现和样板代码交给AI。比如数据库表结构我会先想清楚有哪些实体、它们之间是什么关系然后让AI帮我生成建表语句和对应的模型代码。再比如前端的列表页、表单页这些高度重复的UI我会把设计稿描述清楚让AI一次性生成多个页面的骨架我再逐个调整。这种分工方式的好处是你始终对项目有掌控感不会出现“AI写了一堆代码但我看不懂”的情况。而且当AI生成的代码有问题时你能快速定位是哪个环节出了偏差而不是面对一坨黑盒束手无策。1.3 技术选型的取舍逻辑技术栈的选择上我遵循一个原则选生态成熟、文档丰富、AI训练语料多的方案。原因很直接AI对这些技术栈的代码生成质量明显更高你遇到的坑也更容易在网上找到答案。最终的技术选型是这样的层级技术方案选择理由前端框架React TypeScript组件化清晰类型系统能帮AI生成更准确的代码状态管理Zustand比Redux轻量学习成本低适合中小型项目路由React Router标准方案AI生成的路由配置基本不用改UI组件Tailwind CSS 自建组件原子化样式AI生成样式代码时不容易冲突后端框架Node.js Express前后端同语言减少切换成本数据库SQLite开发/ PostgreSQL生产开发期零配置生产期可平滑迁移ORMPrismaSchema定义清晰AI能准确生成查询代码图表RechartsReact生态内集成简单API直观文件存储本地文件系统开发/ 对象存储生产按环境切换接口抽象统一这里重点说一下为什么用Prisma而不是直接写SQL。Prisma的Schema文件本身就是一种“可读的文档”你把模型定义写清楚之后AI能基于Schema生成准确的增删改查代码而且类型安全。实测下来用Prisma之后AI生成的数据库操作代码几乎不需要手动修正这个效率提升非常明显。2. 核心数据模型与AI协作要点2.1 宠物生命周期的时间轴抽象整个应用的核心抽象是“时间轴”。每一只宠物都有一条属于自己的时间轴时间轴上的每一个节点就是一个事件。事件有很多种类型领养、疫苗、驱虫、体检、体重记录、用药、就诊、洗澡、剪指甲、生日、离世等等。这个抽象的好处是新增功能只需要新增事件类型不需要改动核心数据结构。比如你后面想加一个“宠物社交活动记录”只需要在事件类型枚举里加一项前端加一个对应的表单和展示样式数据库层面完全不用动。事件表的核心字段设计如下model PetEvent { id String id default(cuid()) petId String type EventType title String description String? eventDate DateTime metadata String? // JSON字符串存储类型特有的字段 attachments String? // JSON数组存储附件路径 createdAt DateTime default(now()) updatedAt DateTime updatedAt pet Pet relation(fields: [petId], references: [id], onDelete: Cascade) } enum EventType { ADOPTION VACCINE DEWORMING CHECKUP WEIGHT MEDICATION VISIT GROOMING BIRTHDAY PASSING OTHER }这里有个关键设计决策用metadata字段存类型特有的数据而不是给每种事件建独立的表。比如体重记录需要存体重数值和单位疫苗需要存疫苗名称和批次号体检需要存各项指标。如果每种事件都建一张表表数量会爆炸查询和统计也会变得很麻烦。用JSON字段存扩展数据核心字段保持统一查询时按需解析这是我在实际项目中反复验证过的方案。当然这个方案也有代价无法在数据库层面直接对metadata里的字段做索引和聚合查询。如果你的统计需求很复杂比如“查询所有体重超过5kg的宠物”那就需要在应用层做过滤或者考虑把高频查询的字段单独抽出来建索引。这个取舍要根据实际数据量和查询模式来定。2.2 让AI理解数据关系的提示词技巧用AI生成数据模型相关代码时最大的坑是AI不知道你的完整Schema。你让它写一个查询它可能会引用一个不存在的字段或者用错关联关系。解决办法是在对话开始时把完整的Prisma Schema贴给AI并明确告诉它“以下是我项目的完整数据模型后续所有代码生成都基于这个Schema不要引用不存在的字段。”这个简单的动作能大幅降低AI出错的概率。我实测过不贴Schema直接让AI写查询错误率大概在30%左右贴了Schema之后错误率降到5%以下。而且当AI确实需要引用某个字段时它会主动去Schema里找而不是凭空编造。另一个技巧是用注释标注字段的业务含义。比如model Pet { id String id default(cuid()) name String // 宠物名字 species String // 物种猫、狗、兔等 breed String? // 品种 gender String? // 性别 birthday DateTime? // 出生日期未知时为空 adoptDate DateTime? // 领养日期 avatar String? // 头像文件路径 weight Float? // 当前体重kg isActive Boolean default(true) // 是否在世 createdAt DateTime default(now()) updatedAt DateTime updatedAt events PetEvent[] }这些注释不仅方便你自己回顾AI在生成代码时也会参考这些注释来理解字段用途。比如它看到isActive的注释是“是否在世”在生成查询时就会知道要过滤掉已离世的宠物。2.3 事件类型枚举的扩展性设计事件类型用枚举而不是字符串是为了类型安全。但枚举有个问题新增类型需要改代码。如果你希望用户能自定义事件类型那就不能用枚举得用一张单独的类型表。我的建议是核心类型用枚举自定义类型用扩展表。比如疫苗、驱虫、体检这些是固定类型用枚举用户如果想加一个“宠物美容记录”可以走自定义类型存到单独的CustomEventType表里。这样既保证了核心逻辑的类型安全又保留了扩展性。在实际操作中我让AI生成事件类型相关的代码时会明确告诉它“EventType是固定枚举不要尝试动态添加。如果需要扩展走CustomEventType表。”这样AI就不会生成一些奇怪的动态枚举操作代码。3. 从零搭建的完整实操流程3.1 环境初始化与项目骨架生成第一步是初始化项目。我习惯用Vite来创建React项目因为它的启动速度和热更新体验明显优于传统的Create React App。命令很简单npm create vitelatest pet-lifecycle -- --template react-ts cd pet-lifecycle npm install接下来安装核心依赖。这里我分三批安装避免一次性装太多导致依赖冲突难以排查# 第一批路由和状态管理 npm install react-router-dom zustand # 第二批UI和样式 npm install tailwindcss postcss autoprefixer npx tailwindcss init -p # 第三批图表和工具库 npm install recharts date-fns axios后端部分我在项目根目录下建一个server文件夹独立初始化mkdir server cd server npm init -y npm install express cors prisma prisma/client npm install -D typescript ts-node types/express types/cors npx prisma init这里有个细节前后端分开管理依赖但放在同一个仓库里。这样做的好处是你可以在根目录用一个命令同时启动前后端开发体验很顺畅。我通常会在根目录的package.json里加一个concurrentlynpm install -D concurrently然后在scripts里配置{ scripts: { dev: concurrently \npm run dev:client\ \npm run dev:server\, dev:client: vite, dev:server: cd server ts-node-dev src/index.ts } }这样一条npm run dev就能同时跑起来前后端省去了开两个终端的麻烦。3.2 数据库Schema设计与迁移Schema设计是整个项目的地基这一步没做好后面改起来会很痛苦。我的做法是先把所有实体和关系在纸上画一遍确认没有遗漏再写Prisma Schema。核心实体有三个Pet宠物、PetEvent事件、User用户如果做多用户的话。关系也很简单一个User有多只Pet一只Pet有多个Event。完整的Schema如下generator client { provider prisma-client-js } datasource db { provider sqlite url env(DATABASE_URL) } model User { id String id default(cuid()) email String unique name String? pets Pet[] createdAt DateTime default(now()) } model Pet { id String id default(cuid()) userId String name String species String breed String? gender String? birthday DateTime? adoptDate DateTime? avatar String? weight Float? isActive Boolean default(true) createdAt DateTime default(now()) updatedAt DateTime updatedAt user User relation(fields: [userId], references: [id], onDelete: Cascade) events PetEvent[] } model PetEvent { id String id default(cuid()) petId String type String title String description String? eventDate DateTime metadata String? attachments String? createdAt DateTime default(now()) updatedAt DateTime updatedAt pet Pet relation(fields: [petId], references: [id], onDelete: Cascade) index([petId, eventDate]) }注意最后那个index([petId, eventDate])这是为时间轴查询准备的复合索引。时间轴查询的模式是“查某只宠物的所有事件按时间排序”这个索引能直接命中查询效率很高。Schema写好后执行迁移npx prisma migrate dev --name init npx prisma generatemigrate dev会生成迁移文件并应用到数据库generate会根据Schema生成Prisma Client。每次改完Schema都要重新跑这两个命令建议把它加到package.json的scripts里。3.3 后端API的分层实现后端我采用经典的三层结构路由层、服务层、数据访问层。路由层只负责解析请求参数和返回响应服务层处理业务逻辑数据访问层封装Prisma操作。先看路由层的一个例子// server/src/routes/pets.ts import { Router } from express; import { PetService } from ../services/petService; const router Router(); const petService new PetService(); router.get(/, async (req, res) { try { const pets await petService.getAllPets(req.userId); res.json(pets); } catch (error) { res.status(500).json({ error: 获取宠物列表失败 }); } }); router.post(/, async (req, res) { try { const pet await petService.createPet(req.userId, req.body); res.status(201).json(pet); } catch (error) { res.status(400).json({ error: 创建宠物失败 }); } }); export default router;服务层// server/src/services/petService.ts import { PrismaClient } from prisma/client; const prisma new PrismaClient(); export class PetService { async getAllPets(userId: string) { return prisma.pet.findMany({ where: { userId }, orderBy: { createdAt: desc }, include: { _count: { select: { events: true } } } }); } async createPet(userId: string, data: any) { return prisma.pet.create({ data: { ...data, userId, birthday: data.birthday ? new Date(data.birthday) : null, adoptDate: data.adoptDate ? new Date(data.adoptDate) : null, } }); } }这种分层的好处是业务逻辑集中在服务层路由层很薄测试和复用都方便。比如你后面要加一个定时任务来发送疫苗提醒直接调用服务层的方法就行不用去碰路由。用AI生成这些代码时我会把Prisma Schema和分层结构一起告诉它让它按这个模式生成。实测下来AI对Express Prisma的组合非常熟悉生成的代码基本可以直接用偶尔需要调整一下错误处理的粒度。3.4 前端页面结构与状态管理前端页面按功能划分主要有这几个宠物列表页首页宠物详情页含时间轴添加/编辑宠物页添加事件页统计页体重曲线、事件分布路由配置// src/App.tsx import { BrowserRouter, Routes, Route } from react-router-dom; import PetList from ./pages/PetList; import PetDetail from ./pages/PetDetail; import PetForm from ./pages/PetForm; import EventForm from ./pages/EventForm; import Stats from ./pages/Stats; function App() { return ( BrowserRouter Routes Route path/ element{PetList /} / Route path/pet/:id element{PetDetail /} / Route path/pet/new element{PetForm /} / Route path/pet/:id/edit element{PetForm /} / Route path/pet/:id/event/new element{EventForm /} / Route path/stats element{Stats /} / /Routes /BrowserRouter ); }状态管理用Zustand核心store设计如下// src/stores/petStore.ts import { create } from zustand; import axios from axios; interface Pet { id: string; name: string; species: string; // ...其他字段 } interface PetStore { pets: Pet[]; currentPet: Pet | null; loading: boolean; fetchPets: () Promisevoid; fetchPet: (id: string) Promisevoid; addPet: (data: PartialPet) Promisevoid; } export const usePetStore createPetStore((set) ({ pets: [], currentPet: null, loading: false, fetchPets: async () { set({ loading: true }); const { data } await axios.get(/api/pets); set({ pets: data, loading: false }); }, fetchPet: async (id) { set({ loading: true }); const { data } await axios.get(/api/pets/${id}); set({ currentPet: data, loading: false }); }, addPet: async (petData) { const { data } await axios.post(/api/pets, petData); set((state) ({ pets: [data, ...state.pets] })); }, }));Zustand的好处是没有样板代码一个create函数就搞定。相比Redux需要定义action、reducer、dispatchZustand的写法简洁太多而且TypeScript支持很好。AI生成Zustand代码的准确率也很高基本不需要怎么改。3.5 时间轴组件的实现细节时间轴是这个应用的核心UI我单独拿出来讲。它的需求是按时间倒序展示事件不同类型的事件用不同的图标和颜色点击可以展开详情支持按类型筛选。核心实现思路是先把事件按日期分组再渲染每一组。这样同一天的事件会聚在一起视觉上更清晰。// src/components/Timeline.tsx import { useMemo } from react; import { format, isSameDay } from date-fns; const eventConfig: Recordstring, { icon: string; color: string; label: string } { VACCINE: { icon: , color: blue, label: 疫苗 }, DEWORMING: { icon: , color: green, label: 驱虫 }, CHECKUP: { icon: , color: purple, label: 体检 }, WEIGHT: { icon: ⚖️, color: orange, label: 体重 }, // ...其他类型 }; export function Timeline({ events }: { events: PetEvent[] }) { const grouped useMemo(() { const groups: { date: Date; events: PetEvent[] }[] []; const sorted [...events].sort((a, b) new Date(b.eventDate).getTime() - new Date(a.eventDate).getTime() ); sorted.forEach((event) { const eventDate new Date(event.eventDate); const lastGroup groups[groups.length - 1]; if (lastGroup isSameDay(lastGroup.date, eventDate)) { lastGroup.events.push(event); } else { groups.push({ date: eventDate, events: [event] }); } }); return groups; }, [events]); return ( div classNametimeline {grouped.map((group) ( div key{group.date.toISOString()} classNametimeline-group div classNametimeline-date{format(group.date, yyyy年MM月dd日)}/div {group.events.map((event) { const config eventConfig[event.type] || eventConfig.OTHER; return ( div key{event.id} className{timeline-item border-${config.color}-500} span classNametimeline-icon{config.icon}/span div classNametimeline-content h4{event.title}/h4 {event.description p{event.description}/p} /div /div ); })} /div ))} /div ); }这里有个性能上的考量用useMemo缓存分组结果。如果事件数量很多比如几百条每次渲染都重新分组会有明显的卡顿。useMemo确保只有events变化时才重新计算。另外事件类型的配置我抽成了一个独立的对象这样新增类型只需要改这一处不用去改渲染逻辑。这个模式在AI生成代码时也很友好你可以直接告诉AI“事件类型配置在eventConfig对象里新增类型时同步更新这个对象。”4. 常见问题与排查技巧实录4.1 AI生成代码的典型错误与修正用AI辅助编码最常遇到的几类问题我整理成了速查表问题现象根本原因解决方法引用了不存在的字段AI不知道完整Schema对话开始时贴完整Schema类型定义不一致前后端类型没同步用共享的types文件或让AI基于Prisma生成类型异步错误处理缺失AI倾向于写happy path明确要求“所有async函数都要有try-catch”重复的样板代码AI不知道已有工具函数把已有的工具函数列表告诉AI样式类名冲突Tailwind类名拼写错误让AI生成后自己跑一遍看控制台警告其中最常见的是类型不一致。比如前端定义了一个Pet接口后端返回的字段名稍有不同运行时就会出错。我的解决办法是用Prisma生成的类型作为唯一真相来源。Prisma Client会自动生成所有模型的TypeScript类型前端直接引用这些类型就行不用手写接口定义。具体做法是在server的tsconfig里开启类型导出然后前端通过路径映射引用// server/tsconfig.json { compilerOptions: { declaration: true, outDir: dist } }这样前端就能import { Pet } from ../server/dist/types类型永远同步。4.2 数据库迁移中的坑与应对Prisma迁移在开发期很顺畅但有几个坑我踩过第一个坑是SQLite不支持某些PostgreSQL的特性。比如SQLite没有原生的数组类型如果你在Schema里用了String[]迁移到PostgreSQL时会有问题。解决办法是开发期就用PostgreSQL或者用JSON字符串代替数组。第二个坑是迁移文件冲突。多人协作时如果两个人同时改了Schema迁移文件会冲突。解决办法是每次改Schema前先pull最新代码改完后立即生成迁移并提交。第三个坑是数据丢失。prisma migrate dev在某些情况下会重置数据库。如果你有测试数据不想丢用prisma migrate dev --create-only先生成迁移文件检查无误后再用prisma migrate deploy应用。提示生产环境永远不要用migrate dev要用migrate deploy。migrate dev会检测Schema变化并自动生成迁移这在生产环境是危险的。4.3 时间轴性能优化的实操经验时间轴数据量大了之后性能问题会显现。我实测过当事件超过500条时首屏渲染会有明显延迟。优化手段有几个第一是分页加载。不要一次性拉取所有事件按时间倒序分页每页20条滚动到底部再加载下一页。后端用skip和take实现async getEvents(petId: string, page: number 1, pageSize: number 20) { return prisma.petEvent.findMany({ where: { petId }, orderBy: { eventDate: desc }, skip: (page - 1) * pageSize, take: pageSize, }); }第二是虚拟滚动。如果不想分页可以用虚拟滚动只渲染可视区域内的元素。React生态里有react-window和react-virtualized两个成熟方案。我用的是react-window配置简单和现有代码集成成本低。第三是索引优化。前面提到的index([petId, eventDate])就是为这个查询准备的。没有索引的话每次查询都要全表扫描数据量大了会非常慢。你可以用EXPLAIN命令查看查询计划确认索引是否命中。4.4 前后端联调的常见问题前后端联调阶段问题主要集中在跨域、请求格式、错误处理三个方面。跨域问题在开发期很常见。Vite的配置里加一个proxy就能解决// vite.config.ts export default defineConfig({ server: { proxy: { /api: { target: http://localhost:3001, changeOrigin: true, }, }, }, });请求格式问题通常是日期字段的序列化。JavaScript的Date对象转JSON会变成ISO字符串后端接收后需要转回Date。我在服务层统一处理了这个问题function parseDates(data: any, fields: string[]) { const result { ...data }; fields.forEach((field) { if (result[field]) { result[field] new Date(result[field]); } }); return result; }错误处理方面我建议统一响应格式。成功返回{ data: ... }失败返回{ error: ... }。前端用一个axios拦截器统一处理axios.interceptors.response.use( (response) response.data.data, (error) { const message error.response?.data?.error || 请求失败; // 显示错误提示 return Promise.reject(new Error(message)); } );这样前端调用时只需要关心数据本身不用每次都判断response.data.error。5. 功能扩展与后续迭代方向5.1 提醒系统的实现思路宠物生命周期管理最实用的功能之一是提醒。疫苗每年要打驱虫每月要做体检每半年一次。这些周期性事件如果能自动提醒应用的价值会大幅提升。实现思路是在事件创建时根据事件类型自动计算下一次提醒时间存到单独的Reminder表。然后用一个定时任务每天检查把到期的提醒推送给用户。model Reminder { id String id default(cuid()) petId String eventType String nextDate DateTime interval Int // 间隔天数 isActive Boolean default(true) createdAt DateTime default(now()) pet Pet relation(fields: [petId], references: [id], onDelete: Cascade) }定时任务用node-cron实现import cron from node-cron; cron.schedule(0 9 * * *, async () { const today new Date(); const reminders await prisma.reminder.findMany({ where: { isActive: true, nextDate: { lte: today }, }, include: { pet: true }, }); for (const reminder of reminders) { await sendNotification(reminder); await prisma.reminder.update({ where: { id: reminder.id }, data: { nextDate: addDays(reminder.nextDate, reminder.interval), }, }); } });推送渠道可以先用邮件后面再扩展。邮件用nodemailer配置简单测试方便。5.2 数据导出与备份方案用户数据是宝贵的尤其是养了多年的宠物时间轴上积累了几百条记录。提供数据导出功能是必要的。导出格式我推荐JSON和PDF两种。JSON用于数据备份和迁移PDF用于打印和分享。JSON导出很简单直接把数据库查询结果序列化就行async exportPetData(petId: string) { const pet await prisma.pet.findUnique({ where: { id: petId }, include: { events: { orderBy: { eventDate: asc } } }, }); return JSON.stringify(pet, null, 2); }PDF导出稍微复杂一点需要用到pdfkit或puppeteer。我推荐puppeteer因为它可以直接把HTML渲染成PDF你可以用React组件生成HTML样式控制更灵活。备份方面如果用的是PostgreSQL可以用pg_dump定时备份。SQLite更简单直接复制文件就行。但要注意备份文件要存到不同的物理位置不能和数据库放在同一块硬盘上。5.3 多宠物家庭的视图设计很多家庭养了不止一只宠物所以应用需要支持多宠物视图。首页默认展示所有宠物的卡片列表点击进入单只宠物的详情页。多宠物视图的一个设计难点是时间轴的合并展示。用户可能想看到所有宠物的混合时间轴也可能只想看某一只的。我的做法是提供一个切换开关const [viewMode, setViewMode] useStatesingle | all(single); const events viewMode single ? currentPet.events : allPets.flatMap(pet pet.events.map(e ({ ...e, petName: pet.name })));合并视图下每个事件要标注是哪只宠物的用不同颜色的标签区分。这个功能实现起来不难但用户体验提升很明显。5.4 从SQLite迁移到PostgreSQL的注意事项开发期用SQLite生产期用PostgreSQL这个迁移过程有几个注意点第一是字段类型差异。SQLite的DateTime存的是字符串PostgreSQL有原生的timestamp类型。迁移时Prisma会自动处理但你要确认时区设置一致。第二是自增ID的处理。SQLite的AUTOINCREMENT和PostgreSQL的SERIAL行为略有不同。我用的是cuid不依赖数据库自增所以这个问题不存在。如果你用的是自增ID迁移时要特别注意。第三是并发写入。SQLite在并发写入时会有锁竞争PostgreSQL的并发处理能力强很多。如果你的应用有多用户同时写入的场景生产环境必须用PostgreSQL。迁移步骤很简单改一下datasource的provider和url然后重新生成迁移datasource db { provider postgresql url env(DATABASE_URL) }npx prisma migrate dev --name switch_to_postgresPrisma会自动生成对应的迁移SQL你检查一下没问题就可以应用。6. 我个人的实操体会这个项目我从零到能跑起来前后大概花了三个周末。最大的感受是AI辅助编码的效率提升是真实的但前提是你自己得清楚要做什么。如果你对项目架构没有清晰的规划AI生成的代码会越堆越乱最后变成一团你不敢改的意大利面。另一个体会是数据模型的设计值得多花时间。我一开始图省事把事件的所有字段都塞在一张表里结果后面加功能时发现字段越来越多很多字段大部分事件都用不上。后来改成核心字段加metadata JSON的方案清爽了很多。这个重构花了我一整天但如果一开始就想清楚这时间完全可以省下来。还有一点不要迷信AI生成的代码。我遇到过好几次AI生成的查询逻辑看起来没问题但实际跑起来结果不对的情况。后来我养成了一个习惯AI生成的每个数据库查询我都会手动跑一遍用真实数据验证结果。这个习惯帮我提前发现了好几个隐蔽的bug。最后分享一个小技巧把常用的提示词存成模板。比如“基于以下Prisma Schema生成Express路由”、“生成一个React表单组件包含以下字段”、“帮我排查这个错误...”。这些模板能让你和AI的协作更高效不用每次都重新描述上下文。我大概存了十几个模板覆盖了日常开发的大部分场景用起来很顺手。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑