一、项目结构
开发过程中涉及的主要目录及用途如下;
- tests 测试用例,其内部目录结构与src文件夹保持一致
- docs 文档
- examples 网站示例
- src 开发目录
二、规范
1. 命名
文件夹与文件
名称全部使用小写,单词或分隔使用 - 符号,测试文件需要添加 -spec 标识
示例:
- index.ts
- basic-slider.ts
- number-spec.ts 测试文件
变量
首字母小写的驼峰命名法
示例
- lowercaseVaribaleName
常量
字母全部大写,单词之间使用下划线_分隔
示例
- CONSTANT_NAME
类型与接口
驼峰命名法
示例
- TypeName
类名
驼峰命名法
示例
- ClassName
2. 编码
整体编码规范见 JavaScript 编码规范
三、开发流程
1. 开发设计文档
正式组件开发之前,需要进行充分调研,包括但不限于 1. 参考现有组件缺点 2. 吸取同类组件优点 3. 创新性特性。最终形成开发设计【文档】, 文档需包括:
- 组件简介与描述
- 设计草图
- 引用方式
- 配置项
- 配置项名称
- 类型
- 默认值(若有)
- 描述
- 事件
- 事件名称
- 事件参数
- API
- 接口名称
- 参数列表及类型
- 返回值类型
- 交互
2. 评审
形成文档后,通知专家进行评审,评审考察点包括但不限于:
- 组件必要性、可用性
- 配置项、事件、API的完整性、必要性、命名合理性
- 交互设计的可用性
待评审通过后方可进入编码阶段
3. 编码
开发组件代码位于src/ui/目录,组件需根据其名称单独创建文件夹,内部至少包含入口文件index.ts,类型定义types.ts,可根据项目需要添加常量文件constant.ts,组件工具方法文件utils.ts以及子组件文件。
示例:(Slider)
- index.ts
- types.ts
- handle.ts 子组件
类型定义
首先根据开发设计文档中的配置项在types.ts中完成类型定义,常用的类型引用
// 图形配置项import {ShapeAttrs, // 基本图形配置项类型DisplayObject, // 图形基类类型DisplayObjectConfig, // 图形配置项类型CircleProps, // 圆型配置项类型EllipseProps, // 椭圆配置项类型RectProps, // 矩形配置项类型ImageProps, // 图片配置项类型LineProps, // 线条配置项类型PathProps, // 路径配置项类型PolylineProps, // 多边形配置项类型TextProps, // 文本配置项类型Group, // 分组配置项类型} from "../../types";
对于某些在不同状态下具有不同样式的图形,使用MixAttrs<>来定义其样式属性
// 带状态的文本样式textStyle: MixAttrs<Partial<TextProps>>;// 带状态的矩形样式rectStyle?: MixAttrs<Partial<RectProps>>;// 使用textStyle:{default: {} // 默认状态active: {} // hover状态disable: {} // 禁用状态selected: {} // 选择状态}
对于一个组件,其配置项包括两个部分
- 参数配置项 以【组件名Cfg】形式命名,其需要具有基本的图形属性。需要注释各配置项的作用
- 初始化配置项 以【组件名Options】命名,并使用参数配置项作为DisplayObjectConfig的泛型 ```typescript // Button types export type ButtonCfg = { x: number; y: number; // …配置项 }
// or // export interface ButtonCfg {}
export type ButtonOptions = DisplayObject
// Legend types
export type LegendBaseCfg = ShapeAttrs & {
// …配置项
}
export type LegendBaseOptions = DisplayObjectConfig
<a name="HJZro"></a>#### 组件绘制组件所使用的子组件、图形按需引入,[@antv/g](http://g-next.antv.vision/zh/docs/api/basic/display-object)提供了基本图形,也可以先自行封装然后引入。<br />组件类需继承自GUI类,且包含**组件tag**,**配置项默认值**、**构造方法**、**初始化方法、更新方法、事件绑定,**用到的子组件需定义为**类成员变量**> 为了方便组件更新,建议使用 getter 的方式来计算出绘制每个子图形、组件的属性,然后通过subShape.attr(cfg) 的形式应用属性```typescript// 以 Button 组件为例export class Button extends GUI<Required<ButtonCfg>>{public static tag = 'button'; // tag 名称全小写,单词使用 - 分隔public static defaultOptions = {type: Button.tag,style:{// 配置项默认值}}private textShape!: Text;private backgroundShape!: Rect;private get textCfg() {} // 得到 textShape 配置项的 getterprivate get backgroundCfg() {} // 得到 backgroundShape 配置项的 getterconstructor(options: ButtonOptions){super(deepMix({}, Button.defaultOptions, options));// do something others}// 初始化方法public init() {}// 更新方法public update(cfg: Partial<ButtonCfg>){// 根据需要使用 cfg// this.attr(deepMix({}, this.attributes, cfg));}// 清理方法public clear() {}// 销毁方法public destory() {/*** 1. 子组件销毁 可使用 this.removeChildren(true); 方法*/}private initShape(){// 初始化 textShape backgroundShape}// 事件回调方法private eventCallback = (event) => {}// 绑定事件private bindEvents() {}}
常用库方法
import {clone, // 深度拷贝clamp,deepMix, // 递归合并两个Objectpick, // 从Object中根据name挑选值throttle, // 节流get, // 从Object中根据name获得值min,max,minBy,maxBy,isArray,isElement,isFunction,isNumber,isString,isUndefined,} from "@antv/util";
3. 测试
使用jest框架进行单元测试,测试范围包括但不限于
- 子组件位置是否正确
- 样式是否生效
- 交互是否正常
- 事件能否触发
- 生命周期流程是否正常
- 方法输出是否正确
4. 使用文档
使用文档需包含
- 组件名称及介绍
- 引用方法
- 配置项名称、描述、类型及默认值
5. 网站示例
创建美观的组件示例,尽可能展现组件的各个形态与能力
6. 提交代码
提交代码前需通过ci,具体操作
npm run ci
