前端代码规范 (综合主流规范书写)

原创 luotingv1 随笔 笔记 302阅读 2019-01-03 14:31:17 举报

HTML

语法

  • 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法。
  • 嵌套元素应当缩进一次(即两个空格)。
  • 对于属性的定义,确保全部使用双引号,绝不要使用单引号。
  • 不要在自闭合(self-closing)元素的尾部添加斜线 -- HTML5 规范中明确说明这是可选的。
  • 不要省略可选的结束标签(closing tag)(例如,</li> 或 </body>)。

属性顺序
HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性。

  • class
  • id, name
  • data-*
  • src, for, type, href, value
  • title, alt
  • role, aria-*

class 用于标识高度可复用组件,因此应该排在首位。id 用于标识具体组件,应当谨慎使用(例如,页面内的书签),因此排在第二位。

布尔(boolean)型属性
布尔型属性可以在声明时不赋值。XHTML 规范要求为其赋值,但是 HTML5 规范不需要。

元素的布尔型属性如果有值,就是 true,如果没有值,就是 false。

如果一定要为其赋值的话,请参考 WhatWG 规范:

如果属性存在,其值必须是空字符串或 [...] 属性的规范名称,并且不要在首尾添加空白符。

简单来说,就是不用赋值。

减少标签的数量
编写 HTML 代码时,尽量避免多余的父元素。很多时候,这需要迭代和重构来实现。请看下面的案例

JavaScript 生成的标签
通过 JavaScript 生成的标签让内容变得不易查找、编辑,并且降低性能。能避免时尽量避免。

CSS

语法

  • 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法。(ps 建议编辑器设置tab制表符未2个空格)
  • 为选择器分组时,将单独的选择器单独放在一行。
  • 为了代码的易读性,在每个声明块的左花括号前添加一个空格。
  • 声明块的右花括号应当单独成行。
  • 每条声明语句的 : 后应该插入一个空格。
  • 为了获得更准确的错误报告,每条声明都应该独占一行。
  • 所有声明语句都应当以分号结尾。最后一条声明语句后面的分号是可选的,但是,如果省略这个分号,你的代码可能更易出错。
  • 对于以逗号分隔的属性值,每个逗号后面都应该插入一个空格(例如,box-shadow)。
  • 不要在 rgb()、rgba()、hsl()、hsla() 或 rect() 值的内部的逗号后面插入空格。这样利于从多个属性值(既加逗号也加空格)中区分多个颜色值(只加逗号,不加空格)。
  • 对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5;-.5px 代替 -0.5px)。
  • 十六进制值应该全部小写,例如,#fff。在扫描文档时,小写字符易于分辨,因为他们的形式更易于区分。
  • 尽量使用简写形式的十六进制值,例如,用 #fff 代替 #ffffff。
  • 为选择器中的属性添加双引号,例如,input[type="text"]。只有在某些情况下是可选的,但是,为了代码的一致性,建议都加上双引号。
  • 避免为 0 值指定单位,例如,用 margin: 0; 代替 margin: 0px;。

声明顺序
相关的属性声明应当归为一组,并按照下面的顺序排列:

  • Positioning
  • Box model
  • Typographic
  • Visual
    由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位。盒模型排在第二位,因为它决定了组件的尺寸和位置。

其他属性只是影响组件的内部(inside)或者是不影响前两组属性,因此排在后面。

不要使用 @import
与 <link> 标签相比,@import 指令要慢很多,不光增加了额外的请求次数,还会导致不可预料的问题。替代办法有以下几种:

使用多个 <link> 元素
通过 Sass 或 Less 类似的 CSS 预处理器将多个 CSS 文件编译为一个文件
通过 Rails、Jekyll 或其他系统中提供过 CSS 文件合并功能

媒体查询(Media query)的位置
将媒体查询放在尽可能相关规则的附近。不要将他们打包放在一个单一样式文件中或者放在文档底部。如果你把他们分开了,将来只会被大家遗忘。下面给出一个典型的实例。

简写形式的属性声明
在需要显示地设置所有值的情况下,应当尽量限制使用简写形式的属性声明。常见的滥用简写属性声明的情况如下:

  • padding
  • margin
  • font
  • background
  • border
  • border-radius
    大部分情况下,我们不需要为简写形式的属性声明指定所有值。例如,HTML 的 heading 元素只需要设置上、下边距(margin)的值,因此,在必要的时候,只需覆盖这两个值就可以。过度使用简写形式的属性声明会导致代码混乱,并且会对属性值带来不必要的覆盖从而引起意外的副作用。

Less 和 Sass 中的嵌套
避免不必要的嵌套。这是因为虽然你可以使用嵌套,但是并不意味着应该使用嵌套。只有在必须将样式限制在父元素内(也就是后代选择器),并且存在多个需要嵌套的元素时才使用嵌套。(ps 推荐最多4层)

class 命名

  • class 名称中只能出现小写字符和破折号(dashe)(不是下划线,也不是驼峰命名法)。破折号应当用于相关 class 的命名(类似于命名空间)(例如,.btn 和 .btn-danger)。
  • 避免过度任意的简写。.btn 代表 button,但是 .s 不能表达任何意思。
  • class 名称应当尽可能短,并且意义明确。
  • 使用有意义的名称。使用有组织的或目的明确的名称,不要使用表现形式(presentational)的名称。
  • 基于最近的父 class 或基本(base) class 作为新 class 的前缀。
  • 使用 .js-* class 来标识行为(与样式相对),并且不要将这些 class 包含到 CSS 文件中。

在为 Sass 和 Less 变量命名时也可以参考上面列出的各项规范。

选择器

  • 对于通用元素使用 class ,这样利于渲染性能的优化。
  • 对于经常出现的组件,避免使用属性选择器(例如,[class^="..."])。浏览器的性能会受到这些因素的影响。
  • 选择器要尽可能短,并且尽量限制组成选择器的元素个数,建议不要超过 3 。
  • 只有在必要的时候才将 class 限制在最近的父元素内(也就是后代选择器)(例如,不使用带前缀的 class 时 -- 前缀类似于命名空间)。

代码组织

  • 以组件为单位组织代码段。
  • 制定一致的注释规范。
  • 使用一致的空白符将代码分隔成块,这样利于扫描较大的文档。
  • 如果使用了多个 CSS 文件,将其按照组件而非页面的形式分拆,因为页面会被重组,而组件只会被移动。

JS

文件命名
文件夹和文件名的命名应该能代表代码功能,与后端一致为佳。

语言规范
声明变量必须加上 var 关键字.
当你没有写 var, 变量就会暴露在全局上下文中, 这样很可能会和现有变量冲突. 另外, 如果没有加上, 很难明确该变量的作用域是什么, 变量也很可能像在局部作用域中, 很轻易地泄漏到 Document 或者 Window 中, 所以务必用 var 去声明变量.

分号
总是使用分号
如果仅依靠语句间的隐式分隔, 有时会很麻烦. 你自己更能清楚哪里是语句的起止,而且有些情况下,漏掉分号会很危险。

块内函数声明
不要在块内声明一个函数,不推荐一下写法:

虽然很多 JS 引擎都支持块内声明函数, 但它不属于 ECMAScript 规范 (见 ECMA-262, 第13和14条). 各个浏览器糟糕的实现相互不兼容, 有些也与未来 ECMAScript 草案相违背. ECMAScript 只允许在脚本的根语句或函数中声明函数. 如果确实需要在块中定义函数, 建议使用函数表达式来初始化变量:

闭包
比较好的介绍闭包原理的文档.
有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 DOM 元素附加闭包时, 很可能会产生循环引用, 进一步导致内存泄漏. 比如下面的代码:

这里, 即使没有使用 element, 闭包也保留了 element, a 和 b 的引用, . 由于 element 也保留了对闭包的引用, 这就产生了循环引用, 这就不能被 GC 回收.
这种情况下, 可将代码重构为:

this
仅在对象构造器, 方法, 闭包中使用.
this 的语义很特别. 有时它引用一个全局对象(大多数情况下), 调用者的作用域(使用eval时), DOM 树中的节点(添加事件处理函数时), 新创建的对象(使用一个构造器), 或者其他对象(如果函数被call() 或 apply())。

for-in 循环
最好只用于 object/map/hash 的遍历
对 Array 用 for-in 循环有时会出错. 因为它并不是从 0 到 length - 1 进行遍历, 而是所有出现在对象及其原型链的键值.
例如:给原型添加属性之后,默认情况下枚举,最后输出1234513

所以建议不要对数组执行for in循环,事实上,在高性能javascript这本书中,也强调了for in循环的不好,因为它总是会访问该对象的原型,看下原型上是否有属性,这在无意中就给遍历增加了额外的压力。

编码风格

明确作用域
任何时候都要明确作用域 – 提高可移植性和清晰度. 例如, 不要依赖于作用域链中的 window 对象.
可能在其他应用中, 你函数中的 window 不是指之前的那个窗口对象。

代码格式化

初始值占用多行时, 缩进2个空格.

引号的使用
单引号 (‘) 优于双引号 (“).
当你创建一个包含 HTML 代码的字符串时就知道它的好处了。

过长的单行予以换行
换行应选择在操作符和标点符号之后。

用数组和对象字面量来代替数组和对象构造器
数组构造器很容易让人在它的参数上犯错,如new Array(1, 2, 3)会生成数组[1, 2, 3],但
new Array(3)只会生成长度为3的空数组。
对象构造器不会有类似的问题,但是为了可读性和统一性,我们应该使用对象字面量。

循环的使用
在循环中,尽量使用变量先获取到相关数值,在放入循环中进行判断,否则非常影响性能。

注释
函数注释

语句注释

单行注释:

  • 单独一行://(双斜线)与注释文字之间保留一个空格;
  • 在代码后面添加注释://(双斜线)与代码之间保留一个空格,并且//(双斜线)与注释文字之间保留一个空格;
  • //(双斜线)与代码之间保留一个空格。

Vue规范

  1. Vue属性书写顺序

组件

组件以驼峰命名

组件引用

事件

vue 全局公用函数
如果你需要让一个工具函数在每个组件可用,可以把方法挂载到 Vue.prototype上。
注册
main.js 中

==一般建议函数名使用 $ 前缀。像 vue-router 的 $route 和 $router。==
使用
那么组件代码里

异步加载组件
将所有页面组件一次性加载是一个很浪费资源和考验用户耐心的做法,尤其在移动端。

使用方法
webpack 提供了code splitting,你可以按照下面写法实现当切换到特定路由时才加载代码。

需要注意的是 vue-loader@13.0.0 语法有所变更,具体参照发布说明 v13.0.0

组件实现依赖
新增外部依赖需要与核心开发成员讨论后决定,尽量选择较为知名开源组件,且避免体积过大。

引用

组件内部使用相对路径引用,避免使用alias。如import { extand } from '../util'。

通用方法

通用逻辑和样式使用_style/*, _util/*, 避免组件代码内部通用逻辑或样式冗余【新增需讨论】

区分测试环境和生产环境
如果你使用了 vux2 模板或者 webpack 模板,默认你可以直接通过判断 process.env.NODE_ENV 来区分

比如统计代码仅放在 production 环境,在不同环境里使用不同的 API 接口地址。

编辑器配置

  • 将你的编辑器按照下面的配置进行设置,以避免常见的代码不一致和差异:
  • 用两个空格代替制表符(soft-tab 即用空格代表 tab 符)。
  • 保存文件时,删除尾部的空白符。
  • 设置文件编码为 UTF-8。
  • 在文件结尾添加一个空白行。

小技巧

Normalize
为标准化浏览器元素的样式,推荐引入Normalize.css

ps 移动端

PC端

FastClick
为避免浏览器兼容问题引起的点击问题, 推荐引入FastClick

配置 rem 适配方案
postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem
https://github.com/cuth/postcss-pxtorem
lib-flexible 用于设置 rem 基准值
https://github.com/amfe/lib-flexible

下面提供了一份基本的 postcss 配置,可以在此配置的基础上根据项目需求进行修改

禁用 eslint
并不推荐禁用eslint, 编码规范可以一定程序上保证代码质量。但是如果你确实想禁用,可以删除build/webpack.base.conf.js里的相关代码。

css 重复代码清除
安装duplicate-style插件
在webpack 构建完成后对生成的css文件使用cssnano进行重复样式清除。建议只在production环境下开启,因为dev环境没有必要。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复