> 技术文档 > 从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析_cursor 写前端代码

从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析_cursor 写前端代码

Cursor 编程实践与案例分析

Cursor 编程实践与案例分析

1. 什么是 Cursor?

Cursor 是一款面向开发者的 AI 编程助手,集成于本地 IDE,支持自然语言与代码的无缝协作。它不仅能自动补全、重构、查找代码,还能理解业务上下文,辅助解决实际开发中的复杂问题。

2. Cursor 在实际工作中的优势

高效代码检索:通过自然语言描述,快速定位项目中的相关代码、表结构、业务逻辑。

智能代码生成与重构:根据业务需求自动生成方法、SQL、接口,减少重复劳动。

业务流程梳理:能根据业务描述,自动梳理出数据流、调用链,辅助理解和优化系统。

问题定位与修复:遇到报错或异常时,能快速分析原因并给出修复建议。

文档与注释生成:自动生成方法注释、接口文档、技术分享材料等。

2.1 Cursor和其他智能体的区别

维度 GitHub Copilot ChatGPT Cursor 交互方式 代码补全、片段生成 文本对话、单文件生成 IDE 集成、多文件项目生成 项目支持 适合零散代码片段 缺乏项目结构理解 支持完整项目架构生成 业务理解 依赖上下文有限 需明确需求描述 可解析业务流程与数据模型 新手友好度 适合有经验开发者 需人工整合代码 自动生成可运行项目结构 协作能力 个人开发辅助 缺乏团队协作支持 支持多人协作代码审查

2.2 Cursor 使用建议与局限性

  1. 高效使用策略
  1. 自然语言技巧:使用 “分析”“优化”“生成” 等关键词明确需求,如 “生成 Vue3 组件的单元测试用例”
  1. 分阶段开发:将复杂项目分解为模块,逐步让 Cursor 生成各部分代码
  1. 代码审查机制:生成代码后进行二次 Review,确保业务逻辑与安全性
  1. 当前局限性
  1. 复杂项目处理:尚无法独立完成中大型项目的全流程开发,需人工拆解需求
  1. 深度业务理解:对于高度定制化的业务逻辑,可能需要多次交互才能准确实现
  1. 性能优化能力:在算法级优化、底层代码调优方面仍需人工介入

2.3 Cursor的配置和使用

  • Model
  • Agent
  • Bug Finder

  • rule

https://cursor.directory/

Markdown
# 项目基础说明

- 本项目基于 Vue 3 + TypeScript + Element Plus + Pinia + Vite 搭建。
- 采用组合式 API(``)进行开发。
- 状态管理使用 Pinia,模块化组织。
- 路由使用 Vue Router,采用权限动态路由配置。
- 接口请求统一封装在 `@/utils/request.ts` 中,使用 Axios。
- 表格、表单页面基于 Element Plus 封装通用组件,提高复用性。

# 组件和文件命名规范

- 组件文件名使用 `PascalCase` 格式,例如:`UserTable.vue`, `LoginForm.vue`
- 公共组件放置在 `src/components/` 下,业务组件可放在 `src/views/模块/components/` 中
- 文件夹名和非组件 `.ts/.scss` 文件使用 `kebab-case` 格式,例如:`user-api.ts`, `login-form.scss`
- 页面文件命名与路由保持一致,使用 `kebab-case`,例如:`user-list.vue`, `role-edit.vue`

# 样式和 CSS 使用约定

- **优先使用原子类:** 使用 UnoCSS 提供的原子类进行布局和样式,例如常见的 flex 布局(`flex justify-center items-center` 等)。样式语义明确,便于维护。
- **常用组合提取为全局快捷方式:** 对于**频繁使用**的原子类组合,应在 `unocss.config.ts` 中通过 `shortcuts` 定义全局组合类。例如:将 `flex justify-center items-center` 定义为 `flex-center`,这样可以在整个项目中复用。组合类命名应简洁且语义化,反映布局或功能意图。
- **非常用组合使用局部类:** 对于特定组件中使用但不常见的、超过3个的原子类组合,应该在组件内使用局部CSS类(使用``块),避免过多的全局组合污染全局命名空间。
- **避免重复代码:** 不论是通过全局`shortcuts`还是局部CSS类,都应避免在多个地方重复编写相同的原子类列表,保持代码 DRY(Don\'t Repeat Yourself)原则。
- **样式优先级:** 优先考虑 UnoCSS 解决方案(原子类或组合类),其次才是传统 CSS。当需要使用传统 CSS 时,遵循 BEM 命名规范,即 `block__element--modifier` 格式。

# 导入顺序规范(保持统一结构)

1. Vue 相关 API(如 `ref`, `computed`, `onMounted`)
2. 第三方库(如 `element-plus`, `axios`)
3. 工具函数(如 `@/utils/*`)
4. 状态管理(如 `@/store/*`)
5. 项目内部组件、模块(如 `@/components`, `@/views`)
6. 样式文件

# 开发注意事项

- 使用 TypeScript,避免使用 `any`;
- 组件职责单一,保持结构清晰;
- 所有组件必须使用组合式 API;
- 适当添加注释,提升 AI 理解。

3. 典型工作流与实际案例

3.1 代码检索与业务理解

场景:需要理解某个业务流程涉及的表结构和数据流。

实际操作

  • 用 Cursor 搜索 operation_type字段,快速定位 course_times_detail_operation_tasks表的结构和各类型的业务含义。
  • 通过自然语言提问“帮我分析 getCourseChangeList 这方法的逻辑 流程 和sql”,Cursor 自动梳理出控制器、业务层、SQL 的完整调用链和数据流。

3.2 智能代码生成与重构

场景:实现课次回收功能

文本需求描述

Bash
在CourseTimesConvertRecycleTaskJobBusiness的task里面,我要实现以下功能,
接收参数如下
task($payTaskId=0,$freeTaskId=0,$operationContent)
1.task里面处理两个任务,一个是付费,一个是免费,至少有一个是非空的,operationContent是执行的具体内容
2.通过 TaskService::getInstance()->getInfoByID($taskId); 获取任务信息,任务表是course_times_detail_operation_tasks,operation_rule的内容如下
付费:{\"type\": \"pay\", \"datas\": {\"course_amount\": 10, \"source_course_num\": 10, \"target_course_num\": 10, \"convert_performance_no_list\": [{\"course_amount\": 1, \"channel_order_no\": \"CT-20250123193907602208973\", \"source_course_num\": 1, \"target_course_num\": 1, \"source_performance_no\": \"CT-20250123193907602208973\"}, {\"course_amount\": 9, \"channel_order_no\": \"CT-20250123193907723463141\", \"source_course_num\": 9, \"target_course_num\": 9, \"source_performance_no\": \"CT-20250123193907723463141\"}]}}

免费:{\"type\": \"free\", \"datas\": {\"course_amount\": 0, \"source_course_num\": 10, \"target_course_num\": 10, \"convert_performance_no_list\": [{\"channel_order_no\": \"CT-20250123193907602208973\", \"source_course_num\": 2, \"target_course_num\": 2, \"source_performance_no\": \"CT-22250123193908450905348\"}, {\"channel_order_no\": \"CT-20250123193907723463141\", \"source_course_num\": 8, \"target_course_num\": 8, \"source_performance_no\": \"CT-22250123193908450905349\"}]}}

对应的字段名含义如下:
\"course_amount\": \"金额\",
\"target_course_num\": \"目标课次\",
\"source_course_num\": \"源课次\",
\"convert_performance_no_list\": \"转换履约单列表\",
\"channel_order_no\": \"渠道订单号\",
\"source_performance_no\": \"源履约单号\",
\"source_course_num\": \"源课次\",
\"course_amount\": \"金额\",
\"target_course_num\": \"目标课次\"

开启事务

1.接下来需要循环convert_performance_no_list 插入课次回收流水表course_times_card_account_recycle_flows,插入数据AccountRecycleFlowService的addRecycleFlow方法
public function addRecycleFlow($datas)
{
$model = new AccountRecycleFlowsModel();
$model->user_id = $datas[\'user_id\'];
$model->recycle_trans_no = $datas[\'recycle_trans_no\'];
$model->trans_no = $datas[\'trans_no\'];
$model->card_no = $datas[\'card_no\'];
$model->operation_type = $datas[\'operation_type\'];
$model->performance_no = $datas[\'performance_no\'];
$model->work_order_no = $datas[\'work_order_no\'];
$model->amount = $datas[\'amount\'];
$model->num = $datas[\'num\'];
$model->save();

return $model->toArray();
}
里面的user_id是task表的user_id,recycle_trans_no是 AccountPerformancesModel::makeTransNo(\"CCR\")方法生成的;,trans_no是$TransNo = AccountPerformancesModel::makeTransNo(OperationTasksModel::OPERATION_TYPE_PREFIX[OperationTasksModel::OPERATION_TYPE_LIST[\'convert_recycle\']])生成的;,operation_type是task表的operation_type,performance_no是convert_performance_no_list元素里的source_performance_no,work_order_no是task表的work_order_no,amount是convert_performance_no_list元素里的course_amount,num是convert_performance_no_list元素里的source_course_num

2.更新convert_performance_no_list元素里的每一个source_performance_no的课次,操作course_times_card_account_performances课次订单结果表,参考这个方法
AccountPerformancesModel::where(\'performance_no\', $performanceNo)->decrement(\'freeze_num\', $sourceCourseNum);

3.回收课次账户下对应的冻结课次,操作course_times_card_accounts表,参考这个方法

public function subtractFreezeBumOrPresentFreezeNumByCarNo($type, $num, $cardNo)
{
//课次账户的付费冻结课次
if ($type == 1) {
AccountsModel::where(\'card_no\', $cardNo)->decrement(\'freeze_num\', $num);
} else {
//课次账户的赠送冻结课次
AccountsModel::where(\'card_no\', $cardNo)->decrement(\'present_freeze_num\', $num);
}
}

4.完成课次回收操作后,开始通知订单服务执行新的履约
$res = ChannelPlatformService::getInstance()->convertRechargeCourse($operationContent);

提交事务,返回结果

请帮我实现以上功能

继续优化

1.formateOperationContent有很多foreach 能不能简化

2.将单sql操作改成批量执行,减少对数据库的操作次数

收益:节省了大量手写和调试 SQL 的时间,代码风格统一,易于维护。

接口文档需求描述

JSON
{
\"规则名称列表【搜索用】\": {
\"url\": \"/plan/rule/getRuleNameList\",
\"method\": \"GET\",
\"params\": {

},
\"response\": {
\"code\": 200,
\"msg\": \"success\",
\"data\": [
{
\"id\": 1,
\"title\": \"窦神归来-周日\"
},
{
\"id\": 1,
\"title\": \"窦神归来-周日\"
}
]
}
},
\"tag_dict增加联动关系 增加接口\": {
\"url\": \"/tag/hierarchy\",
\"method\": \"GET\",
\"params\": {

},
\"response\": {
\"code\": 200,
\"msg\": \"OK\",
\"data\": {
\"list\": [
{
\"subject_id\": \"43\",
\"subject_name\": \"英语\",
\"item_list\": [
{
\"item_id\": \"44\",
\"item_name\": \"系统课\",
\"category_type_list\": [
{
\"category_type_id\": \"47\",
\"category_type_name\": \"阅读大师课\"
},
{
\"category_type_id\": \"48\",
\"category_type_name\": \"大师精讲课\"
},
{
\"category_type_id\": \"49\",
\"category_type_name\": \"大师晨读课\"
}