核心渲染中间件

@dojo/framework/core/vdom 模块中包含基础中间件,大多数 Dojo 应用程序都会用到。这些主要用于构建其他自定义中间件(框架提供的附加中间件就是由他们构成的),但在一般的部件开发中也偶尔会用到。

invalidator

这是最重要的中间件,在部件的失效生命周期中设置了一个钩子。调用了 invaludator() 后,会将要渲染的部件排列到下一次的渲染计划中。

API:

  1. import { invalidator } from '@dojo/framework/core/vdom';
  • invalidator()
    • 将使用的部件标记为无效,需要重新渲染。

node

支持通过节点的 key,访问部件底层的 DOM 节点。当被请求的 DOM 节点是有效的,但还不可用时,Dojo 就立刻重新渲染部件,直到 DOM 节点变为可用。

API:

  1. import { node } from '@dojo/framework/core/vdom';
  • node.get(key: string | number): HTMLElement | null
    • 根据节点的 key 属性,返回部件中指定的 DOM 元素。如果当前部件中不存在指定的 DOM 元素,则返回 null

diffProperty

通过为指定的属性注册自己的 diff 函数,以允许部件对差异检测进行细粒度控制。当尝试重新渲染部件时,框架将调用该函数,以确定是否发生了变化,从而需要进行完全的重新渲染。如果在部件的属性集里没有检测到差异,将跳过更新,并且现有的所有 DOM 节点都保持原样。

编写自定义的 diff 函数时,通常需要与 invalidator 中间件组合使用,以便需要更新部件的 DOM 节点时,将当前部件标记为无效。

diffProperty 的另一种用法是,将返回一个可供部件属性使用的值。从 callback 返回的值会替换掉对应的部件属性值。

注意: 在组合部件或中间件的生命周期中,只能为指定的属性注册一个 diff 函数,后续的调用将被忽略。渲染引擎有一套默认算法,该算法对对象和数组进行 shallow 对比,忽略函数,而对其他所有属性进行相等检查。为属性设置了自定义的 diff 函数后,将会覆盖 Dojo 默认的差异检测策略。

API:

  1. import { diffProperty } from '@dojo/framework/core/vdom';
  • diffProperty(propertyName: string, properties: () => WidgetProperties, diff: (current: WidgetProperties, next: WidgetProperties) => void | WidgetProperties[propertyName])
    • 注册指定的 diff 函数,该函数用于确定部件的 propertyName 属性的 currentnext 值之间是否存在差异。函数使用 properties 函数来确定可用的属性和回调的类型信息,包括参数和返回值。

示例:

src/customMiddleware.tsx

  1. import { create, diffProperty } from '@dojo/framework/core/vdom';
  2. const factory = create({ diffProperty }).properties<{ foo?: string }>;
  3. export const customMiddleware = factory(({ properties, middleware: { diffProperty } }) => {
  4. diffProperty('foo', properties, (current, next) => {
  5. if (!next.foo) {
  6. return 'default foo';
  7. }
  8. });
  9. // The rest of the custom middleware that defines the API
  10. });

destroy

指定一个在部件销毁时调用的函数,可以销毁占用的任何资源。

注意: 每一个组合的部件或中间件只能调用一次 destroy(),之后再调用会被忽略。对于需要在移除部件时有条件地添加执行句柄的高级方案,应该注册一个可以跟踪并迭代地销毁所有必要资源的销毁函数。

API:

  1. import { destroy } from '@dojo/framework/core/vdom';
  • destroy(destroyFunction: () => void)
    • 设置当前部件销毁时调用的 destroyFunction。设置的函数将覆盖之前为部件设置的任一销毁函数。

getRegistry

通过处理器接口(handler interface),支持访问部件自身的 Registry 实例,如果需要的话,也可以访问应用程序一级的 Registry

注意: Registry 是一个高阶概念,在编写 Dojo 应用程序时通常用不到。它主要在框架内部使用,以实现更高阶的面向用户的功能,如 Dojo store

API:

  1. import { getRegistry } from '@dojo/framework/core/vdom';
  • getRegistry(): RegistryHandler | null
    • 返回当前部件的 RegistryHandler,如果部件未完全初始化,则返回 null

defer

允许部件暂定和恢复渲染逻辑;在特定条件满足之前短路部件的渲染时也很有用。

API:

  1. import { defer } from '@dojo/framework/core/vdom';
  • defer.pause()
    • 暂停当前部件的进一步渲染,直到标记为恢复。
  • defer.resume()
    • 恢复部件的渲染。