🤔为什么需要代码规范❓
- 提升代码可读性、降低维护成本
- 促进团队协作效率,减少沟通成本
- 避免常见报错(如全局变量污染、样式冲突、变量未定义等等)
基本规则:结构、表现、行为三者分离
尽量在文档和模板中只包含结构性的 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开头
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:
多余的父元素、语义不合理:将按钮放在一个
<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属性
- 在列表数据发生变化时,通过
key
唯一值,来识别哪些元素是没有发生变化的,哪些元素是要改变,哪些元素是要排序的,可以更高效的更新dom
;在组件高度复用时,key
属性作为组件的唯一值可以避免渲染错误 - 唯一值,禁止使用
index
作为key
的值,数据源发生变化时vue无法准确追踪每个元素,删减列表元素时,导致性能问题,后续元素会重新渲染。 - 建议:用数据源的唯一
id
作为循环组件的key
值
1.9、v-for不与v-if在同一元素上使用
v-for
比v-if
优先级高,同时用在同一个元素上,有性能问题(vue2),在vue3中v-if
比v-for
优先级高,解决了这个问题,但仍然不推荐在同一个元素上同时使用这两个指令,因为这样做可能会使代码难以理解和维护。- 解决方案:使用计算属性
computed
过滤掉不显示的项
1.10、代码缩进(团队约定)
统一使用四个空格进行代码缩进,使得各编辑器表现一致(各编辑器有相关配置)indentation
案例:
问题点:1、
class
、id
表达式过长; 2、事件、属性顺序不对;3、多余父标签;4、嵌套不对行内元素嵌套块级元素??; 5、if
判断; 6、行内样式
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;
推荐
padding:0 3px 2px 1px;
2.5 样式嵌套(重要)
预处理器允许你使用嵌套规则,但这并不意味着你应该滥用它们。适当地使用嵌套规则(通常限制在2-3层)
2.6 使用 scoped 关键字,约束样式生效的范围,避免样式污染(重要)
- 提取公用样式进assets文件styles里,按模块/功能区分;
- 封装组件
<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;
}
2.8 属性书写顺序应遵循以下顺序
- 布局定位属性:display / position / float / clear / visibility / overflow
- 自身属性:width / height / margin / padding / border / background
- 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
- 其他属性(CSS3):content / cursor / border-radius / box-shadow / text-shadow / background:linear-gradient …
JS规范
统一团队的 JS 语法风格和书写习惯,减少程序出错的概率
3.1 命名规范(重要)
- 变量/函数:小驼峰式(camelCase),如
firstName
,calculateTotal()
。 - 类/构造函数:大驼峰式(PascalCase),如
class UserAccount {}
。 - 常量:全大写 + 下划线,如
MAX_COUNT = 100
。 - 布尔值(Boolean)命名:
- 场景一:表示元素是否可见性、是否进行某种状态,是否有。。等等;推荐命名方式为
is + 动词(现在进行时)/形容词
如 :isShow: '是否显示', isVisible: '是否可见', isLoading: '是否处于加载中', isConnecting: '是否处于连接中', isValidating: '正在验证中', isRunning: '正在运行中', hasPermission:是否有权限
。 - 场景二:通常用来描述实体(例如:HTML标签、组件、对象)的功能属性,而且定法比较固定;如:
disabled: '是否禁用',editable: '是否可编辑',clearable: '是否可清除',expandable: '是否可展开',checked: '是否选中',
- 场景三:临时的变量:推荐命名为:
flag
- 函数:原生事件:
on开头
;约定俗成的命名:onSubmit: '提交表单'、onReset:重置、onClose:关掉弹窗、onCancel取消
;具有对数据操作或修改类的:get、set开头
或者get/by:getNameById
;跳转函数:go开头
;打开弹窗、抽屉:open开头
;
- 常用词
简写 | 说明 |
---|---|
get\set | 取值\给值 |
add\remove | 增加\移除 |
show\hide | 显示\隐藏 |
view | 查看 |
browse | 浏览 |
edit | 修改 |
save | 保存 |
delete | 删除 |
find | 查询 |
undo | 撤销 |
redo | 重做 |
clean | 清除 |
index | 索引 |
observe | 观察 |
send\receive | 发送\接收 |
refresh\synchronize | 刷新\同步 |
- 常用缩写
数据类型/标签 | 简写后缀 |
---|---|
object | obj |
array | arr |
json | json |
function | fn |
message | msg |
button | btn |
3.3. 变量与声明
使用 const
和 let
,避免 var
(防止变量提升和全局污染)。
3.4 字符串
字符串优先使用单引号
const message = 'Hello';
3.5 对象与数组
-
对象简写:属性尽量简写。
const name = 'John'; const user = { name }; // 而非 { name: name }
-
数组方法:优先使用
map
,filter
,reduce
等函数式方法,而非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: 页签栏刷新后页签丢失问题