【前端命名规范】+【团队协作/代码维护】:从【变量/函数/组件/文件命名逻辑】到【落地实操】,彻底搞懂前端命名的最佳写法,避开命名混乱、维护困难高频坑!

📑 文章目录
- 一、为什么要重视命名?
- 二、命名风格速查表(先记住再往下看)
- 三、变量命名
- [3.1 基本原则](#3.1 基本原则)
- [3.2 推荐写法](#3.2 推荐写法)
- [3.3 布尔变量:用 is / has / can 前缀](#3.3 布尔变量:用 is / has / can 前缀)
- [3.4 数组:用复数或 List 后缀](#3.4 数组:用复数或 List 后缀)
- [3.5 常量:全大写下划线](#3.5 常量:全大写下划线)
- [3.6 常见踩坑](#3.6 常见踩坑)
- 四、函数命名
- [4.1 基本原则](#4.1 基本原则)
- [4.2 常见动词约定](#4.2 常见动词约定)
- [4.3 推荐写法](#4.3 推荐写法)
- [4.4 事件处理函数](#4.4 事件处理函数)
- [4.5 返回布尔值的函数](#4.5 返回布尔值的函数)
- [五、Vue 组件命名](#五、Vue 组件命名)
- [5.1 单文件组件:PascalCase](#5.1 单文件组件:PascalCase)
- [5.2 组件名 = 文件名](#5.2 组件名 = 文件名)
- [5.3 多词组件名](#5.3 多词组件名)
- [5.4 基础组件 vs 业务组件](#5.4 基础组件 vs 业务组件)
- [5.5 使用组件时的写法](#5.5 使用组件时的写法)
- 六、文件与目录命名
- [6.1 文件命名风格](#6.1 文件命名风格)
- [6.2 常见目录结构](#6.2 常见目录结构)
- [6.3 composables:use 前缀](#6.3 composables:use 前缀)
- [6.4 常见踩坑](#6.4 常见踩坑)
- 七、综合示例:一个用户列表页
- 八、小结:一张表记全
- 九、落地建议
同学们好,我是 Eugene(尤金),一名多年中后台前端开发工程师。
(Eugene 发音 /juːˈdʒiːn/,大家怎么顺口怎么叫就好)
很多前端开发者都会遇到一个瓶颈:
代码能跑,但不够规范;功能能实现,但维护起来特别痛苦;
一个人写没问题,一到团队协作就各种混乱、踩坑、返工。
想写出干净、优雅、可维护的专业代码,
靠的不是天赋,而是体系化的规范 + 真实实战经验。
这一系列《前端规范实战》,我会用大白话 + 真实业务场景,
不讲玄学、不堆理论,只分享能直接落地的规范、标准与避坑指南。
帮你从「会写代码」真正升级为「会写优质、可维护、团队级别的代码」。
一、为什么要重视命名?
命名是代码里最频繁出现的「文档」。好的命名能让人一眼看懂用途,差的命名会让人反复猜测、浪费时间,甚至埋坑。
常见问题:
- 变量名
a、temp、data1看不出含义 - 函数名
doSomething、handle太泛,不知道具体做什么 - 组件名
MyComponent、Test难以区分业务含义 - 文件名
util.js、helper.js难以定位功能
本文围绕「变量 / 函数 / 组件 / 文件」四类命名,给出统一标准和实战用法,帮你形成可复用的命名习惯。
二、命名风格速查表(先记住再往下看)
| 类型 | 风格 | 示例 | 适用场景 |
|---|---|---|---|
| 普通变量、函数 | camelCase(小驼峰) | userName, getUserInfo |
JS 变量、函数、对象属性 |
| 常量 | UPPER_SNAKE_CASE(全大写下划线) | MAX_COUNT, API_BASE_URL |
不会变的配置、枚举值 |
| 类、构造函数、组件 | PascalCase(大驼峰) | UserService, UserCard.vue |
类、Vue 组件、类型 |
| 私有变量(约定) | 下划线前缀 | _privateData |
表示「内部用,别乱改」 |
| 布尔值 | is/has/can 前缀 | isLoading, hasPermission |
表示真假状态 |
三、变量命名
3.1 基本原则
- 用名词或「形容词 + 名词」
- 能表达「存的是什么」
- 避免无意义缩写
[⬆ 返回目录](#⬆ 返回目录)
3.2 推荐写法
js
// ✅ 好:一眼能看出存的是什么
const userName = '张三'
const orderList = []
const isLoading = false
const maxRetryCount = 3
// ❌ 差:含义模糊
const a = '张三' // 不知道 a 是什么
const temp = [] // 临时什么?
const flag = false // 什么标志?
const n = 3 // 数量?编号?
[⬆ 返回目录](#⬆ 返回目录)
3.3 布尔变量:用 is / has / can 前缀
js
// ✅ 好:读起来像自然语言
const isLoading = true
const hasPermission = false
const canEdit = true
const isVisible = false
// ❌ 差:需要猜含义
const loading = true // 还行,但不如 isLoading 清晰
const permission = false // 是「有权限」还是「权限对象」?
[⬆ 返回目录](#⬆ 返回目录)
3.4 数组:用复数或 List 后缀
js
// ✅ 好
const users = []
const orderList = []
const menuItems = []
// ❌ 差
const user = [] // 容易误以为是单个对象
const order = [] // 同上
[⬆ 返回目录](#⬆ 返回目录)
3.5 常量:全大写下划线
js
// ✅ 好:一眼看出是常量
const MAX_PAGE_SIZE = 20
const API_BASE_URL = 'https://api.example.com'
const DEFAULT_AVATAR = '/images/default-avatar.png'
// ❌ 差:看起来像普通变量
const maxPageSize = 20
const apiBaseUrl = 'https://api.example.com'
[⬆ 返回目录](#⬆ 返回目录)
3.6 常见踩坑
| 坑 | 说明 | 建议 |
|---|---|---|
| 过度缩写 | usr、usrNm、ordLst |
除非是约定俗成(如 id、url),否则写全 |
| 单字母变量 | i、j 在循环里可以,其他地方慎用 |
尽量用有含义的名字 |
| 拼音混英文 | yonghuList、dingdanData |
统一用英文,团队约定优先 |
[⬆ 返回目录](#⬆ 返回目录)
四、函数命名
4.1 基本原则
- 用动词或「动词 + 名词」
- 能表达「做什么」
- 事件处理函数可用
handle/on前缀
[⬆ 返回目录](#⬆ 返回目录)
4.2 常见动词约定
| 动词 | 含义 | 示例 |
|---|---|---|
| get | 获取数据(同步) | getUserById |
| fetch | 异步获取 | fetchOrderList |
| set | 设置 | setUserName |
| update | 更新 | updateOrderStatus |
| delete / remove | 删除 | deleteUser |
| create / add | 新增 | createOrder |
| check / validate | 校验 | validateForm |
| format | 格式化 | formatDate |
| parse | 解析 | parseJSON |
| handle / on | 事件处理 | handleSubmit |
[⬆ 返回目录](#⬆ 返回目录)
4.3 推荐写法
js
// ✅ 好:动词 + 名词,语义清晰
function getUserById(id) { /* ... */ }
function fetchOrderList(params) { /* ... */ }
function validateEmail(email) { /* ... */ }
function formatPrice(price) { /* ... */ }
// ❌ 差:太泛或太模糊
function doSomething() { /* ... */ } // 做什么?
function handle() { /* ... */ } // 处理什么?
function process(data) { /* ... */ } // 处理成什么样?
[⬆ 返回目录](#⬆ 返回目录)
4.4 事件处理函数
js
// ✅ 好:handle + 事件/动作
function handleSubmit() { /* 提交表单 */ }
function handleClick() { /* 点击 */ }
function handleInputChange(e) { /* 输入变化 */ }
// Vue 中常见写法
const handleUserDelete = (id) => { /* ... */ }
const onSearch = () => { /* ... */ }
[⬆ 返回目录](#⬆ 返回目录)
4.5 返回布尔值的函数
js
// ✅ 好:用 is/has/can 开头
function isValidEmail(str) { /* ... */ }
function hasPermission(user, action) { /* ... */ }
function canEdit(order) { /* ... */ }
// ❌ 差
function check(str) { /* ... */ } // 检查什么?返回什么?
[⬆ 返回目录](#⬆ 返回目录)
五、Vue 组件命名
5.1 单文件组件:PascalCase
Vue 官方推荐组件名用 PascalCase,文件名与组件名一致。
✅ 推荐
UserCard.vue
OrderList.vue
ProductDetail.vue
❌ 不推荐
userCard.vue // 小驼峰
user-card.vue // 和组件名不一致时容易乱
[⬆ 返回目录](#⬆ 返回目录)
5.2 组件名 = 文件名
html
<!-- UserCard.vue -->
<template>
<div class="user-card">
<!-- ... -->
</div>
</template>
<script setup>
// 组件名默认从文件名推导,保持 UserCard 即可
</script>
[⬆ 返回目录](#⬆ 返回目录)
5.3 多词组件名
避免与 HTML 标签冲突,也方便区分业务含义:
<!-- ✅ 好:多词、有业务含义 -->
UserProfileCard.vue
OrderStatusBadge.vue
ProductImageGallery.vue
<!-- ❌ 差:单词易冲突 -->
User.vue
Card.vue
Header.vue
[⬆ 返回目录](#⬆ 返回目录)
5.4 基础组件 vs 业务组件
components/
├── base/ # 基础组件,加 Base 前缀
│ ├── BaseButton.vue
│ ├── BaseInput.vue
│ └── BaseModal.vue
├── business/ # 业务组件
│ ├── UserCard.vue
│ ├── OrderList.vue
│ └── ProductDetail.vue
[⬆ 返回目录](#⬆ 返回目录)
5.5 使用组件时的写法
html
<template>
<!-- ✅ 推荐:PascalCase,和文件名一致 -->
<UserCard :user="user" />
<OrderList :orders="orders" />
<!-- 也可以写 kebab-case,Vue 会自动映射 -->
<user-card :user="user" />
</template>
[⬆ 返回目录](#⬆ 返回目录)
六、文件与目录命名
6.1 文件命名风格
| 类型 | 风格 | 示例 |
|---|---|---|
| Vue 组件 | PascalCase | UserCard.vue |
| JS/TS 工具、模块 | camelCase | formatDate.js |
| 样式文件 | 与组件同名 | UserCard.scss |
| 常量、配置 | camelCase 或 kebab-case | constants.js |
[⬆ 返回目录](#⬆ 返回目录)
6.2 常见目录结构
src/
├── components/ # 通用组件
│ ├── base/
│ └── business/
├── views/ # 页面级组件,PascalCase
│ ├── UserList.vue
│ ├── OrderDetail.vue
│ └── ProductManage.vue
├── composables/ # 组合式函数,use 前缀
│ ├── useUser.js
│ └── useOrder.js
├── utils/ # 工具函数
│ ├── format.js
│ └── validate.js
├── api/ # 接口封装
│ ├── user.js
│ └── order.js
├── constants/ # 常量
│ └── index.js
└── stores/ # 状态管理
└── user.js
[⬆ 返回目录](#⬆ 返回目录)
6.3 composables:use 前缀
js
// useUser.js
export function useUser() {
const user = ref(null)
const fetchUser = async () => { /* ... */ }
return { user, fetchUser }
}
// useOrder.js
export function useOrder() {
const orders = ref([])
const loadOrders = async () => { /* ... */ }
return { orders, loadOrders }
}
[⬆ 返回目录](#⬆ 返回目录)
6.4 常见踩坑
| 坑 | 说明 | 建议 |
|---|---|---|
| 组件名和文件名不一致 | UserCard.vue 里写 name: 'User' |
保持一致 |
| 单词组件名 | Card.vue、List.vue |
用多词,如 UserCard |
| 混用命名风格 | 有的 PascalCase,有的 kebab-case | 团队统一约定 |
[⬆ 返回目录](#⬆ 返回目录)
七、综合示例:一个用户列表页
把变量、函数、组件、文件命名串起来看:
html
<!-- views/UserList.vue -->
<template>
<div class="user-list-page">
<BaseSearch
v-model="searchKeyword"
placeholder="搜索用户名"
@search="handleSearch"
/>
<UserTable
v-if="!isLoading"
:users="userList"
@delete="handleUserDelete"
/>
<BaseLoading v-else />
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { fetchUserList, deleteUser } from '@/api/user'
import BaseSearch from '@/components/base/BaseSearch.vue'
import UserTable from '@/components/business/UserTable.vue'
import BaseLoading from '@/components/base/BaseLoading.vue'
// 变量:名词,布尔用 is 前缀,数组用 List
const searchKeyword = ref('')
const userList = ref([])
const isLoading = ref(false)
// 函数:动词 + 名词,事件用 handle 前缀
const loadUserList = async () => {
isLoading.value = true
try {
const res = await fetchUserList({ keyword: searchKeyword.value })
userList.value = res.data
} finally {
isLoading.value = false
}
}
const handleSearch = () => {
loadUserList()
}
const handleUserDelete = async (userId) => {
await deleteUser(userId)
loadUserList()
}
onMounted(loadUserList)
</script>
js
// api/user.js
const API_BASE_URL = 'https://api.example.com'
export async function fetchUserList(params) {
const res = await fetch(`${API_BASE_URL}/users?${new URLSearchParams(params)}`)
return res.json()
}
export async function deleteUser(id) {
const res = await fetch(`${API_BASE_URL}/users/${id}`, { method: 'DELETE' })
return res.json()
}
[⬆ 返回目录](#⬆ 返回目录)
八、小结:一张表记全
| 类型 | 风格 | 示例 |
|---|---|---|
| 变量 | camelCase | userName, orderList |
| 布尔变量 | is/has/can | isLoading, hasPermission |
| 常量 | UPPER_SNAKE_CASE | MAX_COUNT, API_BASE_URL |
| 函数 | 动词 + 名词 | getUserById, handleSubmit |
| 事件处理 | handle/on | handleClick, onSearch |
| 组件 | PascalCase,多词 | UserCard.vue, OrderList.vue |
| composables | use 前缀 | useUser.js, useOrder.js |
| 基础组件 | Base 前缀 | BaseButton.vue |
[⬆ 返回目录](#⬆ 返回目录)
九、落地建议
- 团队先定一份命名规范文档,贴在项目 README 或 Wiki。
- 用 ESLint 的
camelcase、vue/component-name-in-template-casing等规则做约束。 - Code Review 时重点看命名是否清晰、是否符合约定。
- 新项目从第一天就按规范来,比后期重构成本低很多。
命名规范不是死规矩,而是「可读性」和「一致性」的体现。先掌握这些约定,再结合团队习惯微调,就能写出更易维护的前端代码。
[⬆ 返回目录](#⬆ 返回目录)
技术成长,从来不是比谁写得快,而是比谁写得稳、规范、可维护。
哪怕每次只吃透一条规范,长期下来,差距会非常明显。
后续我会持续更新前端规范、工程化、可维护代码相关实战干货,
帮你告别面条代码、维护噩梦,在开发与面试中更有底气。
觉得有用欢迎 点赞 + 收藏 + 关注,不错过每一篇实战内容。
我是 Eugene,与你一起写规范、写优质代码,我们下篇干货见~