Vue3 开发规范
前言
团队协作中,统一的开发规范能显著降低沟通成本和维护难度。
本文整理一套简洁通用的 Vue3 开发规范,涵盖代码风格、组件设计、项目结构与性能优化。
适用于 Vue3 + Composition API + TypeScript 技术栈,其他变体可按需调整。
常见命名方式
开发中常见的命名风格主要有以下几种,了解它们有助于在不同场景下选择合适的写法。
| 命名方式 | 规则 | 示例 | 常见用途 |
|---|---|---|---|
| PascalCase(大驼峰) | 每个单词首字母大写 | UserProfile、MyComponent |
Vue 组件名、TypeScript 类/接口/类型 |
| camelCase(小驼峰) | 首单词小写,后续单词首字母大写 | userName、getList |
变量、函数、Props、对象属性 |
| kebab-case(短横线) | 全小写,单词间用 - 连接 |
user-profile、get-list |
文件名、CSS 类名、URL 路径、HTML 属性 |
| snake_case(下划线) | 全小写,单词间用 _ 连接 |
user_name |
数据库字段、后端接口参数 |
| UPPER_SNAKE_CASE(大写下划线) | 全大写,单词间用 _ 连接 |
MAX_COUNT、API_BASE_URL |
常量、环境变量 |
前端 Vue3 项目中,最常用的是 PascalCase、camelCase 和 kebab-case 三种。
基本要求
TypeScript 规范
- 所有变量、函数参数、返回值必须声明类型,禁止使用
any。 - 优先使用
interface定义对象结构,type用于联合类型或工具类型。 - 枚举使用
const enum或字符串字面量联合类型。
1 | // 推荐 |
Vue 规范
- 使用
<script setup lang="ts">语法糖,不使用 Options API。 - 组件名使用 PascalCase,模板中使用 kebab-case。
- Props 必须声明类型,使用 TypeScript 类型声明而非运行时声明。
- 事件命名使用 camelCase,如
update:modelValue。 - 组件稍微复杂的要做到模板、脚本和样式分离。
包管理
使用PNPM进行包管理
代码格式
- 使用 2 空格缩进,不使用 Tab。
- 字符串统一使用单引号
',模板字符串使用反引号`。 - 语句末尾不加分号(遵循项目 ESLint 配置)。
- 每行不超过 100 个字符,超长时换行对齐。
注释规范
- 复杂逻辑必须添加注释,说明意图而非描述代码。
- 使用 JSDoc 格式为公共函数添加文档注释。
- TODO 注释格式:
// TODO(作者): 说明
1 | /** |
错误处理
- 异步操作必须使用
try/catch或.catch()处理错误。 - 不要吞掉错误,至少打印日志或上报监控。
- 组件级错误使用
onErrorCaptured捕获。
避免的写法
- 禁止使用
var,统一使用const/let。 - 禁止使用
==,统一使用===。 - 禁止在
computed中产生副作用。 - 禁止直接操作 DOM,优先使用 Vue 指令和 ref。
- 避免过深的嵌套,超过 3 层时考虑拆分函数。
代码习惯
- 禁止多层代码嵌套,需要嵌套的使用Promise进行封装。
- 工具类方法保证不同的工具类中方法名不要重复。
项目结构
推荐目录
1 | src/ |
文件命名
页面文件与路由路径保持一致,使用 kebab-case。
类型定义文件以 .d.ts 或 types.ts 结尾。
组合式函数以 use 开头,如 useAuth.ts。
1 | src/pages/user-profile/index.vue |
路径别名
在 vite.config.ts 中配置路径别名,避免多层相对路径。
1 | import path from 'node:path' |
路径规范
文件夹命名
- 普通文件夹使用 kebab-case,如
user-profile/、composables/。 - 组件文件夹使用 PascalCase,如
UserProfile/、BaseButton/。
文件命名
- 页面组件与路由路径保持一致,使用 kebab-case,如
user-profile/index.vue。 - 通用组件使用 PascalCase,如
UserProfile.vue、BaseButton.vue。 - 工具函数、组合式函数使用 camelCase,如
useAuth.ts、formatDate.ts。 - 类型定义文件以
.d.ts或types.ts结尾,如user.d.ts、api.types.ts。
路由路径
- 路由 path 使用小写,多个单词用
-连接,如/user-profile、/order-detail。 - 动态参数使用 camelCase,如
/user/:userId。
导入路径
- 使用
@/别名指向src/目录,避免多层相对路径。 - 第三方库放最前,
@/别名次之,相对路径放最后。
1 | // 推荐 |
代码风格
命名规范
组件文件名使用 PascalCase,如 UserProfile.vue。
工具函数、变量使用 camelCase,常量使用 UPPER_SNAKE_CASE。
CSS 类名使用 kebab-case,如 user-profile-card。
1 | // 组件引用 |
ESLint 配置
推荐使用 @antfu/eslint-config 或官方 eslint-plugin-vue 的 flat config 模式。
1 | pnpm add -D eslint @antfu/eslint-config |
在项目根目录创建 eslint.config.js:
1 | import antfu from '@antfu/eslint-config' |
oxc/pretter
代码格式
使用 Prettier 或 ESLint 统一格式化,配置 .editorconfig 保持团队一致。
1 | # .editorconfig |
组件设计
组件结构
单文件组件内部按以下顺序组织代码块:<script> → <template> → <style>。<script> 中使用 <script setup lang="ts"> 语法糖,保持代码简洁。
1 | <script setup lang="ts"> |
Props 定义
优先使用 TypeScript 类型声明的方式定义 Props,而非运行时声明。
必须声明类型,避免使用 any。
1 | // 推荐 |
组件粒度
单一组件代码不超过 300 行,超过时应拆分子组件。
通用 UI 元素(按钮、弹窗、表格)抽到 components/ui/ 目录。
业务组件按功能模块分目录存放。
组件通信
父子通信用 props + emit,不要直接修改 props。
跨层级通信用 provide / inject 或状态管理库。
兄弟组件优先通过共同父组件中转,避免事件总线。
性能优化
组件懒加载
路由级别使用动态导入实现懒加载,减少首屏加载体积。
1 | const routes = [ |
响应式精准化
小范围响应式数据用 ref,复杂对象用 reactive。
从 reactive 对象解构时使用 toRefs,避免丢失响应性。
1 | const state = reactive({ name: '', age: 0 }) |
列表渲染
v-for 必须提供稳定且唯一的 key,不要使用 index 作为 key。
大数据列表考虑使用虚拟滚动组件(如 vue-virtual-scroller)。
Getting Started | Vue Virtual Scroller
1 | <template> |
计算属性与缓存
派生数据统一使用 computed,不要在模板中写复杂表达式。
避免在 computed 中产生副作用。
1 | // 推荐 |
在 computed 的上下文中,副作用指的是除了返回值以外,对系统产生的任何其他影响。
常见的违规操作包括:
- ❌ 修改其他响应式变量(如
ref,reactive,data) - ❌ 调用 API / 发送网络请求 (
fetch,axios) - ❌ 操作 DOM (
document.getElementById,window.scrollTo) - ❌ 使用定时器 (
setTimeout,setInterval) - ❌ 打印日志 (
console.log—— 虽然无害但属于副作用) - ❌ 调用会改变外部状态的函数
图片与资源
静态图片放 src/assets/ 并通过模块导入,构建时自动处理。
外部大图使用懒加载指令或 Intersection Observer。
图标优先使用 SVG sprite 或图标库,减少 HTTP 请求。
图片尽量使用WebP。
1 | <script setup lang="ts"> |
测试相关
已改BUG标记后当日发版并通知测试人员
对其他端要求
原型/效果图
- 原型上面的模块和下面的页面分类名称定义清晰
- 效果图不要在原图上添加色块、分类要清晰
- 设计参考组件库
- 设计效果注意组件分组
- 设计图页面分组和排序
接口
文档返回值类型和必填要符合实际情况
要按应用业务模块归类
不要产生业务不需要的接口
字段不能缺失,也不能冗余
接口变更后文档要同步更新
测试
- 要有版本机制,杜绝只有主干的模式