从本文开始将逐步介绍 NG-NEST UI 库的项目源码结构和组件是如何设计制做的。css
经过如下命令来下载 ng-nest 源码:html
$ git clone https://github.com/NG-NEST/ng-nest.git $ cd ng-nest $ npm install
| 文件夹名称 | 说明 | | docs | 非组件文档,项目简介、快速上手、教程等 | | lib | 组件文件夹,包含框架组件源码 | | scripts | ts 脚本,主要用来生成文档页面组件以及相关的路由配置 | | src | 文档项目,生成的文档会自动放到 src/main/docs 下 |
... "scripts": { "ng": "ng", "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", // 加快 ngcc 编译 "start": "ng serve", // 启动文档项目 "start:en": "ng serve --configuration=en", "start:zh": "ng serve --configuration=zh", "build": "node --max_old_space_size=81920 ./node_modules/@angular/cli/bin/ng build --prod ", // 打包文档项目 "build:en": "ng build --prod --configuration=production-en", "build:zh": "ng build --prod --configuration=production-zh", "build:ng-nest-ui": "node --max_old_space_size=81920 ./node_modules/@angular/cli/bin/ng build ng-nest-ui --prod && npm run build:scss", // 打包组件库并拷贝相关scss样式文件 "build:docs": "npm run build:scripts && node ./scripts/build/generate/docs", // 生成文档页面 "build:scripts": "tsc -p scripts", // ts 脚本编译成 js "build:scss": "cpx ./lib/ng-nest/ui/style/**/* ./dist/ng-nest/ui/style", // 拷贝组件库样式文件 "test": "ng test ng-nest-site", // 测试文档项目 "test:ng-nest-ui": "ng test ng-nest-ui", // 组件测试,经过此处开发测试单个组件 "lint": "ng lint", "e2e": "ng e2e", "extract": "ng xi18n --output-path=locale" // 文档项目的本地化配置 }, ...
咱们以 Button 组件来介绍一下组件的结构,全部组件的结构都是遵循此格式。node
lib/ng-nest/ui/button ├── examples 示例代码,组件的示例说明经过此处生成 ├── style 样式 @mixin 和 样式参数定义 ├── button.component.html ├── button.component.scss ├── button.component.spec.ts 测试文件,测试模式下直接访问对应的关键子调试单个组件 ├── button.component.ts ├── button.module.ts 组件模块,声明模块中的视图,依赖的模块,以及导出的视图 ├── button.property.ts 组件属性( Input 输入和 Ouput 输出参数),以及相关的类型定义,文档中的组件参数说明经过此处生成 ├── buttons.component.scss ├── buttons.component.ts ├── index.ts ├── package.json ng-packagr 配置,单独引入组件 ├── public-api.ts 导出全部当前组件中的 class 文件 └── readme.md 组件文件以及API
lib/ng-nest/ui/core 文件夹主要用来定义公共的函数、接口、动画、服务等,如Checkbox 组件中的 checkbox.property.ts:css3
... /** * Checkbox Property */ @Component({ template: '' }) export class XCheckboxProperty extends XControlValueAccessor<boolean | Array<any>> implements XCheckboxOption { /** * 多选框数据 */ @Input() @XDataConvert() data: XData<XCheckboxNode> = []; /** * 按钮样式 */ @Input() @XInputBoolean() button: XBoolean; ... }
XControlValueAccessor 是一个表单的抽象泛型类,boolean | Array<any> 表示控件 ngModel 中绑定的值多是 boolean(data为单个值)或者 Array 数组(data为多个值),其中还定义了表单通用属性以及方法,并实现了 Angular 中作自定义表单控件须要的接口ControlValueAccessor :git
export abstract class XControlValueAccessor<T> extends XFormProp implements ControlValueAccessor { ... value: T; onChange: (value: T) => void; onTouched: () => void; writeValue(value: T): void { this.value = value; } registerOnChange(fn: (value: T) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(disabled: boolean) { this.disabled = disabled; } ... }
data 属性前面的 @XDataConvert() 是一个数据转换的装饰器,Checkbox 的选项数据能够支持如下任意一种格式(最终都被转换成统一的格式):github
dataOne = ['QQ', '微信', '钉钉', '微博']; dataTwo = ['QQ', '微信', { label: '钉钉', disabled: true }, '微博']; dataThree = [ { label: 'QQ', icon: 'ado-qq' }, { label: '微信', icon: 'ado-wechat' }, { label: '钉钉', icon: 'ado-dingding' }, { label: '微博', icon: 'ado-weibo' } ]; dataFour = new Observable((x) => { // 替换成http请求,或者data直接定义成 Observable 对象 x.next(['QQ', '微信', '钉钉', '微博']); x.complete(); });
data 属性的类型 XData<XCheckboxNode> 是一个联合类型,经过 XData<T>来定义:npm
// 数据类型 export type XData<T> = T[] | Observable<T[] | any[]> | any[] | Function;
button 属性前面的 @XInputBoolean() 装饰器主要是使组件支持如下的写法,能够省略传入true 值(写了属性,没有传入值默认转换成 true):json
<x-checkbox [data]="data" button></x-checkbox>
Core 文件夹里面还封装了 Angular 官方的 HttpClient 请求、路由复用的配置、localStorage 和 sessionStorage 服务、树结构的类型定义等等。api
lib/ng-nest/ui/style 定义公共的 @mixin 和参数,并把 css3 中的 var 参数关联到 scss 的变量中,而后各个组件的 style 文件样式中调用。数组
经过以上内容咱们对整个项目有了一个大体的了解,因为单个组件的内容是集中的,模板、示例、样式、配置、测试、文档等,咱们能够很容易的处理组件问题。以后会逐步从简单的组件切入,带领你们去体验如何设计制做组件。