简介
Dojo 鼓励编写简单、模块化的组件,称为 **小部件**,它们从应用程序更广泛的要求中实现单一职责。小部件旨在可组合和可重用,适用于各种场景,并且可以以响应式方式连接在一起,以满足更复杂 Web 应用程序的要求。
小部件通过从其渲染函数返回虚拟节点来描述其预期的结构表示。Dojo 的渲染系统随后在应用程序运行时处理将小部件层次结构的渲染输出持续转换为目标的、高效的 DOM 更新。
功能 | 描述 |
---|---|
响应式设计 | Dojo 小部件围绕核心响应式原则设计,以确保当状态更改在应用程序中传播时,行为可预测且一致。 |
封装的小部件 | 创建独立的、封装的小部件,这些小部件可以以各种配置连接在一起,以创建复杂而美观的用户界面。 |
DOM 抽象 | 框架提供了合适的响应式抽象,这意味着 Dojo 应用程序不需要直接与命令式 DOM 交互。 |
高效渲染 | Dojo 的渲染系统可以检测小部件层次结构中特定子树内的状态更改,从而允许在更新发生时仅高效地重新渲染应用程序中受影响的部分。 |
企业级 | 诸如国际化、本地化和主题之类的跨领域应用程序要求可以轻松添加到用户创建的小部件中。 |
基本用法
定义小部件
- 使用
create()
原语 将小部件定义为渲染函数工厂 - 返回 虚拟 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>;
});
指定小部件属性
- 通过抽象出 状态、配置和 事件处理,通过 类型化属性接口 使小部件更具可重用性
- 通过其
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>
);
});
组合小部件
- 定义小部件层次结构,这些层次结构组合在一起以实现更复杂的应用程序要求
- 为子小部件提供状态和事件处理程序 属性
- 利用
icache
中间件 来管理状态并在状态更改时使受影响的小部件失效/重新渲染
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();