前端开发规范看这一篇就够了

591 阅读10分钟

🤔为什么需要代码规范

  • 提升代码可读性、降低维护成本
  • 促进团队协作效率,减少沟通成本
  • 避免常见报错(如全局变量污染、样式冲突、变量未定义等等)

基本规则:结构、表现、行为三者分离

尽量在文档和模板中只包含结构性的 HTML;而将所有表现代码,移入样式表中;将所有动作行为,移入js脚本之中。

建议:

不使用行内样式:<div color="#F0F0F0"> 或者 <div style="width:100%; margin: 0 auto;"></div>

不使用表象元素:<b>、<i>、<u>、<center>(加粗、倾斜、下划线等等)

表达式不要写在html中,移入js脚本

文件规范

文件命名规范

  • 图片命名:图片业务(可选)+ 图片模块名称(可选) + 图片类别bg\icon\img(必选)+ 图片精度(可选)home_bg@2x.png
  • 文件夹及文件名:小驼峰
  • 组件名:大驼峰.vue;标签内用-隔开,基础组件用Base开头

image.png

HTML规范

一系列建议和方法,帮助你搭建简洁严谨的结构,让页面HTML代码更具语义性。

1.1、语义化标签

标签需要语义化:切忌清一色的 <div> 元素。列表可以使用 <ul><li>,文本使用<p><span>标签等等。 HTML5 推出了语义化的标签,建议使用:<article><section><nav><header><footer><aside>,等 HTML5 布局标签。

1.2、元素属性值使用双引号语法,禁止使用单引号

1.3、自定义标签(自定义组件)

在不使用插槽的情况下,推荐使用自闭合标签的写法,如下

 推荐:<MyComponents /> 不推荐:<MyComponents></MyComponents> 

1.4、多特性分行写

为提高可读性,组件应用时换行并按照ref、class、属性、事件顺序书写,如下:

<template>
  <MyComponent
    ref="MyComponent"
    class="my-component"
    :data="componentData"
    @gatData="gatData"
  />

1.5、标签嵌套

元素的嵌套需要遵循一定的规则,例如:块级元素可以嵌套行内元素,行内元素不可嵌套块级元素;且嵌套标签的语义合理;每个块状元素独立一行

 推荐:
<div>
    <h1></h1>
    <p></p>
</div>
<p><span></span><span></span></p>
不推荐:
<div>
    <h1></h1><p></p>
</div>
<p>
    <span></span>
    <span></span>
</p>
案例1:

image.png

多余的父元素、语义不合理:将按钮放在一个<span>中并没有增加额外的意义。<span>仅仅是一个通用的行内容器;

1.6、 除非有特定的功能、组件要求等,禁止随意使用id来定义元素样式(重要)

1.7、使用表达式

在html模板中,大于1的条件判断、或复杂表达式,强烈建议使用计算属性或者函数,如下

不推荐
<el-button v-if="power.delete && userInfo.department === '新技术应用组' && (state === '1' || type === '2')">删除</el-button>
推荐
<el-button v-if="showDeleteBtn"></el-button>
const showDeleteBtn = computed(()=>{
    if(!power.delete) return
    if(userInfo.department != '新技术应用组') return
    return state === '1' || type === '2'
})

1.8、组件for循环需要加key属性

  1. 在列表数据发生变化时,通过key唯一值,来识别哪些元素是没有发生变化的,哪些元素是要改变,哪些元素是要排序的,可以更高效的更新dom;在组件高度复用时,key属性作为组件的唯一值可以避免渲染错误
  2. 唯一值,禁止使用index作为key的值,数据源发生变化时vue无法准确追踪每个元素,删减列表元素时,导致性能问题,后续元素会重新渲染。
  3. 建议:用数据源的唯一id作为循环组件的key

1.9、v-for不与v-if在同一元素上使用

  • v-forv-if 优先级高,同时用在同一个元素上,有性能问题(vue2),在vue3中 v-ifv-for 优先级高,解决了这个问题,但仍然不推荐在同一个元素上同时使用这两个指令,因为这样做可能会使代码难以理解和维护。
  • 解决方案:使用计算属性 computed 过滤掉不显示的项

1.10、代码缩进(团队约定)

统一使用四个空格进行代码缩进,使得各编辑器表现一致(各编辑器有相关配置)indentation

image.png

案例:

image.png

问题点:1、classid表达式过长; 2、事件、属性顺序不对;3、多余父标签;4、嵌套不对行内元素嵌套块级元素??; 5、 if判断; 6、行内样式

image.png


CSS规范

一系列规则和方法,帮助你架构并管理好样式

2.1 命名规范(重要)

推荐:<div class="page-content"></div>
不推荐:<div class="pageContent"></div> <div class="PageContent"></div>

2.2 合理使用ID(重要)

一般情况下id不应该被用于样式,并且id的权重很高,所以不使id解决样式的问题,而是使用class

2.3 css选择器中避免使用标签名

避免使用标签选择器。效率低,损耗性能,会出现潜在问题,建议使用class;

2.4 尽量使用缩写属性、0后面不带单位(重要)

不推荐
padding-bottom: 2px;
padding-left: 1px;
padding-right: 3px;
padding-top: 0;
推荐
padding0 3px 2px 1px;

2.5 样式嵌套(重要)

预处理器允许你使用嵌套规则,但这并不意味着你应该滥用它们。适当地使用嵌套规则(通常限制在2-3层)

2.6 使用 scoped 关键字,约束样式生效的范围,避免样式污染(重要)

  1. 提取公用样式进assets文件styles里,按模块/功能区分;
  2. 封装组件
<style lang="scss">
.home-table{
    background:red;
}
</style>
<style lang="scss" scoped>
.page-content{
    //定义当前页面样式
    background:red;
}
</style>

2.7 为单个css选择器或新申明开启新行

推荐:
.jdc,
.jdc-logo,
.jdc-hd {
    color: #ff0; 
 }
.nav{
    color: #fff;
 } 

不推荐:
.jdc,.jdc-logo,.jdc-hd {
    color: #ff0;
}.nav{
    color: #fff;
}

image.png

2.8 属性书写顺序应遵循以下顺序

  1. 布局定位属性:display / position / float / clear / visibility / overflow
  2. 自身属性:width / height / margin / padding / border / background
  3. 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
  4. 其他属性(CSS3):content / cursor / border-radius / box-shadow / text-shadow / background:linear-gradient …

JS规范

统一团队的 JS 语法风格和书写习惯,减少程序出错的概率

3.1 命名规范(重要)

  • 变量/函数:小驼峰式(camelCase),如 firstNamecalculateTotal()
  • 类/构造函数:大驼峰式(PascalCase),如 class UserAccount {}
  • 常量:全大写 + 下划线,如 MAX_COUNT = 100
  • 布尔值(Boolean)命名
  1. 场景一:表示元素是否可见性、是否进行某种状态,是否有。。等等;推荐命名方式为 is + 动词(现在进行时)/形容词 如 :isShow: '是否显示', isVisible: '是否可见', isLoading: '是否处于加载中', isConnecting: '是否处于连接中', isValidating: '正在验证中', isRunning: '正在运行中', hasPermission:是否有权限
  2. 场景二:通常用来描述实体(例如:HTML标签、组件、对象)的功能属性,而且定法比较固定;如: disabled: '是否禁用',editable: '是否可编辑',clearable: '是否可清除',expandable: '是否可展开',checked: '是否选中',
  3. 场景三:临时的变量:推荐命名为:flag
  • 函数:原生事件:on开头;约定俗成的命名:onSubmit: '提交表单'、onReset:重置、onClose:关掉弹窗、onCancel取消;具有对数据操作或修改类的:get、set开头或者get/by:getNameById;跳转函数:go开头;打开弹窗、抽屉:open开头
  1. 常用词
简写说明
get\set取值\给值
add\remove增加\移除
show\hide显示\隐藏
view查看
browse浏览
edit修改
save保存
delete删除
find查询
undo撤销
redo重做
clean清除
index索引
observe观察
send\receive发送\接收
refresh\synchronize刷新\同步
  1. 常用缩写
数据类型/标签简写后缀
objectobj
arrayarr
jsonjson
functionfn
messagemsg
buttonbtn

3.3. 变量与声明

使用 const 和 let,避免 var(防止变量提升和全局污染)。

3.4 字符串

字符串优先使用单引号

const message = 'Hello';

3.5 对象与数组

  • 对象简写:属性尽量简写。

    const name = 'John';
    const user = { name }; // 而非 { name: name }
    
  • 数组方法:优先使用 mapfilterreduce 等函数式方法,而非 for 循环。

3.6 条件与循环

  • 使用 === 和 !==,避免 == 和 !=(严格类型检查)。

  • 优先使用 for...of 或数组方法代替传统 for 循环。

for (const item of list) { /* ... */ }
list.forEach(item => {/* ... */})
  • 循环的元素命名强烈建议用item或者与意思相近的,禁用无意义的a,b,c,j,i
  • 循环体内嵌套子循环,元素命名不能相同!!!

3.7 注释

  • 单行注释用 //,多行用 /* ... */
  • 函数注释使用 JSDoc 风格:
    /**
     * 计算两数之和
     * @param {number} a - 第一个数
     * @param {number} b - 第二个数
     * @returns {number} 返回和
     */
    function sum(a, b) { return a + b; }
    

3.8 容错-避免null导致的报错

let dataList = res.data || []
let name = obj?.name

3.9 条件判断真前假后

不推荐
if(!flag){

}else{ }
推荐
if(flag){

}else{  }

vue规范

4.1 使用composition api来编码(重要)

它提供了一种新的方式来组织组件的逻辑,

  • vue3就用组合式composition api的思想来组织代码,按功能块写,抛弃vue2选项式拆分data、methods、computed 、钩子函数分开写的思想;
  • 避免将响应式变量ref声明全部写在一个地方,要按功能分开写
  • composition api是灵活多变的,核心在于通过函数 将逻辑组合在一起,增强代码的可维护性、可扩展性和复用性
不推荐
const count = ref(0);
const list = reactive([1,2,3,4])
const add = () => { count.value++; };
const add2 = ()=>{
    list.forEach(item => ++item)
}
推荐
//功能1
const count = ref(0);
const add = () => { count.value++; };
//功能2
const list = reactive([1,2,3,4])
const add2 = ()=>{
    list.forEach(item => ++item)
}

4.2 在 Vue3 的 <script setup> 语法糖中,虽然没有强制规定的顺序,但遵循一致的代码组织规范可以极大提升代码可读性和维护性。以下是推荐顺序和规范建议:

<script setup>
// 1. 导入---组件、js文件
import { ref, computed, onMounted } from 'vue'
import { useUserApi } from '@/composables/useUserApi'

// 2.Props & Emits 定义(注意规范命名)
const props = defineProps({ initialId: Number })
const emit = defineEmits(['selectTable'])

// 3. 响应式数据
const searchQuery = ref('')

// 4. 计算属性
const filteredList = computed(() => {
  return allList.value.filter(item => item.includes(searchQuery.value))
})

// 5. 监听
watch(userId, (newId) => {
  localStorage.setItem('lastUserId', newId)
})

// 6. 方法
async function fetchData() {
  // ...
}

// 7. 生命周期
onMounted(()=>{})

// 8. 对外暴露
defineExpose({ searchQuery })

</script>

4.2 组件间通讯

通讯方式api
父传子props/defineProps
祖传子provide/inject
子传父@/defineEmits
父子双向绑定v-model/defineModel(vue3.4以下版本用modelValue方式)
父组件访问子组件ref/defineExpose
兄弟组件pinia 或者 浏览器缓存

推荐使用

eslint:是一个JavaScript代码检测工具,侧重于语法和部分格式问题

prettier: 是一个代码格式化器,专注于代码美化和风格统一。两者结合使用,可以确保代码既正确又美观

当配置冲突时,通常以prettier为准。

git规范

现状及意义

代码提交说明现状:首页修改、页面修改、提交部分代码、优化提交等等;

在开发过程中,Git每次提交代码,都需要写Commit message(提交说明),而规范的提说明交可以带来以下核心优势:

  • 语义化信息: 快速理解提交目的,减少沟通成本。明确表示功能内容;
  • 统一格式:团队遵循相同规则,降低阅读和理解他人提交的认知负担:
  • 问题定位: 快速定位Bug修复或修改、新增、优化的提交记录。
  • 提交分类筛选: 审查时可聚焦关键提交(如 feat: 和 fix:),忽略 chore: 或 style: 等次要改动。
  • 版本回滚更高效:清晰的提交历史帮助快速定位稳定版本或问题版本。
  • 新人友好:规范提交记录相当于项目演进文档,降低新人理解代码历史的难度。

Commit messages的基本语法

三个字段组成:type(必须):提交类型、scope(可选):提交影响范围、subject(必须):提交描述

type说明提交类型:只允许使用下面属性(前几个常用)

属性描述
feat新增功能
fix修复bug
style仅修改了代码格式、不改变代码逻辑
refactor代码重构,没有新增或修复bug
chore改变构建流程、或者增加依赖库、工具等
docs仅仅修改了文档
perf增加代码进行性能测试
test增加测试用例

eg:feat: 地区、顺心首页新增附件查询功能fix: 页签栏刷新后页签丢失问题