前端代码规范

230 阅读9分钟

(一)环境搭建

1.1 安装依赖

项目使用的node环境统一v16.14.2

项目中所需要的依赖都会在package.json文件中展示。

安装依赖需要使用cnpm命令,可去cnpm官方文档使用及学习。

1.1.1 生产环境依赖

生产环境需要的依赖安装在属性dependencies之下。

可以使用命令:

cnpm install xxx --save

不可安装生产环境无需用到的依赖,如已经安装,请使用uninstall卸载依赖

1.1.2 开发环境依赖

开发环境需要的依赖安装在属性devDependencies之下。

可以使用命令:

cnpm install xxx --save-dev

1.2 vue.config.js配置

1.2.1 运行端口

项目开发环境下的运行端口为:

port: 8082

如8082端口已被其它应用占用,请提前释放端口绑定

1.2.2 代理

如果项目中需要使用其他系统请求,涉及的跨域问题,可以按照下面方式修改代理配置。

proxy: {
    '/api': {
        target: 'http://xxx',
        pathRewrite: { //是否重写
            '^/api': '',
        },
        changeOrigin: true,
        secure: false,
    },
}

(二) 项目规范

2.1 项目技术构成

本项目由vue.js技术框架搭建,配合webpack打包。

//技术版本
vue: 5.0.8
webpack: 5.74.0

vue.js官方文档 学习及使用。

webpack学习及使用。

2.2 项目结构规范

2.2.1 项目结构的核心思想

  • 业务功能模块的相关代码都集中在一块,方便移动和删除
  • 实现关注点分离,方便开发、调试、维护、编写、查阅、理解代码
  • 按照业务模块进行文件形式的区分,将各自相关模块集中在各自的相关文件目录下

2.2.2 项目目录

.
├── vue.config.js/                      # webpack 配置文件;
├── config/                     # 与项目构建相关的常用的配置选项;
├── src/
│   ├── main.js                 # webpack 的入口文件;
│   ├── assets/                 # 共用的代码以外的资源,如:图片、图标、视频 等;
│   ├── api/                    # 网络模块,如:接口;
│   ├── router/                 # 路由模块
│   ├── vuex/                   # 组件共享状态
│   ├── components/             # 共用的组件;; 这里的存放的组件应该都是展示组件
│   │   ├── base/               # 基本组件,如:共用的弹窗组件,loading加载组件,提示组件。
│   │   ├── common/             # 共用的全局组件,封装的导航条,底部组件等等
│   │   ├── temp/               # 模板组件,如:相同的页面封装成一个组件。
│   │   ├── UItemp/             # UI组件,如:项目中特定的按钮,消息数字,等等一些样式可以封装成组件的。
│   │   ├── tools/              # 自己封装的一些工具
│   │   └── ...
│   ├── layout/                 # 项目基础布局模块
│   └── app/                    # 存放项目业务代码;
│       ├── App.vue             # app 的根组件;
├── public/                     # 纯静态资源,该目录下的文件不会被webpack处理,该目录会被拷贝到输出目录下;
├── .babelrc                    # babel 的配置文件
├── .editorconfig               # 编辑器的配置文件;可配置如缩进、空格、制表类似的参数;
├── .eslintrc.js                # eslint 的配置文件
├── .eslintignore               # eslint 的忽略规则
├── .gitignore                  # git的忽略配置文件
├── index.html                  # HTML模板
├── project-specification.md    # 项目规范文档
├── package.json                # npm包配置文件,里面定义了项目的npm脚本,依赖包等信息
└── README.md                   # 项目信息文档

2.3 资源命名

2.3.1

  • 能直观的感受到当前目录的作用
  • 以小驼峰的方式命名
  • 特殊缩写名称可大写开头
│   ├── view/
│   ├── components/
│   │   ├── UItemp/

2.3.2 页面命名

  • 能直观的感受当前文件的作用
  • 以小驼峰的方式命名
│   ├── index.vue
│   ├── homePage.vue

2.3.3 组件命名

  • 能直观的感受到当前组件的用途
  • 组件命名始终是多个单词的,这是为了避免跟html元素或标签冲突
  • 大写开头
components/
├── BaseButton.vue
├── BaseTable.vue
├── BaseButton.vue

2.3.4 图片命名

  • 图片文件夹一般遵循从页面或者模块命名,如:home/
  • 图片不可随意命名,且严禁使用0,1等数字直接命名图片
  • 图片命名可遵循:用途+描述,多个单词用下划线隔开,如:home_icon.png,nav_icon.png
  • 10K以下图片尽量放置在assets/images下(webpack打包时直接转为base64嵌入)
  • 大图片且不常更换的图片放置在public/images
  • 可用css生成想要的效果样式,就不必去使用图片
  • 国际化图片,后缀使用简体-cn,英文-en,繁体-tw
│   ├── assets/               
│   │   ├── images/
│   │   │    ├── home_icon.png
│   │   │    ├── nav_icon.png

2.4 资源使用

2.4.1 组件使用规范

  • 使用geographic-select格式
  • 命名遵循组件命名规范
  • 推荐使用单标签闭合
<geographic-select />

2.4.2 图片使用规范

项目下有两个文件夹放置图片地址src/assets/images,public/images

webpack打包时会直接copypublic/images下的图片,所以,当你的图片放置public/images下时,为防止图片打包重复,需要遵从以下写法:

  • public/img下的图片调用时禁止使用require

因为通过require调用的图片会经过webpack打包,生成hash后缀,同public/img下图片重复

let img1 = require('../public/images/xxxx')//错误写法
let img2 ='../public/images/xxxx'//正确写法
  • public/img下的图片不可直接嵌入img的src中

因为img标签src中的图片也会经过webpack打包

<!--错误写法-->
<img src="../public/images/xxx">
<!--正确写法-->
<img :src="`../public/images/xxx`">
  • src/assets/images下的图片必须使用require写法,否则会报错找不到图片
<!--正确写法-->
<img src="../asset/images/xxx">
<!--错误写法-->
<img :src="`../asset/images/xxx`">
let img1 = require('../asset/images/xxxx')//正确写法
let img2 ='../asset/images/xxxx'//错误写法

图片这样区分,防止图片重复打包,增加项目体积

2.5 项目路由

2.5.1 路由命名

  • 普通路由(非动态多级)命名,可以直接使用页面组件的命名。
{
    path: '/login',
    name: 'login',
    component: () => import("../view/pages/login.vue"),
},
  • 动态多级路由,遵循:用途或作用或功能。
/user/personal/infomaition  用户中心 -> 个人中心 -> 个人信息
/user/company/infomaition  用户中心 -> 企业中心 -> 企业信息

(三) 编码规范

3.1 HTML规范

3.1.1 外链资源URL协议

省略外链资源(图片及其它媒体资源)URL 中的 http / https 协议,使 URL 成为相对地址,避免Mixed Content 问题,减小文件字节数。

Mixed Content:http和https混用造成的问题。

其它协议(ftp 等)的 URL 不省略。

<!-- 推荐 -->
<script src="//www.xxx.cn/statics/js/autotrack.js"></script>

<!-- 不推荐 -->
<script src="http://www.xxx.cn/statics/js/autotrack.js"></script>
/* 推荐 */
.example {
  background: url(//www.google.com/images/example);
}

/* 不推荐 */
.example {
  background: url(http://www.google.com/images/example);
}

3.1.2 标签中的属性顺序

  • class(class 是最高的复用设计,应该放在最前)
  • id name(id 应尽量少用)
  • data-\* 自定义属性(属性名称全小写用-做连接)
  • src (资源文件)
  • placeholder title alt (提示)
  • required readonly disable(辅助)

3.1.3 引号规范

  • 属性值使用双引号包裹
<div :data="data" data-src="some"></div>

3.1.4 注释规范

<!-- 头部 -->
<view class="header">
  <!-- LOGO -->
  <image class="logo"></image>
  <!-- /LOGO -->
  <!-- 详情 -->
  <view class="detail"> </view>
  <!-- /详情 -->
</view>
<!-- /头部 -->

3.2 CSS规范

3.2.1 id class命名规则

  • 首先根据内容命名,如:nav,header
  • 内容中的子元素使用-链接,名称一律小写,如:card-item
  • 修饰类(易变的)使用--链接,如:card-item--warning
  • 若无内容,结合行为进行辅助,如:box-shawder
  • 不影响语义的情况下,可缩写,如:img-box,btn
  • 避免广告拦截词汇:ad,gg,banner,guagngao

3.2.2 属性

属性顺序

  • 位置属性(position,top,right,z-index,display,flaot)
  • 大小(width,height,padding,margin)
  • 文字(font,line-height,letter-spacing, color)
  • 背景 (background,border)
  • 其他(animation,transition)

属性简写

属性简写需要你非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰;


/* not good */
.element {
    transition: opacity 1s linear 2s;
}
 
/* good */
.element {
    transition-delay: 2s;
    transition-timing-function: linear;
    transition-duration: 1s;
    transition-property: opacity;
}

margin 和 padding 相反,需要使用简写;margin 和 padding 相反,需要使用简写;

3.2.3 媒体查询

尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。

.element-selected { ... }

@media (max-width: 768px) {
  .element-selected { ... }
}
复制代码

3.2.4 注释规范

  • 组件块和子组件之间的注释
/* ==========================================================================
   组件块
 ============================================================================ */

/* 子组件块
 ============================================================================ */
.selector {
  padding: 15px;
  margin-bottom: 15px;
}

/* 子组件块
 ============================================================================ */
.selector-secondary {
  display: block; /* 注释*/
}
复制代码
  • 单行注释/*后跟空格
/* xxx */
复制代码

3.2.5 less规范

  • 组织顺序

    • @import
    • 变量声明
    • 样式声明
  • 避免嵌套过多,将嵌套深度限制在3级,超过需重新评估

@import "mixins/size.less";

@default-text-color: #333;

.page {
  width: 960px;
  margin: 0 auto;
}

3.2.6 其他规范

  • 去掉小数点后面的0,如:rgba(0,0,0,0.5)=>rgba(0,0,0,.5)
  • 颜色代码尽量简写,如:#fff
  • 尽量少用元素选择器,元素选择器和 ID、Class 混合使用也违反关注分离原则。如果HTML标签修改了,就要再去修改 CSS 代码,不利于后期维护。
/* 不推荐 */
.red {}
.box_green {}
.page .header .login #username input {}
ul#example {}

/* 推荐 */
#nav {}
.box-video {}
#username input {}
#example {}

3.3 JavaScript编码规范

3.3.1 缩进

html,css,js缩进一致,使用2个空格。

3.3.2 空格

  • 二元运算符前后
  • 三元运算符前后
  • 代码块{
  • 关键字前:else, while, catch, finally
  • 关键字后:if, else, for, while, do, switch, case, catch, finally, with, return
  • 单行注释//后,多行注释/*
  • 对象的属性值前
  • for 循环
  • 函数的参数之间
  • 运算符前后
  • 函数声明,函数表达式(前不要空格,)后空格

3.3.3 空行

  • 变量声明后
  • 注释前
  • 代码块后
  • 文件最后保留一个空行
let string = "my"

let obj = {
    "name": "yang"
}

{
    // do something
}

/* zheli */
if {
    
} else {
    
}

3.3.4 引号

  • 最外层统一使用双引号。
let str = "my name is"

3.3.5 模板字符串

  • 需要拼接,尽量少用+,多使用模板字符串
let str1 = "yang"

let string = `hello ${str1}`

3.3.6 命名规范

  • 变量命名:小驼峰命名(推荐)

  • 参数名:小驼峰命名(推荐)

  • 函数名:小驼峰命名(推荐)

  • 方法/属性名:小驼峰命名(推荐)

  • 类名开头大写(推荐)

  • 私有属性、变量和方法以下划线 _ 开头。(推荐)

  • 常量名:全部使用大写+下划线(推荐)

  • 由多个单词组成的缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。(推荐)

  • 语义

    • 变量应当使用名词,尽量符合当时语义
    • boolean类型应当使用 is , has 等开头
    • 点击事件命名方式:tap + onClick()
let loadingModules = {};

const HTML_ENTITY = {};

function stringFormat(theBells) {}

function insertHTML(element, html) {}

function Engine(options) {}

3.3.7 二元三元操作符

  • 可用于简单的if替代
  • 操作符始终写在前一行,避免产生预想不到的问题
// 不推荐 
var x = a ? b : c;

// 推荐 
var y = a ?
    longButSimpleOperandB : longButSimpleOperandC;

var z = a ?
        moreComplicatedB :
        moreComplicatedC;

3.3.8 && 和 ||

二元布尔操作符是可短路的, 只有在必要时才会计算到最后一项。

// 不推荐
function foo(opt_win) {
  var win;
  if (opt_win) {
    win = opt_win;
  } else {
    win = window;
  }
  // ...
}

if (node) {
  if (node.kids) {
    if (node.kids[index]) {
      foo(node.kids[index]);
    }
  }
}

// 推荐
function foo(opt_win) {
  var win = opt_win || window;
  // ...
}

var kid = node && node.kids && node.kids[index];
if (kid) {
  foo(kid);
}

3.3.9 声明规范

  • 尽量使用 let 声明变量,少用 var 。

3.3.10 分号

以下情况需要加分号

  • 表达式
  • return
  • throw
  • break
  • continue
  • do-while

3.3.11 注释规范

  • 单行注释,独占一行,//后跟空格

  • 多行注释,/*后跟空格(推荐)

  • 函数/方法注释

    • 注释必须包含函数声明,有参数和返回值时必须注释标识
    • 参数和返回类型必须包含类型信息和说明
    • 当函数是内部函数,外部不可访问时,可使用@inner标识

// 注释

/* xxxx
 xxxx
 xxxxx
/*

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

3.3.12 api规范

  • 每一个接口函数都是用export导出
  • get请求使用参数param
  • post请求使用参数data
  • 请求方法中必须简写
// 非简写
data: params
// 简写
params

// 非简写
data: data
// 简写
data
// 举例
// 测试接口
export function testApi(param) {
  return request({
    url: "/xxx/test",
    method: "get",
    param
  })
}