Skip to content

编码约定

文件命名

  • 组件:PascalCase.vue(如 TextNode.vueCanvasToolbar.vue
  • Composables:useCamelCase.ts(如 useCanvas.tsuseNodeActions.ts
  • Store:camelCase.ts(如 canvasStore.ts
  • 工具函数:camelCase.ts
  • 类型定义:与使用者同文件,或 types/ 目录下 camelCase.ts
  • 测试文件:[filename].test.ts(单元测试)、[filename].spec.ts(E2E 测试)

目录结构

  • 页面组件 → pages/(Nuxt 文件路由)
  • 跨页面共享组件 → components/
  • 仅单页面使用的组件 → 该页面目录内
  • Vue Flow 自定义节点 → components/nodes/
  • 全局状态 → stores/
  • Composables → composables/
  • AI 服务 → services/ai/
  • HTTP 客户端 → services/http/
  • 类型定义 → types/

组件规范

  • 使用 <script setup lang="ts">
  • Props 必须类型化:defineProps<{ ... }>()
  • Emits 必须类型化:defineEmits<{ ... }>()
  • 组件最大约 200 行,超出则拆分子组件
  • 优先使用 Nuxt UI 组件

Vue Flow 自定义节点

  • 每种节点类型一个组件文件(TextNode.vueImageNode.vue 等)
  • 节点组件统一放在 components/nodes/
  • 节点内部配置(Prompt、模型选择、生成按钮)内嵌在节点组件中,不使用外部面板
  • 连接点使用 Vue Flow 的 <Handle> 组件

状态管理

  • 本地状态:仅当前组件使用的数据,用 ref / reactive
  • 全局 Store:跨组件共享的数据(画布列表、当前画布),用 Pinia
  • Vue Flow 状态:节点和连线数据,通过 useVueFlow composable 管理

样式

  • 使用 Nuxt UI 内置样式体系
  • 自定义样式优先用 Tailwind 工具类
  • 使用 Nuxt UI canonical class(如 border-defaultbg-mutedtext-highlighted),禁止使用 CSS 变量引用形式(如 border-(--ui-border)bg-(--ui-bg-muted)
  • 深色主题:使用 CSS 变量,所有颜色值走主题变量
  • 避免内联 style,除非是动态计算值(如节点位置)

TypeScript

  • 严格模式,禁止 any
  • 优先 interface(对象形状),type(联合类型/交叉类型)
  • 使用 as const 替代 enum

Import 排序

由 ESLint 自动处理,规则如下:

  1. Vue / Nuxt 框架导入(vuenuxt/app#imports
  2. 第三方库(@vue-flow/corepinia 等)
  3. 项目内模块(~/composables~/stores~/types 等)

各组之间保留一个空行。

测试

  • 单元测试框架:Vitest
  • 组件测试:@vue/test-utils + happy-dom
  • E2E 测试:Playwright
  • 单元测试放在 test/unit/,Nuxt 集成测试放在 test/nuxt/,E2E 测试放在 tests/
  • 运行命令:pnpm test(全部)、pnpm test:unit(单元)、pnpm test:e2e(E2E)

禁止模式(Anti-patterns)

以下是开发和 AI agent 生成代码时常犯的错误,必须避免:

状态管理

  • 禁止在 action 外直接修改 store state — 所有状态变更必须通过 store action,不得在组件中直接赋值 store.someState = newValue
  • 禁止 store 间循环依赖 — store 依赖必须是单向的,不得 A store 调用 B store 且 B store 调用 A store
  • 禁止在 computed 中执行副作用 — computed 只做纯计算,不得在其中调用 API、修改 state 或触发导航

异步与错误处理

  • 禁止忽略 async 错误 — 所有异步操作(API 调用、文件操作)必须有 try/catch 或 .catch() 处理
  • 禁止在组件卸载后操作 DOM 或更新 state — 异步回调中必须检查组件是否仍然挂载,或使用 AbortController
  • 禁止 await<script setup> 顶层使用而不包在 Suspense 中 — 会阻塞组件渲染

数据流

  • 禁止双向数据绑定绕过单向数据流 — 子组件不得直接修改 props,必须通过 emit 通知父组件
  • 禁止在 watcher 中触发被 watch 的值变更 — 会造成无限循环
  • 禁止将 Vue Flow 内部状态当作 source of truth — 持久化数据以 canvasStore 为准,Vue Flow 仅用于渲染

Import 与依赖

  • 禁止从 packages/shared 引入运行时逻辑 — shared 包只包含类型和常量
  • 禁止组件直接调用 HTTP 客户端 — 必须通过 services 层封装,组件 → composable → service → HTTP
  • 禁止在 components/ 中放非组件文件 — 工具函数放 utils/,composable 放 composables/

Git

  • 分支命名:feat/xxxfix/xxxrefactor/xxx
  • Commit 使用 conventional commits:feat:fix:refactor:docs:chore: