於洋的dojo2學習筆記(4.建立widgets)
小目標
今天我們學習如何建立自定義的小部件
建立widgets
建立一個根節點
在於洋的dojo2學習筆記(2.第一個dojo應用)中,我們建立了一個單節點應用,建立了Biz-E-Bodies檢視,這一章,我們要擴充套件一下,增加名字和畫像,虛構的Biz-E-Bodies下的工人.在此之前,我們需要做一些重構.我們的應用現在是硬編碼渲染widget的.名稱變為了更適合的Banner,在main.ts中:
import { ProjectorMixin } from '@dojo/framework/widget-core/mixins/Projector'; import Banner from './widgets/Banner'; const root = document.querySelector('my-app') || undefined; const Projector = ProjectorMixin(Banner); const projector = new Projector(); projector.append(root);
這行程式碼:const Projector = ProjectorMixin(Banner);告訴應用使用Banner作為vdom的原始碼去渲染,為了加入另一個widget,我們建立另外的widget稱之為app,用來代表整個應用.在src/widgets中開啟空的App.ts.首先,我們需要加入約束依賴去建立app的widget
在檔案頭部加入
import { WidgetBase } from '@dojo/framework/widget-core/WidgetBase'; import { v, w } from '@dojo/framework/widget-core/d';
WidgetBase類作為appwidget的基類,WidgetBase(和其子類)使用WidgetProperties介面來定義widget的公共方法,最後,v()和w()方法被用來渲染virtual DOM(以後簡稱vdom)節點,或widgets. vdom和widget節點根本上產生了Dnodes(dojo中所有vdom的基類)
下一個需要建立的是Banner元件,這元件我們在第一課建立.
為了實現這一點,在App.ts中加入以下程式碼
import Banner from './Banner';
所有依賴就位,我們修改App
加入下面的類定義
export default class App extends WidgetBase {
}
注意App
類擴充套件了 WidgetBase,成為了泛型類並實現了
WidgetProperties的介面.這使得我們的類有了一些希望在dojo中實現的屬性和方法.在class之前加入了export
和default的關鍵字.這是標準的es6建立模組方法,也是dojo建立widget的手段.這個widget應作為預設的輸出物使得其易於使用.
我們使用了一個簡單的
render方法,並將其加入app類
protected render() {
return v('div');
}
這個方法會建立一個div虛擬節點並且沒有子節點,為了把Banner渲染為div的子節點,我們使用w()函式來渲染widget.
將render更新:
protected render() {
return v('div', [
w(Banner, {})
]);
}
強制物件屬性
w()函式的第二入參是必須的,即使沒有需要傳入的東西.這是為了確保正確的型別守護
w函式有兩個入參,widget物件和物件字面量.通過TypeScript generics,字面量必須實現傳入WidgetBase的介面,這種情況Banner使用WidgetProperties,並有下面的定義
export interface WidgetProperties {
key?: string;
}
key是可選的,這裡我們傳入空,接下來會把Banner替換為app,做為我們應用的根
把app部件作為應用的根
把Banner替換為app
我們的App已經建立好了,可以替換Banner類作為應用的根,為了實現這一點,我們編輯main.ts
import從Banner換為app
import App from './widgets/App';
唯一要做的是在line6,把 App 傳入 ProjectorMixin 函式
const Projector = ProjectorMixin(App);
做好以上幾部,App部件就準備好作為應用的根來提供服務了,
下面測試一下:
如果是在本地環境,執行以下命令
dojo build -m dev -w memory -s
接著開啟http://localhost:9999,可以看到
Banner的<h1>tag被App的<div>包裹,一切都正常