前端代码规范

文章详细阐述了前端开发中的命名规则,包括项目文件、目录、JS、CSS、HTML、Vue组件的命名规范。此外,还涵盖了HTML、CSS和JavaScript的代码规范,如缩进、空格、换行、引号的使用,以及属性声明顺序。Vue风格指南部分强调了组件命名、Prop定义、v-for键值设置和v-if/v-for的使用建议。
摘要由CSDN通过智能技术生成

目录

命名规则

项目文件命名

目录命名

JS 文件命名

CSS, SCSS 文件命名

HTML 文件命名

VUE 组件命名

缩进

HTML 代码规范

CSS 代码规范

空格规范

空行/换行

引号

命名

属性声明顺序

颜色

JavaScript 代码规范

分号

空格

换行

引号

变量命名

变量声明

函数

数组、对象

括号

undefined

其他

Vue 风格指南

优先级A的规则:必要的(规避错误)

组件名为多个单词

Prop 定义

为 v-for 设置键值

避免 v-if 和 v-for 用在一起

文章参考:


命名规则

项目文件命名

全部采用小写方式, 以下划线分隔。

例:my_project_name

目录命名

参照项目命名规则。

有复数结构时,要采用复数命名法。

例:scripts, styles, images, data_models

JS 文件命名

参照项目命名规则。

例:account_model.js

CSS, SCSS 文件命名

参照项目命名规则。

例:retina_sprites.scss

HTML 文件命名

参照项目命名规则。

例:error_report.html

VUE 组件命名

组件名首字母大写驼峰,应该由多单词组成,除了一些内置组件,如果是单个单词,加上标识 V

例:ToDoItem.vueVTable.vueVDetail.vue

缩进

HTML、JavaScript、CSS、SCSS、Vue,这些文件的内容全部使用2个空格缩进。可对IDE进行统一设置。


HTML 代码规范

  • 嵌套的节点按照结构,层层缩进,同时要注意 HTML的语义化;
  • 在属性上,使用双引号,不要使用单引号;
  • 自定义属性名全小写,用中划线做分隔符;
  • 当单个元素的属性过多时,需要适当换行,方便查看。

CSS 代码规范

空格规范

以下几种情况不需要空格:

  • 属性名后
  • 多个规则的分隔符','前
  • !important '!'后
  • 属性值中'('后和')'前
  • 行末不要有多余的空格

以下几种情况需要空格:

  • 属性值前
  • 选择器'>', '+', '~'前后
  • '{'前
  • !important '!'前
  • @else 前后
  • 属性值中的','后
  • 注释'/*'后和'*/'前
/* not good */
.element {
    color :red! important;
    background-color: rgba(0,0,0,.5);
}

/* good */
.element {
    color: red !important;
    background-color: rgba(0, 0, 0, .5);
}

/* not good */
.element ,
.dialog{
    ...
}

/* good */
.element,
.dialog {

}

/* not good */
.element>.dialog{
    ...
}

/* good */
.element > .dialog{
    ...
}

/* not good */
.element{
    ...
}

/* good */
.element {
    ...
}

空行/换行

以下几种情况需要空行:

  • 文件最后保留一个空行
  • '}'后最好跟一个空行,包括scss中嵌套的规则

以下几种情况不需要换行:

  • '{'前

以下几种情况需要换行:

  • '{'后和'}'前
  • 每个属性独占一行
  • 多个规则的分隔符','后
/* 空行 */
/* not good */
.element {
    ...
}
.dialog {
    color: red;
    &:after {
        ...
    }
}

/* good */
.element {
    ...
}

.dialog {
    color: red;

    &:after {
        ...
    }
}

/* 换行 */
/* not good */
.element
{color: red; background-color: black;}

/* good */
.element {
    color: red;
    background-color: black;
}

/* not good */
.element, .dialog {
    ...
}

/* good */
.element,
.dialog {
    ...
}

引号

最外层统一使用双引号;

url的内容要用引号;

属性选择器中的属性值需要引号。

.element:after {
    content: "";
    background-image: url("logo.png");
}

li[data-type="single"] {
    ...
}

命名

  • 类名使用小写字母,以中划线分隔
  • id采用驼峰式命名
  • scss中的变量、函数、混合、placeholder采用驼峰式命名
  • css命名规范也可以学习参考BEM策略

/* class */
.element-content {
    ...
}

/* id */
#myDialog {
    ...
}

/* 变量 */
$colorBlack: #000;

/* 函数 */
@function pxToRem($px) {
    ...
}

/* 混合 */
@mixin centerBlock {
    ...
}

/* placeholder */
%myDialog {
    ...
}

属性声明顺序

相关的属性声明按顺序做分组处理,组之间需要有一个空行。

.declaration-order {
    display: block;
    float: right;

    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;

    border: 1px solid #e5e5e5;
    border-radius: 3px;
    width: 100px;
    height: 100px;

    font: normal 13px "Helvetica Neue", sans-serif;
    line-height: 1.5;
    text-align: center;

    color: #333;
    background-color: #f5f5f5;

    opacity: 1;
}
// 下面是推荐的属性的顺序
[
    [
        "display",
        "visibility",
        "float",
        "clear",
        "overflow",
        "overflow-x",
        "overflow-y",
        "clip",
        "zoom"
    ],
    [
        "table-layout",
        "empty-cells",
        "caption-side",
        "border-spacing",
        "border-collapse",
        "list-style",
        "list-style-position",
        "list-style-type",
        "list-style-image"
    ],
    [
        "-webkit-box-orient",
        "-webkit-box-direction",
        "-webkit-box-decoration-break",
        "-webkit-box-pack",
        "-webkit-box-align",
        "-webkit-box-flex"
    ],
    [
        "position",
        "top",
        "right",
        "bottom",
        "left",
        "z-index"
    ],
    [
        "margin",
        "margin-top",
        "margin-right",
        "margin-bottom",
        "margin-left",
        "-webkit-box-sizing",
        "-moz-box-sizing",
        "box-sizing",
        "border",
        "border-width",
        "border-style",
        "border-color",
        "border-top",
        "border-top-width",
        "border-top-style",
        "border-top-color",
        "border-right",
        "border-right-width",
        "border-right-style",
        "border-right-color",
        "border-bottom",
        "border-bottom-width",
        "border-bottom-style",
        "border-bottom-color",
        "border-left",
        "border-left-width",
        "border-left-style",
        "border-left-color",
        "-webkit-border-radius",
        "-moz-border-radius",
        "border-radius",
        "-webkit-border-top-left-radius",
        "-moz-border-radius-topleft",
        "border-top-left-radius",
        "-webkit-border-top-right-radius",
        "-moz-border-radius-topright",
        "border-top-right-radius",
        "-webkit-border-bottom-right-radius",
        "-moz-border-radius-bottomright",
        "border-bottom-right-radius",
        "-webkit-border-bottom-left-radius",
        "-moz-border-radius-bottomleft",
        "border-bottom-left-radius",
        "-webkit-border-image",
        "-moz-border-image",
        "-o-border-image",
        "border-image",
        "-webkit-border-image-source",
        "-moz-border-image-source",
        "-o-border-image-source",
        "border-image-source",
        "-webkit-border-image-slice",
        "-moz-border-image-slice",
        "-o-border-image-slice",
        "border-image-slice",
        "-webkit-border-image-width",
        "-moz-border-image-width",
        "-o-border-image-width",
        "border-image-width",
        "-webkit-border-image-outset",
        "-moz-border-image-outset",
        "-o-border-image-outset",
        "border-image-outset",
        "-webkit-border-image-repeat",
        "-moz-border-image-repeat",
        "-o-border-image-repeat",
        "border-image-repeat",
        "padding",
        "padding-top",
        "padding-right",
        "padding-bottom",
        "padding-left",
        "width",
        "min-width",
        "max-width",
        "height",
        "min-height",
        "max-height"
    ],
    [
        "font",
        "font-family",
        "font-size",
        "font-weight",
        "font-style",
        "font-variant",
        "font-size-adjust",
        "font-stretch",
        "font-effect",
        "font-emphasize",
        "font-emphasize-position",
        "font-emphasize-style",
        "font-smooth",
        "line-height",
        "text-align",
        "-webkit-text-align-last",
        "-moz-text-align-last",
        "-ms-text-align-last",
        "text-align-last",
        "vertical-align",
        "white-space",
        "text-decoration",
        "text-emphasis",
        "text-emphasis-color",
        "text-emphasis-style",
        "text-emphasis-position",
        "text-indent",
        "-ms-text-justify",
        "text-justify",
        "letter-spacing",
        "word-spacing",
        "-ms-writing-mode",
        "text-outline",
        "text-transform",
        "text-wrap",
        "-ms-text-overflow",
        "text-overflow",
        "text-overflow-ellipsis",
        "text-overflow-mode",
        "-ms-word-wrap",
        "word-wrap",
        "-ms-word-break",
        "word-break"
    ],
    [
        "color",
        "background",
        "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
        "background-color",
        "background-image",
        "background-repeat",
        "background-attachment",
        "background-position",
        "-ms-background-position-x",
        "background-position-x",
        "-ms-background-position-y",
        "background-position-y",
        "-webkit-background-clip",
        "-moz-background-clip",
        "background-clip",
        "background-origin",
        "-webkit-background-size",
        "-moz-background-size",
        "-o-background-size",
        "background-size"
    ],
    [
        "outline",
        "outline-width",
        "outline-style",
        "outline-color",
        "outline-offset",
        "opacity",
        "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
        "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
        "-ms-interpolation-mode",
        "-webkit-box-shadow",
        "-moz-box-shadow",
        "box-shadow",
        "filter:progid:DXImageTransform.Microsoft.gradient",
        "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
        "text-shadow"
    ],
    [
        "-webkit-transition",
        "-moz-transition",
        "-ms-transition",
        "-o-transition",
        "transition",
        "-webkit-transition-delay",
        "-moz-transition-delay",
        "-ms-transition-delay",
        "-o-transition-delay",
        "transition-delay",
        "-webkit-transition-timing-function",
        "-moz-transition-timing-function",
        "-ms-transition-timing-function",
        "-o-transition-timing-function",
        "transition-timing-function",
        "-webkit-transition-duration",
        "-moz-transition-duration",
        "-ms-transition-duration",
        "-o-transition-duration",
        "transition-duration",
        "-webkit-transition-property",
        "-moz-transition-property",
        "-ms-transition-property",
        "-o-transition-property",
        "transition-property",
        "-webkit-transform",
        "-moz-transform",
        "-ms-transform",
        "-o-transform",
        "transform",
        "-webkit-transform-origin",
        "-moz-transform-origin",
        "-ms-transform-origin",
        "-o-transform-origin",
        "transform-origin",
        "-webkit-animation",
        "-moz-animation",
        "-ms-animation",
        "-o-animation",
        "animation",
        "-webkit-animation-name",
        "-moz-animation-name",
        "-ms-animation-name",
        "-o-animation-name",
        "animation-name",
        "-webkit-animation-duration",
        "-moz-animation-duration",
        "-ms-animation-duration",
        "-o-animation-duration",
        "animation-duration",
        "-webkit-animation-play-state",
        "-moz-animation-play-state",
        "-ms-animation-play-state",
        "-o-animation-play-state",
        "animation-play-state",
        "-webkit-animation-timing-function",
        "-moz-animation-timing-function",
        "-ms-animation-timing-function",
        "-o-animation-timing-function",
        "animation-timing-function",
        "-webkit-animation-delay",
        "-moz-animation-delay",
        "-ms-animation-delay",
        "-o-animation-delay",
        "animation-delay",
        "-webkit-animation-iteration-count",
        "-moz-animation-iteration-count",
        "-ms-animation-iteration-count",
        "-o-animation-iteration-count",
        "animation-iteration-count",
        "-webkit-animation-direction",
        "-moz-animation-direction",
        "-ms-animation-direction",
        "-o-animation-direction",
        "animation-direction"
    ],
    [
        "content",
        "quotes",
        "counter-reset",
        "counter-increment",
        "resize",
        "cursor",
        "-webkit-user-select",
        "-moz-user-select",
        "-ms-user-select",
        "user-select",
        "nav-index",
        "nav-up",
        "nav-right",
        "nav-down",
        "nav-left",
        "-moz-tab-size",
        "-o-tab-size",
        "tab-size",
        "-webkit-hyphens",
        "-moz-hyphens",
        "hyphens",
        "pointer-events"
    ]
]

颜色

颜色16进制用小写字母; 


JavaScript 代码规范

分号

为了使代码统一且整洁,所有行行末非必要不使用分号,以下情况需要使用分号:

以 “[”、“(”、“+”、“-”开头的行,需要在行首使用分号;

//反例 会报错
let hey = 'hey'
['hello', 'world'].forEach(...)

//正确
let hey = 'hey'
;['hello', 'world'].forEach(...)

//反例 会报错
const a = 1
const b = 2
const c = a + b
(a + b).toString()

//正确
const a = 1
const b = 2
const c = a + b
;(a + b).toString()

空格

以下几种情况不需要空格:

  • 对象的属性名后
  • 前缀一元运算符后
  • 后缀一元运算符前
  • 函数调用括号前
  • 无论是函数声明还是函数表达式,'('前不要空格
  • 数组的'['后和']'前
  • 对象的'{'后和'}'前
  • 运算符'('后和')'前

以下几种情况需要空格:

  • 二元运算符前后
  • 三元运算符'?:'前后
  • 代码块'{'前
  • 下列关键字前:elsewhilecatchfinally
  • 下列关键字后:ifelseforwhiledoswitchcasetrycatchfinallywithreturntypeof
  • 单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
  • 对象的属性值前
  • for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
  • 无论是函数声明还是函数表达式,'{'前一定要有空格
  • 函数的参数之间
// not good
let a = {
    b :1
}

// good
let a = {
    b: 1
}

// not good
++ x
y ++
z = x?1:2

// good
++x
y++
z = x ? 1 : 2

// not good
let a = [ 1, 2 ]

// good
let a = [1, 2]

// not good
let a = ( 1+2 )*3

// good
let a = (1 + 2) * 3

// no space before '(', one space before '{', one space between function parameters
let doSomething = function(a, b, c) {
    // do something
}

// no space before '('
doSomething(item)

// not good
for(i=0;i<6;i++){
    x++
}

// good
for (i = 0; i < 6; i++) {
    x++
}

换行

换行的地方,行末必须有','或者运算符;

以下几种情况不需要换行:

  • 下列关键字后:elsecatchfinally
  • 代码块'{'前

以下几种情况需要换行:

  • 代码块'{'后和'}'前
  • 变量赋值后
// not good
let a = {
    b: 1
    , c: 2
}

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

// no need line break with 'else', 'catch', 'finally'
if (condition) {
    ...
} else {
    ...
}

try {
    ...
} catch (e) {
    ...
} finally {
    ...
}

// not good
function test()
{
    ...
}

// good
function test() {
    ...
}

引号

最外层统一使用单引号。

// not good
let x = "test"

// good
let y = 'foo',
    z = '<div id="test"></div>'

变量命名

  • 标准变量采用驼峰式命名
  • 变量名首选用有意义的单词,非必要不使用单字母、中文和拼音,使用拼音时用全拼字母;
  • 常量全大写,用下划线连接;

变量声明

优先使用constlet声明变量,非必要不使用var。

函数

  • 函数命名规范同变量命名
  • 无论是函数声明还是函数表达式,'('前不要空格,但'{'前一定要有空格;
  • 函数调用括号前不需要空格;
  • 参数之间用', '分隔,注意逗号后有一个空格。
  • 使用有意义的前缀名称,例如:
    • get、find等代表函数返回一个值;
    • list、getXxxList、getXxxArray等代表返回一个集合列表;
    • add、insert代表函数将用于新增;
    • update、edit、set代表函数用于更新;
    • delete、remove代表函数用于删除;
    • on、handle用于事件处理函数;
    • is、should、can代表函数返回一个布尔类型;
// no space before '(', but one space before'{'
let doSomething = function(item) {
    // do something
}

function doSomething(item) {
    // do something
}

// not good
doSomething (item);

// good
doSomething(item);

数组、对象

  • 对象属性名不需要加引号;
  • 对象以缩进的形式书写,不要写在一行;
  • 数组、对象最后不要有逗号。
// not good
let a = {
    'b': 1
}

let a = {b: 1};

let a = {
    b: 1,
    c: 2,
}

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

括号

下列关键字后必须有大括号(即使代码块的内容只有一行):ifelseforwhiledoswitchtrycatchfinallywith

// not good
if (condition)
    doSomething()

// good
if (condition) {
    doSomething()
}

undefined

永远不要直接使用undefined进行变量判断;

使用typeof和字符串'undefined'对变量进行判断

// not good
if (person === undefined) {
    ...
}

// good
if (typeof person === 'undefined') {
    ...
}

其他

  • 用'===', '!=='代替'==', '!=';
  • 内容过长或者逻辑复杂的函数,尽量多写注释并将内部拆分成多个函数,使逻辑清晰;
  • 重复使用的代码或者后续能使用到的部分,尽量封装成函数;

Vue 风格指南

优先级A的规则:必要的(规避错误)

组件名为多个单词

组件名应该始终是多个单词的,根组件 App 以及 <transition>、<component> 之类的 Vue 内置组件除外。这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。

//反例
Vue.component('todo', {
  // ...
})

export default {
  name: 'Todo',
  // ...
}

//好例子
Vue.component('todo-item', {
  // ...
})

export default {
  name: 'TodoItem',
  // ...
}
Prop 定义

在你提交的代码中,prop 的定义应该尽量详细,至少需要指定其类型

//反例
props: ['status']

//好例子
props: {
  status: String
}

//更好的例子
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}
为 v-for 设置键值

在组件上总是必须用 key 配合 v-for,以便维护内部组件及其子树的状态。

//反例
<ul>
  <li v-for="todo in todos">
    {{ todo.text }}
  </li>
</ul>

//好例子
<ul>
  <li
    v-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>
避免 v-if 和 v-for 用在一起

一般我们在两种常见的情况下会倾向于这样做:

  • 为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
  • 为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ul、ol)。
//反例
<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

//反例
<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

//好例子
<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

//好例子
<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

优先级B:强烈推荐

优先级C:推荐

优先级D:谨慎使用

优先级B/C/D,可参考Vue官方风格指南

文章参考:

Code Guide by @AlloyTeam

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值