title: "常见问题解答" post_status: publish comment_status: open taxonomy: category: - gutenberg-docs post_tag: - Interactivity Api - Reference Guides - Repos


常见问题解答

Interactivity API 底层如何运作?

它的三个主要组件是:

为何选择 Preact 构建指令系统?为何不用 React 或其他 JavaScript 框架?

在前端领域(这也是交互式 API 的关注点),Preact 相较于 React 以及 Vue、Svelte 或 Solid 等其他 JavaScript 框架具有多项优势:

Gutenberg 是否会因为交互性 API 使用 Preact 而从 React 迁移到 Preact?

不会。目前没有进行这种迁移的计划。编辑器作为一个完全交互式应用程序,其需求和优势截然不同。Preact 确实提供了 @preact/compat 包,可实现与 React 生态系统的完全兼容,许多大型网络应用程序都在使用它。然而,在区块编辑器中使用 Preact 并不会像在前端的交互性 API中那样带来优势。

除了使用指令,还考虑了哪些方法?

我们考虑了许多替代方案。以下是一些方案的简要总结:

React 和其他 JavaScript 框架

首先考虑了 React,因为 Gutenberg 开发者对它很熟悉。其他流行的 JS 框架如 Svelte、Vue.js 或 Angular 也被考虑过,但它们(包括 React)都不兼容 PHP,也不支持 WordPress 钩子或国际化。

Alpine.js

Alpine.js 是一个优秀的框架,它为交互性 API 的许多功能提供了灵感。然而,它不支持其指令的服务器端渲染,而拥有一个为 WordPress 区块量身定制的类似系统则具有诸多优势。

选择 Preact 而非 Alpine.js 有多重原因,例如其更小的体积、更好的性能(尤其是在引入信号之后)、自定义指令使用 Preact 的声明式语法和工具(钩子、信号)编写、它比 Alpine.js 经过更多实战检验且拥有更大的社区。它还与 React 兼容(便于从编辑器共享客户端渲染的组件),并且为交互性 API 提供了开箱即用的最快 DOM 差异算法,包括 UI 状态保持。

此外,借助 Preact 在后台运行,交互性 API 管理着“最后一层”,因此能更好地适应 WordPress 的要求。例如,指令内部不允许使用 JavaScript 表达式,以避免安全风险并确保符合严格的安全策略,并且所有 WordPress 指令都是符合规范的 HTML 属性。

请查看 "为什么选择 Preact 而非 Alpine?" 中的讨论以了解更多信息。

原生 JavaScript

请查看下方的答案。

模板 DSL

我们也研究了创建一种用于编写交互式模板的 DSL 的可能性。用该模板 DSL 编写的代码随后将被编译成 JavaScript 和 PHP。然而,创建一个生产级的模板编译器非常复杂,需要投入大量且具有风险的工作。这种方法仍在未来的考虑之中,指令集将作为编译目标。

作为区块开发者,我为何应使用交互性 API 而非 React?

在 PHP 服务器渲染环境中,前端使用 React 无法顺畅工作。任何使用 React 渲染区块的方法都必须通过客户端 JavaScript 加载内容。如果仅在客户端渲染区块,通常会导致用户体验不佳,因为用户需要盯着空占位符和加载动画等待内容加载。

在 PHP 扩展(如 v8js)中使用 JavaScript 也是可行的,但遗憾的是 PHP 扩展不具备向后兼容性,且只能在有 PHP 备用方案时使用。

现在,虽然可以在 PHP 中服务器渲染区块,并在前端使用 React 渲染同一区块。但这会导致开发体验不佳,因为逻辑必须在 PHP 和 React 部分重复实现。不仅如此,您还可能因此暴露于 WordPress 钩子引发的隐蔽错误中!

假设安装了一个带有钩子(过滤器)的第三方插件,该钩子会修改服务器渲染的 HTML。例如,这个过滤器为您的区块 HTML 添加了一个 CSS 类。这个 CSS 类将出现在服务器渲染的标记中。但在前端,您的区块会通过 React 重新渲染,此时内容将不包含该 CSS 类,因为无法将 WordPress 钩子应用于 React 渲染的内容!

另一方面,交互性 API 专为与 WordPress 钩子完美协作而设计,因为指令会为服务器渲染的 HTML 增强行为。这也意味着它能与 WordPress 后端 API(如 i18n)开箱即用。

总结来说,使用交互性 API 而非仅使用 React 具有以下优势:

相比直接使用 jQuery 或原生 JavaScript,Interactivity API 有哪些优势?

主要区别在于 Interactivity API 是声明式和响应式的,因此编写和维护复杂的交互体验会变得容易得多。此外,它专门设计用于与区块配合工作,提供了一个标准,并带来了上述优势,如区块间通信、兼容性或客户端导航等全站功能。

最后,与 jQuery 相比,Interactivity API 运行时约为 10kb,更加轻量。实际上,WordPress 生态系统正在努力移除像 jQuery 这样的重型框架,而 Interactivity API 在这方面将有所帮助。

我需要了解 React、PHP 和这个交互性 API 吗?

如果你想使用此 API 为区块添加前端交互性,简短的回答是:需要。如果你的区块不具备交互性,区块创建流程将完全保持不变。

交互性 API 引入了一种新标准方法,旨在简化将交互行为集成到 WordPress 前端的过程。这意味着你仍然需要使用 React 来处理区块的编辑器部分。

另一方面,如果你想创建一个交互式区块,借助交互性 API,你无需处理诸如工具链、与 WordPress 的集成、区块间通信或交互部分的服务器端渲染等复杂主题。

交互性 API 能否在区块之外使用?

当然可以,它并不局限于区块。你会看到很多关于交互性 API 如何为创建交互式区块提供标准的提及,但这只是因为那是最常见的用例。更一般地说,交互性 API 标准可用于为 WordPress 任何部分的前端添加“交互行为”。

有关在区块之外使用任意 HTML 的交互性 API 的详细信息,请参阅 wp_interactivity_process_directives 函数

这是否意味着我必须将所有交互式区块迁移到此 API?

不是的。不使用交互性 API 的区块可以与使用它的区块共存。然而,如上所述,请注意使用此 API 的区块有一些好处:

使用此 API 对性能有何影响?对于非常简单的用例,是否值得加载交互性 API?

该 API 在设计时已充分考虑性能,因此不应成为问题:

它是否与核心翻译 API 兼容?

由于交互性 API 与服务器端渲染完美配合,您可以使用所有 WordPress API,包括 __()_e()。您可以用它来翻译 HTML 中的文本(像通常那样),甚至可以在服务器端使用 wp_interactivity_state() 时在 store 内部使用它。看起来可能像这样:

// render.php
wp_interactivity_state( 'favoriteMovies', array(
      "1" => array(
        "id" => "123-abc",
        "movieName" => __("someMovieName", "textdomain")
      ),
) );

目前正在开发一个与脚本模块(交互性 API 所需)兼容的翻译 API。请查看 #60234 以跟进此工作的进展。

我担心 XSS 攻击;JavaScript 能否被注入到指令中?

不能。Interactivity API 只允许将引用作为值传递给指令。这样就不需要 eval() 完整的 JavaScript 表达式,因此不可能执行 XSS 攻击。

是否支持自定义安全策略?

是的。交互性 API 不使用 eval()Function() 构造函数,因此不会违反 unsafe-eval 内容安全策略。它也被设计为可与任何自定义内容安全策略配合使用。

能否使用指令发起 AJAX/REST-API 请求?

当然可以。指令调用的操作和回调函数能够执行任何 JavaScript 函数的功能,包括发起 API 请求。