從本文開始將逐步介紹 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 文件樣式中調用。數組
經過以上內容咱們對整個項目有了一個大體的瞭解,因爲單個組件的內容是集中的,模板、示例、樣式、配置、測試、文檔等,咱們能夠很容易的處理組件問題。以後會逐步從簡單的組件切入,帶領你們去體驗如何設計製做組件。