Angular 組件庫 NG-NEST 源碼解析:項目結構

前言

從本文開始將逐步介紹 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 下 |

package.json 文件中的 scripts 說明

...
"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

Core 文件夾

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

Style 文件夾

lib/ng-nest/ui/style 定義公共的 @mixin 和參數,並把 css3 中的 var 參數關聯到 scss 的變量中,而後各個組件的 style 文件樣式中調用。數組

總結

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

相關文章
相關標籤/搜索