代码

365 阅读6分钟

前端代码规范

其中,* 表示部分为需严格遵守内容,其余为推荐内容。

该规范使用的项目模板为 :

参考文档:腾讯代码规范 凹凸实验室代码规范 Vue 官方风格指南

1. 项目安装及运行

依赖包安装

npm install

运行

npm run serve

打包

npm run build

格式化

npm run lint

2. 代码规范及开发风格指南

2.1 代码风格

本项目使用 eslint+prettier 来统一代码风格,并设置为保存文件时自动根据规则格式化,eslint 规则采用字节跳动前端代码规范,所有规则均已添加注释

在 vscode 中先安装插件 eslint 和 prettier

本项目的风格指南主要是参照vue官方的 风格指南

2.2 文件/文件夹命名规则 *

文件夹

文件夹使用横线连接 (kebab-case)

尽量使用名词,尽量使用一个单词

Component vue组件

所有的 Component 文件都是以大写开头 (PascalCase) ,这也是官方所推荐的。但除了 index.vue

例子:

  • @/src/components/BaseSelect.vue
js 文件

所有的.js文件都遵循横线连接 (kebab-case) ,其中属于class(类)的.js文件使用大写开头 (PascalCase)

views

views文件夹下,除index.vue之外,.vue文件都使用大写开头 (PascalCase)

例子:

  • @/src/views/demo-home/Home.vue

2.3 CSS样式

统一使用横线连接 (kebab-case) 命名风格

  1. 本项目使用 CSS/Scss, assets/css/index.css,assets/css/common.scss 中是全局样式的声明,在组件中,全部使用 scoped *,避免样式污染,需要修改 element 样式部分可使用 /deep/ 或者 >>> 深度作用选择器,或者在组件中新增没有 scoped 的 style 代码块,外层使用类名包裹

样式穿透

  • less使用 /deep/
<style scoped lang="less">
.content /deep/ .el-button {
     height: 60px;
}
</style>
复制代码
  • scss使用 ::v-deep
<style scoped lang="scss">
.content ::v-deep .el-button {
  height: 60px;
}
</style>
复制代码
  • stylus使用 >>>
<style scoped lang="stylus">
外层 >>> .custon-components{
  height: 60px;
}
</style>
  1. 通用样式封装:

在 styles/varibles.scss 进行相关通用样式封装,包含 通用element 样式、scss变量、样式@mixin 封装。例如:

//自定义滚动条样式
@mixin scrollbar-custom {
    overflow-y: scroll;
    &::-webkit-scrollbar {
        /*滚动条整体样式*/
        width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
        height: 15px;
    }
    &::-webkit-scrollbar-thumb {
        /*滚动条里面小方块*/
        border-radius: 5px;
        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
        background-color: rgba(63, 214, 235, 0.5);
        scrollbar-arrow-color: red;
    }
    &::-webkit-scrollbar-track {
        /*滚动条里面轨道*/
        border-radius: 10px;
        background: transparent;
    }
}
  1. 属性顺序

    同一 规则下的属性在书写时,应按功能进行分组。 并以 Formatting Model(布局方式、位置) > Box Model(尺寸) > Typographic(文本相关) > Visual(视觉效果) 的顺序书写,以提高代码的可读性。

    解释

    • Formatting Model 相关属性包括:position / top / right / bottom / left / float / display / overflow 等
    • Box Model 相关属性包括:border / margin / padding / width / height 等
    • Typographic 相关属性包括:font / line-height / text-align / word-wrap 等
    • Visual 相关属性包括:background / color / transition / list-style 等

2.4 注释规范

2.4.1 单行注释 *

一般用于简单的描述,如某些状态描述、属性描述等

注释内容前后各一个空格字符,注释位于要注释代码的上面,单独占一行

推荐:

<!-- Comment Text -->
<div>...</div>

不推荐:

<div>...</div><!-- Comment Text --> 
    
<div><!-- Comment Text -->
    ...
</div>

2.4.2 模块注释 *

一般用于描述模块的名称以及模块开始与结束的位置

注释内容前后各一个空格字符,<!-- S Comment Text --> 表示模块开始,<!-- E Comment Text --> 表示模块结束,模块与模块之间相隔一行

推荐写法:

<!-- S Comment Text A -->   
<div class="mod_a">
    ...
</div>
<!-- E Comment Text A -->
    
<!-- S Comment Text B -->   
<div class="mod_b">
    ...
</div>
<!-- E Comment Text B -->

不推荐写法:

<!-- S Comment Text A -->
<div class="mod_a">
    ...
</div>
<!-- E Comment Text A -->
<!-- S Comment Text B -->   
<div class="mod_b">
    ...
</div>
<!-- E Comment Text B -->

2.4.3 嵌套模块注释

当模块注释内再出现模块注释的时候,为了突出主要模块,嵌套模块不再使用

<!-- S Comment Text -->
<!-- E Comment Text -->

而改用

<!-- /Comment Text -->

注释写在模块结尾标签底部,单独一行。

<!-- S Comment Text A -->
<div class="mod_a">
        
    <div class="mod_b">
        ...
    </div>
    <!-- /mod_b -->
        
    <div class="mod_c">
        ...
    </div>
    <!-- /mod_c -->
        
</div>
<!-- E Comment Text A -->

2.4.4 函数/方法注释 *

vscode 中可使用插件 koroFileHeader, ctrl+alt+i 生成 文件头部注释,ctrl+alt+t 生成方法注释

[强制] 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。

解释:

return 关键字仅作退出函数/方法使用时,无须对返回值作注释标识。

[强制] 参数和返回值注释必须包含类型信息,且不允许省略参数的说明。

[建议] 当函数是内部函数,外部不可访问时,可以使用 @inner 标识。

示例:

/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}

[强制] 对 Object 中各项的描述, 必须使用 @param 标识。

示例:

/**
 * 函数描述
 *
 * @param {Object} option 参数描述
 * @param {string} option.url option项描述
 * @param {string=} option.method option项描述,可选参数
 */
function foo(option) {
    // TODO
}

2.4.5 文件注释

参照:

/*
 * @Author: mat
 * @Date: 2021-03-29 07:57:37
 * @LastEditTime: 2021-04-14 14:23:47
 * @Description: Cesium 相关工具方法,包含坐标转换、定位等
 */

2.4.6 复杂对象注释

参照:

/**
 * 服务器
 *
 * @typedef {Object} namespaceA~Server
 * @property {string} host 主机
 * @property {number} port 端口
 */

2.5 Vue 项目中的代码规范

  1. v-for设置key值 *
  2. 避免v-if和v-for用一起 *
  3. 组件使用方式 *
<!-- 在单文件组件、字符串模板和 JSX 中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>
  1. props 的定义尽量详尽, 例如类型、必填项、默认值、校验规则 *
props: {
    status: {
        type: String,
        required: true,
        default: ''
    }
}
  1. 所有的vue项目,统一使用路由懒加载。例如:*
{
    path: '/login',
    name: 'login',
    component: () => import('@/views/home/login')
},
  1. 组件文件中必须包含name,name必须是由多个单词组成,并且是驼峰形式 *
  2. 页面中样式尽量写在<style scoped></style>中,避免引起多页面样式被覆盖。 *
  3. 覆盖饿了么组件样式时,统一加上父元素class。 *
  4. this复制统一使用 let that = this。*
  5. vue中变量定义声明用let或const。*
  6. 静态资源引用使用绝对路径 , 例如:background: url('/images/weather/menu-bg.png'); *
  7. 组件选项顺序 *
export default {
      name: '',
      mixins: [],
      components: {},
      props: {},
      data() {},
      computed: {},
      watch: {},
      created() {},
      mounted() {},
      destroyed() {},
      methods: {}
}

2.6 其他规范:

  1. 职责单一 *

任何时候尽量是的一个函数就做一件事情,而不是将各种逻辑全部耦合在一起,提高单个函数的复用性和可读性

每个页面都会在加载完成时进行数据的请求并展示到页面

created() {
  this.init();
},
methods: {
  // 将全部的请求行为聚合在init函数中
  // 将每个请求单独拆分
  init() {
    this.getList1()
    this.getList2()
  },
  getList1() {
    // to do ...
  },
  getList2() {
    // to do ...
  }
}
  1. 策略模式 *

策略模式的使用,避免过多的if else判断,也可以替代简单逻辑的switch

const formatDemandItemType = (value) => {
    switch (value) {
        case 1:
            return '基础'
        case 2:
            return '高级'
        case 3:
            return 'VIP'
    }
}

// 策略模式
const formatDemandItemType2 = (value) => {
    const obj = {
        1: '基础',
        2: '高级',
        3: 'VIP',
    }
    
    return obj[value]
}

3. 请求封装 *

本项目在 utils/request.js 中对 axios 进行简单封装,在 api 文件夹下对各个模块的接口进行单独声明,在组件中使用时先引入

import UserApi from '@/api/UserApi.js'

后使用

UserApi.list().then(res => {
   console.log(res)
})