1. Vue项目代码规范的重要性刚接手一个Vue项目时最头疼的就是看不懂前人写的代码。组件命名乱七八糟有的叫userList.vue有的叫DataTable.vue还有的直接用拼音缩写。方法名更是随心所欲getData、fetchInfo、queryList各显神通。这种项目维护起来简直是一场噩梦每次修改都像在拆炸弹。我在实际项目中踩过不少坑。曾经有个电商项目因为缺乏统一规范三个开发人员写了三种风格的代码。结果每次合并代码都冲突不断上线后Bug频出。后来我们花了整整两周时间重构代码制定了严格的规范开发效率直接提升了40%。好的代码规范能带来三个明显好处可读性像读报纸一样轻松理解代码逻辑可维护性新人接手项目不再需要考古协作效率Git合并时不再需要解决命名冲突2. 项目结构与文件命名2.1 目录结构规范一个典型的Vue项目目录应该像这样清晰my-project/ ├── public/ # 静态资源 ├── src/ │ ├── assets/ # 静态资源 │ ├── components/ # 公共组件 │ │ ├── base/ # 基础组件 │ │ ├── business/ # 业务组件 │ ├── composables/ # 组合式函数 │ ├── router/ # 路由配置 │ ├── stores/ # 状态管理 │ ├── styles/ # 全局样式 │ ├── utils/ # 工具函数 │ ├── views/ # 页面组件 │ ├── App.vue # 根组件 │ └── main.js # 入口文件关键原则按功能而非类型组织文件避免把所有utils放一个文件夹控制单目录文件数量超过10个考虑子目录保持目录层级扁平最好不超过3层2.2 文件命名规则不同文件类型采用不同命名风格// 组件文件 - PascalCase UserProfile.vue BaseButton.vue // JS/TS文件 - kebab-case user-api.js date-utils.ts // 图像文件 - 小写下划线 user_avatar.png banner_main.jpgVue单文件组件必须使用PascalCase这是社区共识。我见过有人用user-profile.vue命名组件结果在模板中使用时极其混乱!-- 错误示范 -- user-profile / !-- 看起来像HTML原生标签 -- !-- 正确示范 -- UserProfile / !-- 一眼就知道是组件 --3. Vue组件开发规范3.1 组件分类与命名Vue组件应该分为四类每类有明确的前缀基础组件以Base前缀开头BaseButton.vue BaseIcon.vue业务组件以Custom前缀开头CustomOrderCard.vue CustomProductGallery.vue单例组件以The前缀开头TheHeader.vue TheSidebar.vue紧密耦合组件以父组件名开头TodoList.vue TodoListItem.vue3.2 组件代码结构一个标准的Vue组件应该按以下顺序组织代码script setup // 1. 组件名 defineOptions({ name: UserProfile }) // 2. Props const props defineProps({ userId: { type: Number, required: true } }) // 3. Emits const emit defineEmits([update:modelValue]) // 4. 组合式函数 const { user, loading } useUser(props.userId) // 5. 方法 function handleSave() { // ... } /script template !-- 模板内容 -- /template style scoped /* 样式 */ /style提示使用script setup语法糖可以让代码更简洁。我在迁移旧项目到Vue3时组件代码量平均减少了30%3.3 Props设计原则设计Props时要考虑周全defineProps({ // 基础类型检查 title: String, // 多个可能的类型 width: [String, Number], // 必填项 id: { type: Number, required: true }, // 默认值 size: { type: String, default: medium }, // 自定义验证 status: { validator(value) { return [active, inactive].includes(value) } } })我在设计表单组件时踩过坑没有对props做严格验证导致传入非法值时组件直接崩溃。后来加上了validator调试时间减少了70%。4. 代码风格与最佳实践4.1 模板编写规范模板中要注意这些细节!-- 属性换行 -- MyComponent :titlepageTitle :datatableData changehandleChange / !-- v-for必须带key -- li v-foritem in list :keyitem.id {{ item.name }} /li !-- 避免v-if和v-for一起用 -- template v-ifshowList ListItem v-foritem in filteredList :keyitem.id / /template4.2 脚本部分规范脚本部分的一些黄金法则// 变量命名 - 前缀表明类型 const userList ref([]) // ref响应式变量 const loading ref(false) // 布尔值加is/has/can前缀 const apiService inject(api) // 服务注入 // 方法命名 - 动词开头 function fetchUser() {} function handleSubmit() {} function validateForm() {} // 自定义事件 - kebab-case function emitEvent() { emit(update:model-value) }4.3 样式编写建议样式部分容易忽视的要点/* 使用scoped避免污染全局 */ style scoped /* BEM命名规范 */ .user-profile { __header { /* ... */ } __body { --loading { /* ... */ } } } /* 深度选择器慎用 */ :deep(.third-party-class) { /* ... */ } /style在大型项目中我推荐使用CSS Modules替代scopedtemplate div :classstyles.container !-- ... -- /div /template style module .container { /* ... */ } /style5. 工具链与自动化5.1 ESLint配置推荐使用vue/eslint-config-standard配置// .eslintrc.js module.exports { extends: [ vue/eslint-config-standard ], rules: { vue/multi-word-component-names: off, vue/attribute-hyphenation: [error, always] } }关键规则强制组件名多单词避免与HTML标签冲突模板属性使用kebab-case禁止v-if和v-for混用5.2 Prettier集成与ESLint配合的.prettierrc配置{ semi: false, singleQuote: true, printWidth: 100, htmlWhitespaceSensitivity: ignore }在团队中统一这些格式规则可以消除无意义的代码风格争论。5.3 Git Hooks用Husky设置提交前检查// package.json { scripts: { lint: eslint . --ext .vue,.js,.jsx,.ts,.tsx --fix }, husky: { hooks: { pre-commit: npm run lint } } }这样可以在提交前自动修复可修复的问题。我在项目中引入这个机制后代码评审时间缩短了50%。6. 团队协作规范6.1 代码评审要点代码评审时要重点检查组件命名是否符合规范Props定义是否完整复杂逻辑是否有注释重复代码是否可提取性能是否有隐患建议使用GitHub的PR模板## 变更类型 - [ ] Bug修复 - [ ] 新功能 - [ ] 重构 ## 变更描述 ## 影响范围 ## 测试建议6.2 提交信息规范采用Conventional Commits规范feat: 添加用户管理页面 fix(login): 修复登录失效问题 chore: 更新依赖包可以使用commitizen工具交互式生成合规的提交信息npm install -g commitizen commitizen init cz-conventional-changelog --save-dev --save-exact7. 注释与文档7.1 代码注释原则好的注释应该解释为什么而不是做什么// 错误无用的注释 // 设置用户ID const userId 123 // 正确解释非常规做法 // 使用setTimeout避免批量更新导致的渲染卡顿 setTimeout(() { updateChart() }, 0)7.2 组件文档使用Vuese自动生成组件文档# Button 通用按钮组件 ## Props | 名称 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | String | default | 按钮类型 |或者在组件内使用JSDoc/** * 用户头像组件 * displayName UserAvatar */ export default { props: { /** * 用户ID */ userId: Number } }8. 性能优化实践8.1 组件优化技巧script setup // 用computed减少重复计算 const fullName computed(() ${firstName.value} ${lastName.value}) // 用watchEffect自动清理副作用 watchEffect((onCleanup) { const timer setTimeout(() { // ... }, 1000) onCleanup(() clearTimeout(timer)) }) // 大列表使用虚拟滚动 import { useVirtualList } from vueuse/core const { list, containerProps, wrapperProps } useVirtualList( allItems, { itemHeight: 32 } ) /script8.2 资源加载策略!-- 图片懒加载 -- img v-lazyimageUrl !-- 组件懒加载 -- script setup const Editor defineAsyncComponent(() import(./Editor.vue)) /script在电商项目中通过图片懒加载将首屏加载时间从4s降到了1.8s。9. 测试规范9.1 单元测试示例import { mount } from vue/test-utils import Counter from ./Counter.vue test(increments counter, async () { const wrapper mount(Counter) await wrapper.find(button).trigger(click) expect(wrapper.text()).toContain(Count: 1) })9.2 测试目录结构tests/ ├── unit/ │ ├── components/ │ │ └── Button.spec.js │ └── utils/ │ └── date.spec.js └── e2e/ └── login.spec.js10. 持续维护代码规范不是一成不变的。我们团队每季度会回顾规范根据新技术和团队变化进行调整。最近我们就新增了Composition API的使用指南和Pinia的规范。维护一个CHANGELOG.md记录规范变更## [1.2.0] - 2023-06-01 ### Added - Composition API风格指南 - Pinia store规范 ### Changed - 更新TypeScript规则记住规范是为了服务项目而不是束缚开发。当规范与实际情况冲突时应该优先考虑项目的可维护性。