翻譯 https://github.com/dojo/framework/blob/master/docs/en/creating-widgets/introduction.md
Dojo 鼓勵編寫簡單的、模塊化組件,並稱之爲部件,它僅實現應用程序大量需求中的單一職責。部件被設計成可在各種場景中組合和複用,能以響應的方式連接在一起,以滿足更復雜的 web 應用程序需求。
部件使用渲染函數返回的虛擬節點描述其預期的結構。然後,在應用程序運行時,Dojo 的渲染系統會持續地將部件每一層渲染的內容轉換爲對應的、高效的 DOM 更新。
功能 | 描述 |
---|---|
響應式設計 | Dojo 部件是圍繞響應式的核心原則設計的,這樣在應用程序中傳播變化的狀態時,就可以確保可預見的、一致的行爲。 |
封裝部件 | 創建獨立、封裝的部件,這些部件可通過各種配置組合在一起,從而創建出複雜且漂亮的用戶界面。 |
DOM 抽象 | 框架提供了恰當的抽象,這意味着 Dojo 應用程序不需要直接與命令式 DOM 打交道。 |
高效渲染 | Dojo 的渲染系統可以檢測出部件層次結構中特定子節點的狀態變化,這樣當更新發生時,只需要高效的重新渲染應用程序中受影響的部分。 |
企業級 | 跨領域的應用程序需求,如國際化、本地化和樣式主題,可以輕鬆地添加到用戶創建的部件中。 |
基本用法
定義部件
- 使用 內置的
create()
將部件定義爲一個渲染函數 factory - 返回定義了部件結構的 虛擬 DOM 節點,這裏使用 TSX 語法
src/widgets/MyWidget.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
const factory = create();
export default factory(function MyWidget() {
return <div>Hello from a Dojo widget!</div>;
});
設置部件屬性
- 爲了使部件能更好的複用,需要使用類型化的屬性接口來抽象出 state, 配置和事件處理函數
- 使用
create
工廠爲部件提供中間件 - 通過爲節點指定
key
屬性,來區分同一類型的兄弟元素,此示例中是兩個div
元素。這樣當應用程序中的狀態發生變化,需要更新 DOM 節點時,框架就可以高效、準確地定位到相關元素
src/widgets/Greeter.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
const factory = create({ icache }).properties<{
name: string;
onNameChange?(newName: string): void;
}>();
export default factory(function Greeter({ middleware: { icache }, properties }) {
const { name, onNameChange } = properties();
let newName = icache.get<string>('new-name') || '';
return (
<div>
<div key="appBanner">Welcome to a Dojo application!</div>
{name && <div key="nameBanner">Hello, {name}!</div>}
<label for="nameEntry">What's your name?</label>
<input
id="nameEntry"
type="text"
value={newName}
oninput={(e: Event) => {
icache.set('new-name', (e.target as HTMLInputElement).value);
}}
/>
<button
onclick={() => {
icache.set('new-name', undefined);
onNameChange && onNameChange(newName);
}}
>
Set my name
</button>
</div>
);
});
組合部件
- 通過將部件組合在一起形成多層結構,以滿足更復雜的應用程序需求
- 爲子部件提供 state 和事件處理函數等屬性(properties)
- 使用
icache
中間件管理 state,並當狀態變更時,失效或重新渲染受影響的部件
src/widgets/NameHandler.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import Greeter from './Greeter';
const factory = create({ icache });
export default factory(function NameHandler({ middleware: { icache } }) {
let currentName = icache.get<string>('current-name') || '';
return (
<Greeter
name={currentName}
onNameChange={(newName) => {
icache.set('current-name', newName);
}}
/>
);
});
渲染到 DOM 中
- 使用框架中的
renderer
函數將部件掛載到 DOM 中 - 也可以對 Dojo 應用程序在頁面中呈現的位置做更多控制,以便穩步地採用較小的子組件,甚至支持一個頁面中存在多個應用程序或框架
src/main.tsx
import renderer, { tsx } from '@dojo/framework/core/vdom';
import NameHandler from './widgets/NameHandler';
const r = renderer(() => <NameHandler />);
r.mount();