WebApp【公共组件库】@前端(For Git Submodule)
edit | blame | history | raw

开发规范

规范宗旨

代码首先是给人读的,其次才是给机器运行,所以让代码容易阅读是应尽的责任

除了尽可能不写难懂的代码外,我们还需要尽量遵守统一的规范,来帮助我们更高效率的相互阅读代码

命名问题

命名需要具有实义

命名的核心原则是名称含有具体的实体含义

比如没有实义的

const onClick = () => null; // 不好的命名

因为 click 可以发生在任何元素上,从这个名称上无法分辨业务种类,所以我们认为这个函数名没有实义,需要改进一下:

const onProductSelected = () => null; // 良好的命名 

改进后,从函数名一看便知,这是商品被选中了以后的需要进行的操作,又因为具备了在同一个页面的唯一性,能帮我们快速获取信息,知道这是哪个业务的哪个环节,大幅提高阅读效率,这就是实义

文件命名

常用文件命名约定

界面层文件

界面层文件(.vue、.scss),采用小驼峰命名

index.vue
index.scss

数据控制层文件

数据控制层文件(.js),以固定前缀 P 开头,再接大驼峰

PIndex.js

数据层代码定义的名称,需要和文件名一致

export class PIndex extends Pilot {}

组件文件

不论是公共组件还是页面子组件(.vue、.scss),都以固定前缀 C 开头,再接大驼峰

CMenu.vue
CMenu.scss

组件代码定义的名称,需要和文件名一致

// CMenu.vue 的组件名,必须是 CMenu
export default {
    name: 'CMenu',
}

请求文件

请求层文件(.js),以固定前缀 F 开头,再接大驼峰

FCommon.js

请求集合的代码定义名称,需要和文件名一致

// FCommon.js 的类名称,必须是 FCommon
class FCommon extends Fetcher {}

// FCommon.js 代表的类的实例名称,则是 $fetchCommon
export const $fetchCommon = new FCommon();

样式命名

样式名的命名,采用横杠连接

.page-name {}

界面样式

任何一个界面必定包含众多样式,所以:

  • 最父级样式名固定,与界面名称一直
  • 中间层,需要以父级为前缀,接板块说明
  • 末端则可单名,且尽量不含实义
/** 在界面 userList.vue 中,最父级样式名名称固定 **/
.user-list {

    /** 中间多层,以父级为前缀 **/
    .user-list-title {

        /** 末端可单名,尽量非实义 **/
        .left,
        .text,
        .icon,
        .sub,
        .close {}
    }
}

组件样式

组件样式名必须已 c- 开头,最父级样式名必须与组件名挂钩

例如,组件 CMenu.vue 中,最父级样式名必须是:

.c-menu {}

JS 变量和属性的命名

使用小驼峰,注意不能以动词开头

// 变量
const name = '';
const orderList = '';
// 属性
const user = {
    name: '',
    lastOrder: '',
};

变量命名的特别约定

变量名允许 is 开头
变量名不能用动词开头,但是允许 is 作为特例

// 允许 is 开头的变量名
let isOpened = false;

事件变量用 evt
事件 event 的简写,必须是 evt(不能用单字母 e )

<view @tap="evt => onOrderClick(evt)"></view>
<CMenu :onClick="evt => onMenuItemClick(evt)" />

报错信息用 err
报错 error 的简写,必须是 err(不能用单字母 e )

Taro.request({
    fail: err => {},
});

后端数据 res
后端返回数据,优先采用 resource 的简写 res

$fetch.getEquipments().then(res => {});

JS 方法的命名

在数据控制层

提供给界面层使用的方法,用 on 开头

// 数据控制层定义
onOpenOrderDetail() {}
// 界面层使用
<view class="order-item" @tap="evt => onOpenOrderDetail()">

数据层自用的方法,用下划线开头

// 数据控制层定义
_checkOrderDetailOpened() {}

onOpenOrderDetail() {
    // 数据控制层内部自用
    this._checkOrderDetailOpened();
}

在组件内

接收父级方法的时候,用 on 开头

export default {
    props: {
        // 选择会员后的回调
        onUserSelected: Function,
    },
}

组件自身模版绑定的时候,用 handle 开头

export default {
    methods: {
        // 组件层定义
        handleUserSelected() {}
    }
}
// 组件层自身模板绑定
<view class="user-item" @tap="evt => handleUserSelected()">

函数相互调用的时候,用下划线开头

export default {
    methods: {
        // 组件层定义
        _checkUser() {},
        handleUserSelected() {
            // 组件层内部自用
            this._checkUser()
        }
    }
}

给父级ref的引用进行调用的方法,使用 $ 开头

export default {
    methods: {
        // 组件层定义
        $close() {}
    }
}

父级

<CUserDetail ref="userDetail">
onCloseAll() {
    // 父级 ref 调用
    this.$refs.userDetail.$close()
}

书写问题

书写规则都由编辑器自动格式化即可,这里主要说明非格式化的几点约定

JS 中的书写

变量定义符

弃用 var ,改用 constlet ,且优先使用 const ,除非要改值

const name = 'Tevin';
let count = 0;
count++;

注意,const 定义的对象,其属性是可以改值的

const search = {
    count: 1
};
search.count++; // 允许运行
search = {}; // 报错

所以:
* 对于普通数据,如果明确要变更变量值,才使用 let
* 对于引用数据,如果明确需要重新赋值一个引用对象,才使用 let

模版中的函数调用

模版中调用函数,必须显式的书写 evt 变量和箭头函数,即: evt => fncName()
我们把 Taro 自身组件视为普通元素,元素绑定事件使用 @tap 的方式,非元素皆是组件,组件使用 :onClick 的方式绑定

例如:
html <view @tap="() => onOpenOrderDetail()"></view> <CMenu :onItemClick="evt => onMenuItemClick(evt)" />

CSS 属性顺序

为了避免 css 属性写重复,请按如下顺序书写:

  • 文档流属性
    display, position, float, clear, visibility, table-layout 等

  • 大小属性
    width, height, margin, padding 等

  • 文字排版属性
    font, line-height, text-align, text-indent, vertical-align 等

  • 装饰性属性
    color, background, border, opacity, shadow, cursor 等

  • 生成内容属性
    content, list-style, quotes 等

  • 二次渲染属性
    zoom, transform 等

  • 动画属性
    transition, animation 等