×

前端代码规范文档(阿里+Vue+airbnb Style)

sexyspace sexyspace 发表于2021-03-25 17:19:19 浏览449 评论0

一.基础规范

1.      所有文件都使用无 BOM 的 UTF-8 编码

2.      全部采用小写方式, 以中划线分隔

正例:web-management-system

反例:web_management_system / webManagementSystem

3.      目录命名

全部采用小写方式, 以中划线分隔,有复数结构时,要采用复数命名法, 缩写不用复数

正例: scripts / styles / components / images / utils / layouts / demo-styles / img / doc

反例: script / style / demo_scripts / demoStyles / imgs / docs

Vue 的项目中的 components 中的组件目录,使用PascalCase命名

正例: HeadSearch / PageLoading

反例: head-search / page-loading / notice-icon

4.      JS、CSS、SCSS、HTML、PNG 文件命名(全部采用小写方式, 以中划线分隔)

正例: render-dom.js / signup.css / index.html / company-logo.png

反例: renderDom.js / UserManagement.html

5.      命名严谨性

代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。 说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用

正例:henan / luoyang / rmb 等国际通用的名称,可视同英文。

反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3

 

二.HTML 规范(Vue Template 同样适用)

1.      HTML 类型

1)  使用h5的语义化标签

2)  规定字符编码

3)  IE 兼容模式

4)  规定字符编码

5)  DOCTYPE大写

6)  省略协议头

省略图像、媒体文件、样式表和脚本等URL协议头部声明 ( http: , https: ),这样可以同时兼容 http 和 https 。如果不是这两个声明的URL则不省略。

7)  提供有关页面的元信息

8)  注释

单行注释 //

多行注释 /** */

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

<meta name=”description” content=” ”>

<meta name=”keywords” content=” ”>

<meta name=”author” content=” ”>

<title>域名批发www.Yuming.fun/</title>

</head>

<body>

<header>头部</header>

    <img src="//www.Yuming.fun/images/company-logo.png" alt="Company" />

<footer>尾部</footer>

<script>

              /**

              *  let money = 100

              *  console.log(money)

              */

      </script>

</body>

</html>

2.      缩进

一般缩进2个字符(4个空格)

<!DOCTYPE html>

<html>

  <head>

<meta charset="UTF-8" />

    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />   

    <title>域名批发www.Yuming.fun/</title>

  </head>

  <body>

    <!-- 多行注释 -->

    <img src="//www.Yuming.fun/images/company-logo.png" alt="Company" />

   

  </body>

</html>

3.      单双引号

字符串 全部用单引号 ‘ ’

html代码中属性全部用双引号””

<!DOCTYPE html>

<html>

  <head>

    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

    <meta charset="UTF-8" />

    <title>Page title</title>

  </head>

  <body>

    <!-- 多行注释 -->

    <img src="images/company-logo.png" alt="Company" />

    <script>

              let str = '你好啊'

      </script>

  </body>

</html>

 

三.css规范

1.      命名

1)     class跟id名称使用小写字母,以中划线分隔

2)     scss 中的变量、函数、混合、placeholder 采用驼峰式命名

2.      选择器

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

2)     从结构、表现、行为分离的原则来看,应该尽量避免 css 中出现 HTML 标签,并且在 css 选择器中出现标签名会存在潜在的问题。

3)     选择子选择器,尽量避免直接使用,最好加上子代选择器 >

正例

.content > .title {

}

反例 (可能会消耗性能)

.content .title {

}

4)     每个选择器及属性独占一行

正例

.content  {

      height: 80px;

      width: 150px;

      font-size: 20px;

}

反例 (可能会消耗性能)

.content .title {

      height: 80px; width: 150px;

}

5)     避免使用id选择器及全局标签选择器防止污染全局样式

反例:

#header {

  padding-bottom: 0px;

  margin: 0em;

}

正例:

.header {

  padding-bottom: 0px;

  margin: 0em;

}

3.      不要使用@import

四.javascript 规范

1.      命名

1)     采用小写驼峰命名 lowerCamelCase,代码中的命名均不能以下划线或美元符号结束

反例: name / name / name$

2)     方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式。

正例: localValue / getHttpMessage() / inputUserId

3)     其中 method 方法命名必须是 动词 或者 动词+名词 形式

正例:saveShopCarData /openShopCarInfoDialog

反例:save / open / show / go

4)     常量命名全大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例: MAX_STOCK_COUNT

反例: MAX_COUNT

2.      代码格式

1)     使用 2 个空格进行缩进

正例:

if (x < y) {

  x += 10;

} else {

  x += 1;

}

2)     不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。

说明:任何情形,没有必要插入多个空行进行隔开。

3.      字符串

统一使用单引号(‘),不使用双引号(“)。这在创建 HTML 字符串非常有好处:

正例:

let str = 'foo';

let testDiv = '<div id="test"></div>';

反例:

let str = 'foo';

let testDiv = "<div id='test'></div>";

4.      对象声明

1)     使用字面值创建对象

正例: let user = {};

反例: let user = new Object();

2)     使用字面量来代替对象构造器

正例:

var user = {

  age: 0,

  name: 1,

  city: 3

};

反例:

var user = new Object();

user.age = 0;

user.name = 0;

user.city = 0;

5.      使用 ES6,7

1)     必须优先使用 ES6,7 中新增的语法糖和函数。这将简化你的程序,并让你的代码更加灵活和可复用。

2)     必须强制使用 ES6, ES7 的新语法,比如箭头函数、await/async , 解构, let , for…of 等等

6.      括号

下列关键字后必须有大括号(即使代码块的内容只有一行):if, else, for, while, do, switch, try, catch, finally, with。

正例:

if (condition) {

  doSomething();

}

反例:

if (condition) doSomething();

7.      undefined 判断

永远不要直接使用 undefined 进行变量判断;使用 typeof 和字符串’undefined’对变量进行判断。正例:

if (typeof person === 'undefined') {

    ...

}

反例:

if (person === undefined) {

    ...

}

8.      条件判断和循环最多三层

条件判断能使用三目运算符和逻辑运算符解决的,就不要使用条件判断,但是谨记不要写太长的三目运算符。如果超过 3 层请抽成函数,并写清楚注释。

9.      this 的转换命名

对上下文 this 的引用只能使用‘_this’来命名

10.   慎用 console.log

因 console.log 大量使用会有性能问题,所以在非 webpack 项目中谨慎使用 log 功能

 

五.Vue 项目规范

vue 项目规范以 Vue 官方规范 (https://cn.vuejs.org/v2/style-guide/) 中的 A 规范为基础,在其上面进行项目开发,故所有代码均遵守该规范。

注意:请仔仔细细阅读 Vue 官方规范。

1.      组件规范

1)     组件名为多个单词

组件名应该始终是多个单词组成(大于等于 2),且命名规范为PascalCase格式。

这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。

正例:

export default {

  name: 'TodoItem'

  // ...

};

反例:

export default {

  name: 'Todo',

  // ...

}

export default {

  name: 'todo-item',

  // ...

}

 

2)     组件文件名为kebab-case 格式

正例:

components/

|- my-component.vue

反例:

components/

|- myComponent.vue

|- MyComponent.vue

3)     基础组件文件名为 base 开头,使用完整单词而不是缩写。

正例:

components/

|- base-button.vue

|- base-table.vue

|- base-icon.vue

反例:

components/

|- MyButton.vue

|- VueTable.vue

|- Icon.vue

4)     和父组件紧密耦合的子组件应该以父组件名作为前缀命名

正例:

components/

|- todo-list.vue

|- todo-list-item.vue

|- todo-list-item-button.vue

|- user-profile-options.vue (完整单词)

反例:

components/

|- TodoList.vue

|- TodoItem.vue

|- TodoButton.vue

|- UProfOpts.vue (使用了缩写)

5)     在 Template 模版中使用组件,应使用 PascalCase 模式,并且使用自闭合组件。

正例:

<!-- 在单文件组件、字符串模板和 JSX 中 -->

<MyComponent />

<Row><table :column="data"/></Row>

反例:

<my-component /> <row><table :column="data"/></row>

6)     组件的 data 必须是一个函数

当在组件中使用 data 属性的时候 (除了 new Vue 外的任何地方),它的值必须是返回一个对象的函数。 因为如果直接是一个对象的话,子组件之间的属性值会互相影响。

正例:

export default {

  data () {

    return {

      name: 'jack'

    }

  }

}

反例:

export default {

  data: {

    name: 'jack'

  }

}

7)     Prop 定义应该尽量详细

必须使用 camelCase 驼峰命名

必须指定类型

必须加上注释,表明其含义

必须加上 required 或者 default,两者二选其一

如果有业务需要,必须加上 validator 验证

正例:

 props: {

  // 组件状态,用于控制组件的颜色

   status: {

     type: String,

     required: true,

     validator: function (value) {

       return [

         'succ',

         'info',

         'error'

       ].indexOf(value) !== -1

     }

   },

    // 用户级别,用于显示皇冠个数

   userLevel:{

      type: String,

      required: true

   }

}

8)     为组件样式设置作用域

正例:

<template>

  <button class="btn btn-close">X</button>

</template>

 

<!-- 使用 `scoped` 特性 -->

<style scoped>

  .btn-close {

    background-color: red;

  }

</style>

反例:

<template>

  <button class="btn btn-close">X</button>

</template>

<!-- 没有使用 `scoped` 特性 -->

<style>

  .btn-close {

    background-color: red;

  }

</style>

9)     如果特性元素较多,应该主动换行。

正例:

<MyComponent

     foo="a" bar="b" baz="c"

    foo="a" bar="b" baz="c"

    foo="a" bar="b" baz="c"

 />

反例:

<MyComponent foo="a" bar="b" baz="c"  foo="a" bar="b" baz="c"/>

2.      模板中使用简单的表达式

组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么,而非如何计算那个值。而且计算属性和方法使得代码可以重用。

正例:

<template>

  <p>{{ normalizedFullName }}</p>

</template>

// 复杂表达式已经移入一个计算属性

computed: {

  normalizedFullName: function () {

    return this.fullName.split(' ').map(function (word) {

      return word[0].toUpperCase() + word.slice(1)

    }).join(' ')

  }

}

反例:

<template>

  <p>

       {{

          fullName.split(' ').map(function (word) {

             return word[0].toUpperCase() + word.slice(1)

           }).join(' ')

        }}

  </p>

</template>

3.      指令都使用缩写形式

指令推荐都使用缩写形式,(用 : 表示 v-bind: 、用 @ 表示 v-on: 和用 # 表示 v-slot:)

正例:

<input

  @input="onInput"

  @focus="onFocus"

反例:

<input

  v-on:input="onInput"

  @focus="onFocus"

4.      标签顺序保持一致

单文件组件应该总是让标签顺序保持为

正例:

<template>...</template>

<script>...</script>

<style>...</style>

反例:

<template>...</template>

<style>...</style>

<script>...</script>

5.      必须为 v-for 设置键值 key

6.      v-show 与 v-if 选择

如果运行时,需要非常频繁地切换,使用 v-show ;如果在运行时,条件很少改变,使用 v-if。

7.      script 标签内部结构顺序

components > props > data > computed > watch > filter > 钩子函数(钩子函数按其执行顺序) > methods

8.      Vue Router 规范

1)     页面跳转数据传递使用路由参数

页面跳转,例如 A 页面跳转到 B 页面,需要将 A 页面的数据传递到 B 页面,推荐使用 路由参数进行传参,而不是将需要传递的数据保存 vuex,然后在 B 页面取出 vuex 的数据,因为如果在 B 页面刷新会导致 vuex 数据丢失,导致 B 页面无法正常显示数据。

正例:

let id = ' 123';

this.$router.push({ name: 'userCenter', query: { id: id } });

2)     使用路由懒加载(延迟加载)机制

{

        path: '/uploadAttachment',

        name: 'uploadAttachment',

        meta: {

          title: '上传附件'

        },

        component: () =>import('@/view/components/uploadAttachment/index.vue')

},

3)     router 中的命名规范

path、childrenPoints 命名规范采用kebab-case命名规范(尽量vue文件的目录结构保持一致,因为目录、文件名都是kebab-case,这样很方便找到对应的文件)

name 命名规范采用KebabCase命名规范且和component组件名保持一致!(因为要保持keep-alive特性,keep-alive按照component的name进行缓存,所以两者必须高度保持一致)

// 动态加载

export const reload = [

  {

    path: '/reload',

    name: 'reload',

    component: Main,

    meta: {

      title: '动态加载',

      icon: 'icon iconfont'

    },

 

    children: [

      {

        path: '/reload/smart-reload-list',

        name: 'SmartReloadList',

        meta: {

          title: 'SmartReload',

          childrenPoints: [

            {

              title: '查询',

              name: 'smart-reload-search'

            },

            {

              title: '执行reload',

              name: 'smart-reload-update'

            },

            {

              title: '查看执行结果',

              name: 'smart-reload-result'

            }

          ]

        },

        component: () =>

          import('@/views/reload/smart-reload/smart-reload-list.vue')

      }

    ]

  }

];

4)     router 中的 path 命名规范

path除了采用kebab-case命名规范以外,必须以 / 开头,即使是children里的path也要以 / 开头。如下示例

{

    path: '/file',

    name: 'File',

    component: Main,

    meta: {

      title: '文件服务',

      icon: 'ios-cloud-upload'

    },

    children: [

      {

        path: '/file/file-list',

        name: 'FileList',

        component: () => import('@/views/file/file-list.vue')

      },

      {

        path: '/file/file-add',

        name: 'FileAdd',

        component: () => import('@/views/file/file-add.vue')

      },

      {

        path: '/file/file-update',

        name: 'FileUpdate',

        component: () => import('@/views/file/file-update.vue')

      }

    ]

}

 

目的:

经常有这样的场景:某个页面有问题,要立刻找到这个vue文件,如果不用以/开头,path为parent和children组成的,可能经常需要在router文件里搜索多次才能找到,而如果以/开头,则能立刻搜索到对应的组件

 

9.      其他

1)  vue 项目中的所有命名一定要与后端命名统一。

比如权限:后端 privilege, 前端无论 router , store, api 等都必须使用 privielege 单词!

2)  使用 vue-cli3 来初始化项目,项目名按照上面的命名规范。

3)  目录名按照上面的命名规范,其中 components 组件目录用大写驼峰,其余除 components 组件目录外的所有目录均使用 kebab-case 命名。

4)  注释说明(必须加注释的地方)

公共组件使用说明

api 目录的接口 js 文件必须加注释

store 中的 state, mutation, action 等必须加注释

vue 文件中的 template 必须加注释,若文件较大添加 start end 注释

vue 文件的 methods,每个 method 必须添加注释

vue 文件的 data, 非常见单词要加注释其他

 

附Airbnb Javascript Style Guide

https://Github.com/airbnb/JavaScript