样式规范
使用scss嵌套写法,scoped为组件作用域, class类名尽量语义化, 方便阅读且缩短类名长度可使用后缀衔接的方式
如:
<style lang="scss" scoped>
/* 这是注释 */
.pvc-test-tree {
.test-tree-title {
.title-icon {
color: '#ccc';
}
}
.test-tree-content {
.content-table {}
}
}
</style>
代码格式化
样式书写分紧凑格式和展开格式, 统一用展开格式书写样式
/* 不推荐 */
.jdc { display: block;width:50px;}
/* 推荐 */
.jdc {
display: block;
width: 50px;
}
代码大小写
样式选择器, 属性名, 属性值全部小写, 属性字符串允许使用大小写
/* 推荐 */
.jdb {
display: block;
}
/* 不推荐 */
.JDC {
DISPLAY: BLOCK;
}
选择器
- 尽量少用通配符选择器 *
- 不使用 ID 选择器
- 不使用无具体语义定义的标签选择器
/* 不推荐 */
* {}
#jdc {}
.jdc div {}
/* 推荐 */
.jdc {}
.jdc li {}
.jdc li p {}
分号
每个属性声明末尾都要加分号 ;
.jdc {
width: 100%;
height: 100%;
}
代码易读性
为单个css 选择器或新申明开启新行
.jdc,
.jdc_logo,
.jdc_hd {
color: '#ffo';
}
.nav {
color: '#fff';
}
属性值引号
css属性值需要用引号时, 统一使用单引号
.jdc {
font-family: 'Hiragino Sans GB';
}
注释规范
注释以字符 /* 开始, 以字符 */ 结束
/* 注释 */
.jdc {
display: block;
}
js 书写规范
空格
if-else、for、function...... 与 () {} 之间保留空格
箭头函数 () => {} 保留空格
函数参数之间保留空格
< > = + - * % ?&& || 号两边保留空格
// if-else
if (condition) {
} else {
}
// for
for (let index = 0; index < array.length; index++) {
}
// function
function name(params) {
}
// class
class Event {
constructor() {
}
}
// 箭头函数
const init = () => {
}
// 三元表达式
const value = num === 0 ? 1 : 2
// 赋值
const name = 18
// 判断大小
if (num >= 20) return
// 计算
const year = (2000 + 23) * 1
// 对象
const info = {name: 'tom', age: 19}
大括号风格
if (foo) {
bar();
} else {
baz();
}
链式赋值
// 禁止
const a = b = c = 1;
// 推荐
const a = 1;
const b = 1;
const c = 1;
变量声明
禁止在一个声明中声明多个变量
// 禁止
const a, b, c;
// 推荐
const a;
const b;
const c;
使用const let 关键字进行变量声明并分组, 禁止不写关键字, 直接暴露在全局上下文, 可能导致与现有变量冲突
const b;
const d;
let a;
let c;
let e;
函数声明
不要在(if, while 等) 中声明函数
// 错误
if (isUse) {
function test () {
// do something
}
}
// 正确
let test;
if (isUse) {
test = () => {
// do something
}
}
不要将参数命名为arguments, 会导致该参数的优先级高于每个函数作用域内原先存在的arguments 对象
// 错误
function foo (name,options,arguments) {
// ...
}
// 正确
function foor (name,options,args) {
}
不要使用 arguments, 只是一个类数组, 要使用展开运算符 ... ,才是一个真正的数组
// 错误
function test () {
const args = Array.prototype.slice.call(arguments);
return args.join('')
}
// 正确
function test (...args) {
return args.join('')
}
使用函数默认参数, 不要修改函数参数值
// 错误
function handleThings (opts) {
opts = opts || {};
// ...
}
// 错误
function handleThings (opts) {
if (opts === void 0) {
opts = {}
}
// ...
}
// 正确
function handleThings (opts = {}) {
// ...
}
类&构造函数
使用 class, 避免直接操作 prototype
// 不推荐
function Queue (contents = []) {
this._queue = [...contents];
}
Queue.prototype.pop = function () {
const value = this._queue[0];
this._queue.splice(0,1);
return value
}
// 推荐
class Queue {
constructor (contents = []) {
this._queue = [...contents];
}
private pop () {
const value = this._queue[0];
this._queue.splice(0,1);
return value
}
}
使用 extends 来实现继承
原因: 这是一个不会破坏 instanceof 的内建实现原型式继承的方式
// 错误
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this,contents);
}
inherits(PeekableQueue,Queue);
PeekableQueue.prototype.peek = function () {
return this.queue[0]
}
// 正确
class PeekableQueue extends Queue {
public peek () {
return this.queue[0]
}
}
构造函数首字母大写
const footItem = new Foo();
类和函数的命名
函数采用小驼峰命名, 类采用大驼峰命名, 类的含义尽可能为名词, 函数为动词
const replayer = new Replayer();
function transTo() {}
类的函数成员和变量成员
- 明确成员的作用域, 必须在成员前标识成员的作用域, private, protect和public
- 变量成员命名采用 '_' 开头
class MyClass {
private _test;
public getText() {
}
}
函数参数个数限制
函数参数个数限定在4个以内, 包含4, 函数参数过长容易漏, 也无法很好扩展
// 不推荐
function trans(num1, num2, isChange, isRevert, isCount) {
}
//推荐
function trans(num1, num2, options: {isChange, isRevert, isCount}) {
}
注释规范
单行注释:
独占一行, 注释内容和注释符之间需要有一个空格
// 将文本转换成base64
let base64 = trans2Base64(text);
多行注释:
非类和函数避免使用 /**/ 这样的多行注释, 有多行注释内容时, 使用多个单行注释
// 将文本转换成base64
// 目的是为了转base64
let base64 = trans2Base64(text);
类注释:
类必须添加注释, 并符合 jsdoc 导出规范
/**
* Book类,代表一个书本.
* @constructor
* @param {string} title - 书本的标题.
* @param {string} author - 书本的作者.
*/
class BookClass {
constructor(title, author) {
}
}
函数/方法注释:
函数/方法必须添加注释, 并符合 jsdoc 导出规范
必须包含类的说明; 有参数和返回值时, 必须有注释标志; 参数和返回值必须包含类型信息和说明; 当函数是内部函数, 外部不可以访问时,可以使用 @inner 来标识; 示范:
/**
* 计算总价
* @param {number} price 商品价格
* @returns {number} 加税后的总价
*/
function calculateTotal(price) {
return price * 1.08; // 1.08 是税率
}
文件注释:
文件注释用于告诉不熟悉这段代码的读者这个文件中包含哪些东西。文件注释要标明作者、文件版本、创建/修改时间、重大版本修改记录; 示范
/**
* 文件描述
* @Author: nobady
* @Date: 2022-04-24 17:14
* @Last Modified by: somebody
* @Last Modified time: 2022-04-24 17:14
*/
版本号规范
- 软件版本阶段说明 Alpha版: 此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。
Beta版: 该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI。
RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。
Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release 不会以单词形式出现在软件封面上,取而代之的是符号(R)。
- 版本命名规范 软件版本号由四部分组成:
第一个1为主版本号
第二个1为子版本号
第三个1为阶段版本号
第四部分为日期版本号加希腊字母版本号
希腊字母版本号共有5种,分别为:base、alpha、beta、RC、release。例如:1.1.1.051021_beta
常规:完全的版本号定义,分三项::<主版本号>.<次版本号>.<修订版本号>,如 1.0.0
- 版本号定修改规则 主版本号(1):当功能模块有较大的变动,比如增加多个模块或者整体架构发生变化。此版本号由项目决定是否修改。
子版本号(1):当功能有一定的增加或变化,比如增加了对权限控制、增加自定义视图等功能。此版本号由项目决定是否修改。
阶段版本号(1):一般是 Bug 修复或是一些小的变动,要经常发布修订版,时间间隔不限,修复一个严重的bug即可发布一个修订版。此版本号由项目经理决定是否修改。
日期版本号(051021): 用于记录修改项目的当前日期,每天对项目的修改都需要更改日期版本号。此版本号由开发人员决定是否修改。
希腊字母版本号(beta): 此版本号用于标注当前版本的软件处于哪个开发阶段,当软件进入到另一个阶段时需要修改此版本号。此版本号由项目决定是否修改。