前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键

一、如何保证代码的质量

  • 使用代码风格检查工具:使用诸如 ESLint 等代码风格检查工具,可以规范代码的书写风格,提高代码的一致性和可读性。

  • 使用类型和错误检查工具:使用诸如 TypeScript、Flow 等类型检查工具和 ESLint 等错误检查工具,可以避免编码时出现类型和语法错误,用来提高代码质量和可维护性。

  • 进行代码复审和 code review:通过与团队成员进行代码复审和 code review,可以发现代码中存在的问题,提高代码的可读性和扩展性。

  • 单元测试和集成测试:通过编写单元测试和集成测试,可以检查代码是否符合预期的行为。单元测试和集成测试是保证代码质量和程序正确性的重要手段。

  • 模块化:将系统拆分成多个小模块或组件,每个模块都专注于实现特定的功能。这样可以提高代码的可重用性和可维护性,更便于后期的维护和扩展。

  • 提高代码的可读性:通过提高代码的可读性,让代码更加易于理解和维护。比如使用有意义的命名、注释、缩进、代码结构等方面加强代码质量。

二、编码规范

1、HTML/Template 编码规范
(1)缩进使用两个空格代替Tab

前端代码层级较深,使用短缩进有利于利用屏幕空间,提升效率,使用两个空格代替Tab可以保证在所有环境下获得一致展现。

<!-- not good -->
<div>
  <div>bar</div>
</div>

<!- good -->
<div>
  <div>bar</div>
</div>
(2)嵌套元素应当缩进一次(即两个空格),同层级缩进应保持一致
<!- not good -->
<div>
<div>bar</div>
  <div>bar</div>
</div>

<!- good-->
<div>
  <div>bar</div>
  <div>bar</div>
</div>
(3)对于属性的定义,使用双引号,不要使用单引号
<!- not good -->
<input class='a' type=text>
  
<!- good-->
<input class="a" type="text">
(4)不要省略可选的结束标签(closing tag) (如或)

省略可选的结束标签,虽不会违反H5规范,但可能会造成层级上的困扰,导致代码出现无法预料的问题。

<!-- not good -->
<h1>h1 text
  <h2>h2 text
    
<!-- good -->
<h1>h1 text</h1>
<h2>h2 text</h2>
(5)td / th 要在 tr ⾥⾯,li 要在 ul / ol ⾥⾯
<!-- not good -->
<table>
  <td>test</td>
</table>

<!-- good -->
<table>
  <tr>
    <td>test</td>
  </tr>
</table>
(6)ul / ol 的直接⼦元素只能是 li,不能包含其他元素
<!-- not good -->
<ul>
  <span>123</span>
  <li>a</li>
  <li>b</li>
</ul>

<!-- good -->
<ul>
  <li><span>123</span></li>
  <li>a</li>
  <li>b</li>
</ul>
(7)⾏内元素⾥⾯不可使⽤块级元素

a 标签是⼀个⾏内元素,⾏内元素⾥⾯套了⼀个 div 的标签,这样可能会导致 a 标签⽆法正常点击

<!-- not good -->
<a href="../test">
  <div></div>
</a>

<!-- good -->
<a href="../test" style="display: block">
  <div></div>
</a>
(8)不要在https的链接⾥写http的图⽚

只要https的⽹页请求了⼀张http的图⽚,就会导致浏览器地址栏左边的⼩锁没有了,⼀般不要写死,写成根据当前域名的协议去开头:

<img src="//static.chimeroi.com/hello-world.jpg">
(9)不要在⾃闭合(self-closing)元素的尾部添加斜线( HTML5 规范中说明这是可选的)
<!-- not good -->
<img src="logo.png" alt />

<!-- good -->
<img src="logo.png" alt>
(10)不使⽤属性设置样式(img, table等元素)
<!-- not good -->
<img src="test.jpg" alt width="400" height="300">

<!-- good -->
<img src="test.jpg" style="width:400px;height:300px;">
(11)⾃定义属性要以data-开头 ⾃⼰添加的⾮标准的属性要以data-开头

否则w3c validator会认为是不规范的

<!-- not good -->
<div count="5"></div>

<!-- good -->
<div data-count="5"></div>
2、CSS / Less 编码规范
(1)命名:
  • 【强制】类名使⽤⼩写字母,以中划线分隔

  • 【强制】id 采⽤驼峰式命名

  • 【强制】less 中的变量、函数、混合等采⽤驼峰式命名

@mainFontColor: #444;
#companyName,
.company-name {
  color: @mainFontColor;
}
(2)语法:
  • 【强制】所有声明语句都应当以分号结尾
/* error */
.selector {
  font-size: 15px
  color: red
}

/* good */
.selector {
  font-size: 15px;
  color: red;
}
  • 【强制】⼗六进制值应该全部⼩写,例如:#f3f6fa

  • 【推荐】不要使⽤*选择器

  • 【推荐】适当使⽤:before和:after来画页⾯的⼀些视觉上的辅助性元素
    如三⾓形、短的分隔线、短竖线等,可以减少页⾯上没有⽤的标签

  • 【推荐】选择器不要超过4层(在 Less 中避免嵌套超过 4 层)

  • 【推荐】⽤ border: 0; 代替 border: none;

  • 【推荐】使⽤全写形式的⼗六进制值。
    例如,⽤#ffffff代替#fff,这样颜色能保持统一格式。

  • 【推荐】对于属性值或颜⾊参数,省略⼩于 1 的⼩数前⾯的 0
    例如,.5 代替 0.5;-.5px 代替-0.5px

(3)样式兼容性
  • 【强制】当使⽤⼀些较新的 CSS3 语法时,应注意添加浏览器前缀
    ( 打包⼯具包含 CSS 预处理,一般⽆需考虑此条)

  • 【推荐】不要使⽤ input 的 line-height来做垂直居中
    设置 line-height 为⼀个很⾼的值会导致 Safari 浏览器的输⼊光标变得巨⼤ (与line-height等⾼)

/* not good */
input {
  height: 40px;
  line-height: 40px;
}

/* good */
input {
  height: 20px;
  line-height: 20px;
  padding: 10px 0;
}
  • 【强制】⾮通⽤样式使⽤嵌套⽅式进⾏编写,避免影响其他⾃⼰不了解样式,造成样式覆盖

  • 【强制】减少使⽤!important,除⾮原样式使⽤内联样式或!important,且⽆法直接修改才考虑使用

(4)CSS动画
  • 【推荐】不要使⽤all属性做动画

使⽤transition做动画的时候不要使⽤all所有属性,在有⼀些浏览器上⾯可能会有⼀些问题,如下:

transition: all 2s linear; 在Safari上⾯可能会有⼀些奇怪的抖动。

正确的做法是要⽤哪个属性做动画就写哪个,如果有多个就⽤逗号隔开,如下代码所⽰:

transition: transform 2s linear, opacity 2s linear;

  • 【推荐】位移动画使⽤ transform 替代 position (提升动画性能)

  • 【推荐】使⽤ CSS 动画替代 JS 动画

(5)声明顺序

【参考】相关的属性声明按以下顺序做分组处理,组之间需要有⼀个空⾏

  • Positioning(影响其他元素和⾃⾝位置相关声明

  • Box model(⾃⾝盒模型相关声明)

  • Typographic(⽂本相关声明)

  • Visual(⾃⾝样式)

  • Misc(其他声明)

例子:

.declaration-order {
  /* Positioning */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: block;
  float: right;
  width: 100px;
  height: 100px;

  /* Typography */
  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visual */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Misc */
  opacity: 1;
}
3、JavaScript 编码规范
(1)命名:
  • 【强制】标准变量采⽤驼峰式命名(考虑与后台交换数据的情况,对象属性可灵活命名)

  • 【强制】常量全⼤写,⽤下划线连接

  • 【强制】变量名不应过短,要能准确完整地描述该变量所表述的事物,但也不能过长,不利于阅读,最长不能超过5个单词。

不好的变量名好的变量名
inpinput, priceInput
day1, day2, param1today, tomorrow
iduserId, orderId
objorderData, houseInfos
tIdremoveMsgTimerId
handlersubmitHandler, searchHandler
  • 【强制】变量名不要使⽤计算机术语,如 texareaData,应该取和业务相关的名字,如 leaveMsg

  • 【强制】变量名使⽤正确的语法

  • 【推荐】不要使⽤否定的名词,如 notOk、notReady,因为否定的词取反的时候就会⽐较奇怪,如 if (!notOk)

(2)语法:
  • 【强制】变量不要先使⽤后声明

  • 【强制】不要声明了变量却不使⽤

  • 【强制】不要在同个作⽤域下声明同名变量

  • 【强制】⼀个函数作⽤域中所有的变量声明尽量提到函数⾸部,可根据代码进⾏分组,但不允许出现两个连续的变量声明

// not good
let registerForm = null;
let question = "";
let calculateResult = 0;

// good
let registerForm = null,
    question = "",
    calculateResult = 0;
  • 【强制】单⼀函数的返回值类型要确定
    如下⽆法确定该函数的最终返回类型
// not good
function calculatePrice(seatCount){
  if (seatCount <= 0) {
     return "";
  } else {
     return seatCount * 79;
  }
}
  • 【强制】debugger不要出现在提交的代码⾥

  • 【推荐】使⽤箭头函数取代简单的函数

// not good
let _this = this;
setTimeout(function() {
  _this.foo = "bar";
}, 2000);

// good
setTimeout(() => this.foo = "bar", 2000);
  • 【推荐】在必要的地⽅添加⾮空判断以提⾼代码的稳健性

  • 【推荐】将复杂的函数分解成多个⼦函数,⽅便维护和复⽤

(3)⽂档注释

【参考】各类标签建议在以下情况下使⽤:

  • 所有常量

  • 所有函数

  • 所有类

/**
 * @func
 * @desc ⼀个带参数的函数
 * @param {string} a - 参数a
 * @param {number} b=1 - 参数b默认值为1
 * @param {string} c=1 - 参数c有两种⽀持的取值</br>1—表⽰x</br>2—表⽰xx
 * @param {object} d - 参数d为⼀个对象
 * @param {string} d.e - 参数d的e属性
 * @param {string} d.f - 参数d的f属性
 * @param {object[]} g - 参数g为⼀个对象数组
 * @param {string} g.h - 参数g数组中⼀项的h属性
 * @param {string} g.i - 参数g数组中⼀项的i属性
 * @param {string} [j] - 参数j是⼀个可选参数
 */
function foo(a, b, c, d, g, j) {
  // ...
}
4、Vue 组件编码规范
(1)命名:
  • 【强制】组件名应该始终是多个单词的,根组件App除外,但最多不超过5个单词

  • 【强制】单⽂件组件的⽂件名应该始终是单词⼤写开头( PascalCase )

// not good
components/
|- mycomponent.vue

components/
|- myComponent.vue

// good
components/
|- MyComponent.vue
  • 【推荐】应⽤特定样式或者约定的基础组件应该全部以⼀个特定的前缀开头,⽐如 Base、App或 V
// not good
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue

// good
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue

components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue

components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
  • 【推荐】只应该拥有单个活跃实例的单例组件应该以 The 前缀命名,以⽰其唯⼀性
    单例组件不意味着组件只可⽤于⼀个单页⾯,⽽是每个页⾯只使⽤⼀次。这些组件永远不接受任何 prop,因为它们是为你的应⽤定制的,⽽不是它们在你的应⽤中的上下⽂。如果你发现有必要添加 prop,那就表明这实际上是⼀个可复⽤的组件,只是⽬前在每个页⾯⾥只使⽤⼀次。
// not good
components/
|- Heading.vue
|- MySidebar.vue

// good
components/
|- TheHeading.vue
|- TheSidebar.vue
  • 【推荐】和⽗组件紧密耦合的⼦组件应该以⽗组件名作为前缀命名
    如果⼀个组件只在某个⽗组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织⽂件,所以这样做可以把相关联的⽂件排在⼀起。
// not good
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue

//good
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
  • 【推荐】组件名应该以⾼级别的 (通常是⼀般化描述的) 单词开头,以描述性的修饰词结尾
// not good
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue

// good
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
  • 【推荐】组件名应该倾向于完整单词⽽不是缩写
// not good
components/
|- SdSettings.vue
|- UProfOpts.vue

// good
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
(2)语法:
  • 【强制】prop 的定义应该尽量详细,⾄少需要指定其类型
// not good
// 这样做只有开发原型系统时可以接受
props: ['status']

// good
props: {
  status: String
}

// better
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}
  • 【强制】Prop 名⼤⼩写,在声明和使用 prop 的时候,其命名应该始终使⽤ camelCase。
// not good
props: {
  'greeting-text': String
}
<WelcomeMessage greeting-text="hi"/>
  
// good
props: {
  greetingText: String
}
<WelcomeMessage greetingText="hi"/>
  • 【推荐】⾃闭合组件在单⽂件组件、字符串模板和 JSX 中没有内容的组件应该是⾃闭合的;但在 DOM 模板⾥尽量不要这样做。
<!-- not good -->
<!-- 在单⽂件组件、字符串模板和 JSX 中 -->
<MyComponent></MyComponent>
<!-- 在 DOM template模板中 -->
<my-component/>
  
<!-- good -->
<!-- 在单⽂件组件、字符串模板和 JSX 中 -->
<MyComponent/>
<!-- 在 DOM template模板中 -->
<MyComponent></MyComponent>
  • 【强制】模版中的组件名⼤⼩写在单⽂件组件和字符串模板中组件以及DOM 模板中名应该总是PascalCase 的,保持统一,方便搜索定位。
<!-- not good -->
<!-- 在单⽂件组件和字符串模板中 -->
<mycomponent/>
<!-- 在单⽂件组件和字符串模板中 -->
<myComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>
  
<!-- good -->
<!-- 在单⽂件组件和字符串模板中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<MyComponent></MyComponent>
  • 【推荐】多个特性的元素应该分多⾏撰写,每个特性⼀⾏(此项 Volar 插件会⾃动根据⾏宽阈值进⾏⾃动折⾏处理,⼀般⽆需考虑)
<!-- not good -->
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
<MyComponent foo="a" bar="b" baz="c"/>
  
<!-- good -->
<img
  src="https://vuejs.org/images/logo.png"
  alt="Vue Logo"
>
<MyComponent
  foo="a"
  bar="b"
  baz="c"
/>
  • 【强制】组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或⽅法
// not good
{{
  fullName.split(' ').map(function (word) {
    return word[0].toUpperCase() + word.slice(1)
  }).join(' ')
}}

// good
// 在模板中
{{ normalizedFullName }}
// 复杂表达式已经移⼊⼀个计算属性
computed: {
  normalizedFullName: function () {
    return this.fullName.split(' ').map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(' ')
  }
}
  • 【推荐】应该把复杂计算属性分割为尽可能多的更简单的属性
// not good
computed: {
  finalPrice: function () {
    var basePrice = this.manufactureCost / (1 - this.profitMargin)
    return (
      basePrice -
      basePrice * (this.discountPercent || 0)
    )
  }
}

// good
computed: {
  basePrice: function () {
    return this.manufactureCost / (1 - this.profitMargin)
  },
  discount: function () {
    return this.basePrice * (this.discountPercent || 0)
  },
  finalPrice: function () {
    return this.basePrice - this.discount
  }
}
  • 【强制】⾮空 HTML 特性值应该始终带引号
<!-- not good -->
<input type=text>
<AppSidebar :style={width:sidebarWidth+'px'}>
  
<!-- good -->
<input type="text">
<AppSidebar :style="{ width: sidebarWidth + 'px' }">
  • 【强制】单⽂件组件应该总是按照 、
<!-- good -->
<!-- ComponentA.vue -->
<template>...</template>
<style>/* ... */</style>

<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
5、代码风格

此处⼤部分⼯作将由代码格式化⼯具完成(参见运行环境约定),⼀般⽆需关心,仅作为了解和配置格式化工具参考。

(1)CSS
  • 【强制】缩进使⽤两个空格代替 Tab

  • 【强制】为选择器分组时,将单独的选择器单独放在⼀⾏

/* not good */
.selector, .selector-secondary, .selector[type=text] {
  /* ... */
}

/* good */
.selector,
.selector-secondary,
.selector[type="text"] {
  /* ... */ 
}
  • 【强制】声明块的左花括号前添加⼀个空格

  • 【强制】声明块的右花括号应当单独成⾏

  • 【强制】每条声明语句的 : 后应该插⼊⼀个空格

  • 【强制】每条样式声明应该独占⼀⾏

/* not good */
.selector {
  font-size: 15px; color: red;
}

/* good */
.selector {
  font-size: 15px;
  color: red;
}
  • 【强制】对于以逗号分隔的属性值,每个逗号后⾯都应该插⼊⼀个空格(例如,box-shadow,transition)
/* not good */
.selector {
  transition: border .2s,color .3s,padding .4s;
}

/* good */
.selector {
  transition: border .2s, color .3s, padding .4s;
}
  • 【强制】!important 前插⼊⼀个空格

  • 【强制】注释:// 后插⼊⼀个空格,/* 后插⼊⼀个空格,*/ 前插⼊⼀个空格

(2)Javascript
  • 【强制】缩进使⽤两个空格代替 Tab

  • 【强制】统⼀使⽤双引号""(与 Prettier 默认格式化配置持⼀致)

  • 【强制】对象属性名不需要加引号

  • 【强制】对象以缩进的形式书写,不要写在⼀⾏

  • 【强制】数组中不要存在空元素

  • 【强制】不要⽤for in循环数组

  • 【推荐】数组、对象最后要有逗号,为了Git多人修改时查看记录

// not good
let a = {
  'b': 1
};
let a = { b: 1 };
let a = {
  b: 1,
  c: 2
};

// good
let a = {
  b: 1,
  c: 2,
};
  • 47
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邹荣乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值