大家好,作为前端开发者,我们都在享受 AI 编码助手(如 Cursor、OpenCode)带来的效率提升。但你是否也遇到过:AI 生成的代码风格混乱、命名不统一、TypeScript 类型缺失、甚至引入项目中从未用过的依赖?这些问题不仅没有提升效率,反而增加了大量的 Code Review 成本。
今天,我就分享一套经过实战打磨的Vue 3 + TypeScript 项目 AI 编码助手规则集,它能帮你从源头约束 AI 行为,让 AI 生成的代码从第一行就符合团队规范,真正做到 "拿来就能用"。




一、为什么需要给 AI 制定 "员工手册"?
AI 编码助手就像一个新入职的实习生:它能力很强,但完全不了解你的项目约定。如果不给它明确的规则,它就会按照自己的 "通用常识" 写代码,结果往往是:
- 风格不统一:一会儿 PascalCase,一会儿 camelCase
- 依赖满天飞:不管项目用的 UI 库,强行引入新组件
- 类型 any 泛滥:把 TypeScript 写成了 AnyScript
- 架构混乱:无视项目目录结构,到处创建文件
解决这些问题的根本方法,就是给 AI 制定一套清晰、可执行的 "行为准则",让它在你的项目里也能像老员工一样 "守规矩"。
二、我的 Vue 项目 AI 规则集全景
我将规则分为了 4 个核心文件,覆盖了从通用行为到具体编码细节的所有场景:
.agents/rules/common.md:通用编码规范(Vue3+TS 基础约定).agents/rules/vue.md:Vue 3 组件专属规范.agents/rules/css.md:样式编写规范(BEM 命名等).agents/rules/agent.md:AI 助手通用行为准则
下面我为你逐一拆解每个文件的核心内容与设计思路。
📄 1. 通用编码规范 (common.md)
这是整个规则集的基础,定义了所有代码都必须遵守的 "宪法级" 约定。
核心规则概览
表格
| 模块 | 关键约定 |
|---|---|
| 基础规范 | 路径别名遵循tsconfig配置;单文件不超过 400 行;注释清晰 |
| 命名规范 | 组件名PascalCase;函数camelCase;常量UPPER_SNAKE_CASE |
| TypeScript | 优先interface;禁止滥用any;props默认值用withDefaults |
| 导入与排序 | 按「类型导入 → 第三方库 → Vue 官方库 → 项目内部」分组 |
| 目录组织 | 遵循components/views/composables/stores约定 |
| 最佳实践 | 组件优先复用 UI 库;响应式优先用ref/computed;重复逻辑下沉 |
关键设计亮点
-
强约束的命名规则:AI 对命名的理解往往很模糊,这里直接规定死:
- 组件名必须是
PascalCase(如UserCard.vue) - 事件处理函数必须带
handle前缀(如handleSubmit) - 组合式函数必须带
use前缀(如useUserList)
- 组件名必须是
-
TypeScript 安全锁 :明确禁止滥用
any,并强制使用withDefaults定义props默认值,从源头杜绝类型安全问题。 -
防重复造轮子:要求 AI 优先复用项目内已有组件、工具函数,避免引入新依赖。
📄 2. Vue 3 组件专属规范 (vue.md)
这是针对 Vue 单文件组件(SFC)的 "专项约束",解决 AI 生成 Vue 代码时最容易出错的问题。
核心规则概览
-
强制 Composition API :新组件必须使用
<script setup lang="ts">,禁止 Options API -
固定代码块顺序 :
template→script setup→style -
Script 内部顺序约定:
- 类型导入
import type - 第三方库 / UI 组件
- Vue API(
ref/reactive/computed等) - 项目内模块导入
defineProps/defineEmits等编译器宏- 响应式数据、方法、生命周期钩子
- 类型导入
-
关键 API 使用规范:
defineEmits必须使用基于类型的函数调用签名,禁止数组 / 元组形式- 获取组件实例优先使用
useTemplateRef(Vue3.3+) defineExpose仅暴露父组件必须调用的方法 / 属性
关键设计亮点
- SFC 结构标准化:很多 AI 生成的 Vue 文件结构混乱,这里直接规定了代码块和内部逻辑的顺序,保证所有组件结构一致。
- 响应式规则 :明确约定 "原始值用
ref,对象用reactive,派生状态用computed",避免 AI 写出低效的响应式代码。 - 禁止项明确 :列出了 AI 最容易犯的错误,如重复导入已自动注册的组件、用
JSON.parse(JSON.stringify())做深拷贝等。
📄 3. 样式编写规范 (css.md)
AI 写 CSS 时最容易放飞自我,比如随便命名 class、滥用!important、写出嵌套过深的选择器。这个文件就是用来 "驯服" AI 的样式代码。
核心规则概览
-
BEM 命名强制约定:
- Block:
user-card(双下划线连接,禁止驼峰) - Element:
user-card__avatar(双下划线连接) - Modifier:
user-card--compact(双横杠表示状态)
- Block:
-
SFC 样式块规范 :默认使用
scoped,必须覆盖第三方样式时需注释说明 -
编写原则 :优先使用项目 CSS 变量;避免魔法数字;禁止滥用
!important -
禁止项:
- class 使用
camelCase命名 - BEM 元素链式嵌套(如
block_a__b) - 在
scoped样式中依赖深度选择器穿透多层级
- class 使用
关键设计亮点
- BEM 命名可执行化 :不仅介绍 BEM,还直接给出了
scoped中结合 SCSS 嵌套的写法示例,让 AI 知道怎么写才对。 - 防污染控制 :强制使用
scoped,并对穿透样式做严格限制,避免全局样式污染。 - 反模式清单:明确列出了 AI 写 CSS 的常见错误,让它从一开始就避开这些坑。
📄 4. AI 助手行为准则 (agent.md)
这是给 AI 助手本身制定的 "元规则",控制它的行为边界,防止它越权操作。
核心规则概览
- 通用要求:始终使用简体中文沟通;未经允许不创建文档、不执行 Git 操作
- 应当做的:改代码前阅读项目约定;优先复用已有抽象;修改后运行 lint/typecheck
- 不应当做的:擅自新增说明文档;为已自动导入的 API 写冗余 import;猜测不存在的 API 路径
关键设计亮点
- 边界控制:明确禁止 AI 执行 Git 操作、修改配置文件等危险行为,保证开发者对项目的绝对控制权。
- 效率优先:禁止 AI 做 "多余的事",比如在没有要求的情况下添加测试、注释或文档,避免干扰开发者的节奏。
三、如何在项目中落地这套规则?
步骤 1:创建规则文件目录
在项目根目录创建.agents/rules/文件夹,将上面 4 个文件放入其中。
plaintext
erlang
.
├── .agents/
│ └── rules/
│ ├── common.md
│ ├── vue.md
│ ├── css.md
│ └── agent.md
步骤 2:配置 Cursor Rules
在项目根目录创建.cursorrules文件,将所有规则文件串联起来:
markdown
yaml
---
applyTo: "**"
---
# 项目编码规范
以下规则适用于本项目所有代码,请严格遵守:
## 通用编码规范
@./.agents/rules/common.md
## Vue 3 组件规范
@./.agents/rules/vue.md
## CSS 样式规范
@./.agents/rules/css.md
## AI 助手行为准则
@./.agents/rules/agent.md
步骤 3:让 AI "看见" 规则
- 在 Cursor 中,AI 会自动读取
.cursorrules文件 - 在其他工具中,可以在每次对话时手动引用这些文件,或配置项目级别的全局指令
四、效果实测:AI 写代码的变化
在应用这套规则前后,AI 生成的代码质量有了质的变化:
表格
| 场景 | 规则前 | 规则后 |
|---|---|---|
| 组件命名 | userCard.vue(驼峰) |
UserCard.vue(PascalCase) |
| Props 定义 | const props = defineProps({ id: Number }) |
const props = withDefaults(defineProps<{ id?: number }>(), { id: 0 }) |
| Class 命名 | .headerTitle/.btn-primary |
.user-card__title/.user-card__btn--primary |
| API 调用 | 直接在组件中写 fetch | 调用项目已封装的useApi组合式函数 |
五、总结与扩展
给 AI 制定编码规范,不是为了限制它的能力,而是为了让它的能力更好地服务于你的项目。这套规则集的核心价值在于:
- 统一团队代码风格:无论谁用 AI 写代码,输出的结果都能保持一致
- 降低 Code Review 成本:AI 生成的代码天然符合规范,减少不必要的风格争论
- 提升项目可维护性:TypeScript 类型更安全、架构更清晰、样式更可控
- 解放开发者精力:你不用再花时间修正 AI 的低级错误,可以专注于业务逻辑
💡 后续优化建议
- 按需扩展:根据你的项目特性,添加更多项目特定规则,比如状态管理(Pinia)、路由、权限等
- 定期更新:随着项目迭代,不断完善规则集,将团队的最佳实践沉淀进去
- 团队共享:将这套规则同步给团队所有人,让 AI 成为统一的 "代码风格监督员"
如果你需要,我可以把这 4 个规则文件的完整 Markdown 内容整理出来,方便你直接复制使用。
觉得有用的话,欢迎点赞收藏,也欢迎在评论区分享你的 AI 编码规范实践!
附:规则文件完整模板(可直接复制)
.agents/rules/common.md
markdown
markdown
# 编码规范 (Vue 3 + TypeScript)
适用于 Vue 3 + TypeScript 前端项目的通用编码约定。Vue SFC 细节见 `vue.md`,样式见 `css.md`。
## 基础规范
- 路径别名、目录结构遵循**项目既有配置**(如 `tsconfig`、`vite.config`);避免 `../../../../` 式相对路径穿越。
- `.vue` 文件与模板中的组件使用 **PascalCase**(`UserCard.vue` / `<UserCard />`)。
- 样式 class 推荐 **kebab-case**;组件内自定义 class 推荐 BEM(见 `css.md`)。
- 单文件建议不超过 400 行,超出应拆分组件或模块。
- 注释语言、标识符语言遵循项目约定;代码标识符使用英文,含义清晰。
## 命名规范
- **组件名**: PascalCase。
- **变量 / 函数**: camelCase;事件处理函数推荐 `handle` 前缀(如 `handleSubmit`)。
- **常量**: 需要时使用 UPPER_SNAKE_CASE。
- **Props / Emits**: props 用 camelCase;模板事件名与 emits 定义用 kebab-case。
- **Composables**: 推荐 `use` 前缀(如 `useUserList`)。
- **全局组件前缀**(如有): 遵循项目统一前缀,不要自创多套命名。
## TypeScript 规范
- `import type` 与值导入分离。
- 对象结构优先 `interface`;联合类型、工具类型用 `type`。
- 组件 props 默认值使用 `withDefaults(defineProps<Type>(), { ... })`。
- 避免 `any`;确实需要时使用显式类型或窄化。
- Composables、工具函数适当使用泛型提升类型安全。
- 公共类型集中管理;领域类型靠近业务模块,按项目目录约定放置。
## Vue 相关(摘要)
以下细则见 `vue.md`,此处不重复:
- Composition API + `<script setup>`
- `defineOptions` / `defineProps` / `defineEmits` / `defineExpose`
- 模板 ref、`v-model`、事件与插槽命名
## 导入与排序
推荐分组(同组内按字母序):
1. 类型导入
2. 第三方库
3. Vue / 官方库
4. 项目内部(composables、组件、utils、样式、资源)
- 不要重复 import 已由自动导入注册的符号(类型除外)。
- 静态资源、样式按项目约定引入,避免大段内联样式。
## 目录与组织
- 遵循项目现有目录划分(如 `components`、`views`、`composables`、`stores` 等)。
- 可复用 UI 放组件目录;页面级逻辑解放 views 或路由对应模块。
- 跨页面逻辑抽到 composables;纯函数抽到 utils。
- 常量、枚举集中管理,避免魔法字符串散落。
## 代码质量与 Lint
- 遵循项目 **ESLint**、**Stylelint**、**tsconfig** 配置,不擅自关闭规则。
- 必要的 `eslint-disable` / `@ts-expect-error` 须注释说明原因。
- Vue 相关 lint(block 顺序、宏顺序、事件命名等)以项目 ESLint 配置为准。
## 最佳实践
- **组件封装**: 优先复用项目 UI 库与已有封装;透传 props / attrs 时保持 API 一致。
- **类型安全**: 接口、props、emits、composables 返回值均提供类型。
- **响应式**: 原始值用 `ref`,对象用 `reactive`,派生用 `computed`(详见 `vue.md`)。
- **性能**: 模板避免复杂计算;大列表考虑分页、虚拟滚动或拆分;按需加载路由与组件。
- **代码复用**: 重复逻辑下沉 composable 或 utils,不要复制粘贴。
## 提交流程与检查
- 包管理器与锁文件以仓库为准;变更依赖时同步更新 lockfile。
- 提交前按项目脚本执行检查(如 `lint`、`typecheck`、`test`、`build`)。
- 新文件默认带类型,避免无类型的 `any` 扩散。
.agents/rules/vue.md
markdown
markdown
# Vue 规范 (Vue 3)
适用于 Vue 3 + Composition API + `<script setup>` 的组件开发约定。
## 基础要求
- 新组件一律使用 **Composition API** + `<script setup lang="ts">`,禁止 Options API。
- 需要组件名时(调试、keep-alive、路由缓存等)使用 `defineOptions({ name: 'ComponentName' })`。
- 路由级页面组件的 `name` 建议与路由配置保持一致。
## 组件块顺序
- `<template>` → `<script setup lang="ts">` → `<style>`(样式见 `.agents/rules/css.md`)
- 遵循项目 ESLint/Vue block-order 规则。
## Script 内推荐顺序
1. 类型导入 `import type ...`
2. 第三方库 / UI 组件
3. Vue API(`ref`、`reactive`、`computed`、`watch` 等)
4. 项目内模块(composables、utils、components 等)
5. `defineOptions`(如有)
6. `defineModel`(如有)
7. `defineProps` + `withDefaults`
8. `defineEmits`(事件名 kebab-case)
9. `defineSlots`(如有)
10. 常量 / 工具函数 / composables 解构
11. 响应式数据 `ref` / `reactive`
12. `computed` 派生数据
13. 方法(推荐 `handle` 前缀,如 `handleSubmit`)
14. 生命周期 / 副作用(`onMounted`、`watch` 等)
15. `defineExpose` 放最后(如需要)
## 自动导入
若项目配置了 `unplugin-auto-import`、`unplugin-vue-components` 等,**遵循项目已有约定**:
- 已自动注册的 API / 组件不要重复手写 import。
- 仅需**类型**时使用 `import type`。
- 不确定是否自动导入时,以项目 `vite.config` 与现有代码为准。
## 模板约定
- 模板保持单根节点(或遵循 Vue 3.3+ 多根节点的项目约定)。
- 事件名、插槽名使用 **kebab-case**。
- 受控表单优先 `v-model`;修饰符与命名参数按 Vue 3 语法书写。
- 布尔 prop / 双向绑定使用显式写法(如 `:visible="visible"`、`v-model:visible="visible"`)。
- 复杂列表/表格渲染可使用 `lang="tsx"` 或 render 函数,按项目既有模式选用。
## 组件注册与引用
- 全局 / 局部组件在模板中使用 **PascalCase**(如 `<UserCard />`)。
- 不要手动 import 已由自动导入注册的组件(类型导入除外)。
- 子组件通过 props / emits 通信,避免随意访问父组件实例。
## defineEmits
- 使用**基于类型的函数调用签名**,禁止数组 / tuple 形式。
- 无参事件: `(e: 'event-name'): void`;有参事件将参数写在 `e` 之后。
```typescript
// ✅
const emit = defineEmits<{
(e: 'submit'): void
(e: 'change', value: string): void
}>()
// ❌
const emit = defineEmits({ submit: [] })()
const emit = defineEmits<{ change: [value: string] }>()
模板 Ref
- 获取子组件实例 或 DOM 元素时,优先使用
useTemplateRef(Vue 3.5+);低版本可用ref+ 同名模板 ref,与项目约定保持一致。 - 模板上的
ref属性值与useTemplateRef('...')参数字符串一致。
vue
xml
<script setup lang="ts">
import type { FormInstance } from './types'
const formRef = useTemplateRef<FormInstance>('formRef')
function submit() {
formRef.value?.validate()
}
</script>
<template>
<form ref="formRef" @submit.prevent="submit">
<!-- ... -->
</form>
</template>
defineExpose
- 仅暴露父组件组件确实需要调用的方法或属性。
- 弹窗、表单等封装组件常用
defineExpose({ open, close, reset })模式。
响应式
- 原始值用
ref,对象用reactive;派生状态用computed。 - 避免不必要的大对象
reactive;从 composable 返回时保持结构清晰。 - 解构 reactive 对象时注意响应式丢失,必要时用
toRefs。
禁止事项
- 使用 Options API 编写新组件
- 重复 import 已自动注册的 API / 组件(类型除外)
- 用无关的
ref()命名绑定模板 ref 导致语义混乱(优先useTemplateRef) defineEmits使用数组 /tuple 形式- 在模板中写复杂业务逻辑,应抽到
computed或方法 - 使用
JSON.parse(JSON.stringify())做深拷贝(优先structuredClone或项目提供的工具)
样式相关约定见 .agents/rules/css.md。
plaintext
javascript
#### `.agents/rules/css.md`
```markdown
# CSS 规范 (Vue 3)
适用于 Vue 3 单文件组件(SFC)的样式编写约定。
## SFC 样式块
- 样式块位于 `<script>` 之后:`<style lang="scss|less|css" scoped>`。
- 遵循项目的 ESLint/Vue block-order 规则(通常为 template → script → style)。
- 默认使用 **`scoped`**,避免污染全局;需要全局样式时须在注释中说明原因。
- 预处理器(SCSS/LESS)与纯 CSS 按项目既有约定选用,同一组件内保持一致。
## 命名约定
- 自定义 class 使用 **kebab-case**。
- 组件内自定义 class 推荐 **BEM**(Block Element Modifier)。
- 第三方 UI 库自带类名、项目全局工具类不在 BEM 约束范围内;仅约束本组件新增的 class。
## BEM 结构
| 类型 | 格式 | 示例 |
| :--- | :--- | :--- |
| Block(块) | `block` | `user-card`、`search-form` |
| Element(元素) | `block__element` | `user-card__avatar`、`search-form__input` |
| Modifier(修饰符) | `block--modifier` 或 `block__element--modifier` | `user-card--compact`、`search-form__btn--disabled` |
约定:
- **Block** 对应当前组件语义,一个 SFC 通常只设一个 Block。
- **Element** 用双下划线 `__` 连接 Block;多级语义用 `-` 连接,**禁止** `block__a__b` 链式元素写法。
- **Modifier** 用双连字符 `--` 表示状态或变体(如 `--active`、`--disabled`、`--compact`)。
- 在 `<style scoped>` 中优先用预处理器嵌套表达 BEM(`&__element`、`&--modifier`)。
```vue
<template>
<div class="user-card">
<img class="user-card__avatar" :src="avatar" alt="">
<div class="user-card__body">
<h3 class="user-card__name">{{ name }}</h3>
<span class="user-card__badge user-card__badge--vip">VIP</span>
</div>
</div>
</template>
<style lang="scss" scoped>
.user-card {
display: flex;
gap: 12px;
&__avatar {
width: 48px;
height: 48px;
border-radius: 50%;
}
&__name {
margin: 0;
font-size: 16px;
}
&__badge {
font-size: 12px;
&--vip {
color: var(--color-warning, #faad14);
}
}
}
</style>
编写原则
- 颜色、间距、字号优先复用项目 CSS 变量或设计令牌,避免魔法数字。
- 动画与过渡可复用的,抽到公共样式;组件内只写与布局 / 状态相关的差异。
- 避免内联
style;动态样式(如宽高、坐标)等场景除外。 - 尽量避免
!important;确需覆盖第三方样式时注明原因。
Stylelint
- 遵循项目已配置的 Stylelint 规则(如 standard、scss、recommended-vue、recess-order 等)。
- 属性顺序以 Stylelint 输出为准;class 命名推荐 BEM/kebab-case。
- 样式改动后按项目脚本执行 lint(如
lint:style)。
禁止事项
- ❌ 自定义 class 使用 camelCase 或非语义命名(如
.headerTitle、.activeBtn) - ❌ BEM 元素链式嵌套(如
block__a__b,应扁平为block__a-b) - ❌ 滥用
!important覆盖样式 - ❌ 在组件内写大段内联
style(特殊动态样式除外) - ❌ 在 scoped 样式中依赖未声明的深度选择器穿透(
:deep()等)堆叠过多层级
plaintext
diff
#### `.agents/rules/agent.md`
```markdown
# Agent 行为准则
适用于 Cursor、OpenCode、Codex 等 AI 编码助手。
## 通用要求
- 始终使用**简体中文**与用户沟通。
- 未经用户明确要求,**不要**创建说明文档(README、*.md 等)。
- 未经用户明确要求,**不要**执行 git commit / push / 修改 git 配置。
- 改动范围最小化:只改与任务直接相关的代码,不顺手重构无关模块。
- 优先复用项目已有抽象与约定,禁止凭空引入新架构或重复造轮子。
## 应当
- 改代码前先阅读项目既有实现与目录约定,保持风格一致。
- 优先复用项目内已有组件、composables、工具函数与 API 封装。
- 任务完成后,在合适时运行项目配置的 lint / typecheck / test 脚本(若与改动相关)。
- 存在分层文档或 skills 时,**按需读取**与当前任务相关的部分,不要预加载全部。
## 不应
- 擅自新增说明性 Markdown 文档(除非用户明确要求)。
- 为已自动导入的 API / 组件写冗余 import。
- 引入与项目技术栈不符的 UI 库或全新抽象层。
- 猜测不存在的 API 路径、响应结构或配置项;以项目代码与类型定义为准。
- 在用户未要求时添加测试、文档或无关注释。