# 代码格式约定

::: details 目录
[[toc]]
:::

## 意义

::: tip
使应用程序的结构和编码风格标准化,以便于阅读和理解这段编码。

好的编码约定可使源代码严谨、可读性强且意义清楚。
:::

## 格式约定

### 要求

启动`ESLint`,不可存在语法报错问题。特殊情况，无法解决的，提出，共同探讨。

### 缩进
缩进统一为4格

### 注释

单行注释符后留一个空格
```typescript
// this is comment
```

如果某段代码有功能未实现，或者有待完善，必须添加`TODO`标记，`TODO`前后应留一个空格
```typescript
  private drawBox(painter: SPainter): void {
        // TODO 未实现绘制方块
    }
```

属性注释格式
```typescript
/** ... */
```
功能函数注释：注释将会以预定格式出现在API文档中。它以“/**”开头，以“*/”结束，其间的每一行均以“*”开头（均与开始符的第一个“*”对齐），且注释内容与“*”间留一个空格
```typescript
/**
 * 功能说明
 *
 * @param 参数名    参数说明
 * @param 参数名    参数说明
 * @param 参数名    参数说明
 * @return 返回值说明
 */
```

### 语法

私有变量以下划线_开头

```typescript
private _index = -1;
```

`import`导入时，需顶格,使用`{}`引用模块时,`{}`中前后需空一格
```typescript
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { v1 as uuid } from "uuid";
import { SCanvasView, SColor, SPainter, STextAlign } from "@persagy-web/draw/lib";
</script>
```

类添加类的注释头 姓名 + 邮箱，如果多个，用逗号分割。
```javascript
/**
 * 俄罗斯方块视图
 *
 * @author 郝洁 <haojie@persagy.com>
 */

/**
 * 俄罗斯方块视图
 *
 * @author 郝建龙 <haojianlong@sagacloud.com>，郝洁 <haojie@persagy.com>
 */
```

类中的属性，方法函数添加注释，if语句，for循环需添加注释,括号前后加空格，语句结束需空一行
```typescript {23,24,26}
class TestView extends SCanvasView {
    /** 背景表示数组 */
    map: number[][] = [];
    /**
     * 构造函数
     *
     * @param id canvas DOM id
     */
    constructor(id: string) {
        super(id);
    }
}

   /**
    * 是否碰撞
    *
    * @param x     x 坐标
    * @param y     y 坐标
    * @param dir   方块变形索引
    * @return 是否碰撞
    */
    private checkKnocked(x: number, y: number, dir: number): boolean {
        for (let row = 0; row < 4; row++) { // 绘制图形行数
            for (let col = 0; col < 4; col++) { // 绘制图形列数
                // 判断是否重合，每种图形四个一组，四种变形的某种变形，不为零表示绘制（确定方块），坐标转换，背景图中绘制
                if (this.box[this.boxType * 4 + dir][row][col] != 0 && this.map[y + row][x + col] != 0) {
                    return true;
                }
            }
        }
        return false;
    }
```
```typescript {4,8}
    switch (type) { // 类型判断
            case 0:     // 空白
                break;

            case -1:    // 边界
                painter.drawRoundRect(x, y, 28, 28, 6);
                break;

            default:    // 填充
                painter.drawRoundRect(x, y, 28, 28, 6);
                break;
        }
```

```typescript {7,12}
  private remove(): void {
        // 循环行数，不包含底部填充2行
        for (let row = 0; row < 20; row++) {
            for (let col = 2; col < 12; col++) {
             // ...
            }

            if (flag) { // 标记删除
                // ...
            }
        }

        if (removeCount > 0) {   // 记录消除行数
           // ...
    }
```
