Interactivity API 是一套基于声明式代码的标准指令系统,用于为区块添加前端交互性。

指令通过特殊属性扩展 HTML,告知 Interactivity API 将指定行为附加到 DOM 元素上,甚至对其进行转换。对于熟悉 Alpine.js 的人来说,这是一种类似的方法,但它是专门为与 WordPress 无缝协作而设计的。

API 目标

Interactivity API 的主要目标是提供一种标准和简单的方式来处理 Gutenberg 区块的前端交互性。

标准化使得开发人员能够更轻松地创建丰富的交互式用户体验,从简单的计数器或弹出窗口等场景,到更复杂的功能如即时页面导航、即时搜索或购物车和结账流程。

所有这些用户体验在技术上目前无需 Interactivity API 即可实现。然而,用户体验越复杂,区块之间的交互越多,开发人员构建和维护站点就越困难。他们必须自行解决许多挑战。该 API 旨在提供开箱即用的手段来支持这类交互。

为了解决这一挑战,定义了以下 Interactivity API 的需求/目标:

  • 区块优先且 PHP 优先:API 必须与 PHP 和当前的区块系统(包括在 WordPress 中广泛使用的动态区块)良好配合工作。它必须支持服务器端渲染。服务器渲染的 HTML 和客户端水合(hydrate)的 HTML 必须完全相同。这对 SEO 和用户体验至关重要。
  • 向后兼容:API 必须与 WordPress 钩子兼容,这些钩子可能会修改服务器渲染的 HTML。它还必须与国际化工具以及站点上现有的 JS 库(如 jQuery)兼容。
  • 可选且逐步采用:与前一点相关,API 必须保持可选。应该能够逐步采用它,这意味着不使用此 API 的交互式区块可以与使用它的区块共存。
  • 声明式和响应式:API 必须使用声明式代码,监听数据的变化,并仅更新依赖于该数据的 DOM 部分。
  • 高性能:运行时必须快速且轻量,以确保最佳的用户体验。
  • 可扩展:正如 WordPress 专注于可扩展性一样,这个新系统必须提供可扩展的模式以覆盖大多数用例。
  • 原子化和可组合:拥有可重用的小部分并将其组合以创建更复杂的系统是创建灵活且可扩展解决方案所必需的。
  • 与现有区块开发工具兼容:API 必须与现有的区块构建工具集成,而无需开发人员额外的工具或配置。

除了所有这些要求之外,在任何解决方案之上集成客户端导航应该是容易且高性能的。客户端导航是在不重新加载整个页面的情况下在网站页面之间导航的过程,这是 Web 开发人员最引人注目的用户体验之一。因此,此功能应与这个新系统兼容。

为什么是指令?

指令是对不同可能性和方法进行深入研究的结果。我们发现这种设计最能有效地满足需求。

区块优先且对 PHP 友好

API 是为区块世界设计的,并深刻理解了 WordPress 紧密依附于 Web 标准的历史。

由于指令是 HTML 属性,它们非常适合动态区块和 PHP。

动态区块示例

<div
  data-wp-interactive="wpmovies"
  <?php echo wp_interactivity_data_wp_context( array( 'isOpen' => false ) ); ?>
  data-wp-watch="callbacks.logIsOpen"
>
  <button
    data-wp-on--click="actions.toggle"
    data-wp-bind--aria-expanded="context.isOpen"
    aria-controls="p-1"
  >
    Toggle
  </button>

  <p id="p-1" data-wp-bind--hidden="!context.isOpen">
    This element is now visible!
  </p>
</div>

如您所见,data-wp-on--click 或 data-wp-bind--hidden 等指令作为自定义 HTML 属性添加。WordPress 可以在服务器上处理此 HTML,处理指令的逻辑并创建适当的标记。

向后兼容

由于 Interactivity API 与服务器端渲染完美配合,您可以使用所有 WordPress API,包括:

  • WordPress 过滤器和操作:您可以继续使用 WordPress 钩子来修改 HTML 甚至修改指令。此外,现有钩子将继续按预期工作。
  • 核心翻译 API:例如 __() 和 _e()。您可以使用它将 HTML 中的文本翻译成您通常的做法,甚至可以在指令的服务器端使用这些 API。

可选且逐步采用

Interactivity API 管道通过在 WordPress 坚实的基础和模式之上构建来促进渐进增强。

例如,带有指令的区块可以与其他(交互式或非交互式)区块共存。这意味着如果页面上有其他使用 jQuery 等其他框架的区块,一切都将按预期工作。

使用 Interactivity API 进行全页客户端导航将是此与其他库兼容性规则的例外。有关更多详细信息,请参阅 客户端导航。

声明式和响应式

Interactivity API 遵循与其他流行 JS 框架类似的方法,分离状态、操作和回调并以声明方式定义它们。为什么要声明式地定义?

声明式代码描述程序应该做什么,而命令式代码描述程序应该如何做。使用声明式方法,UI 会根据底层数据的变化自动更新。使用命令式方法,每当数据发生变化时,您都必须手动更新 UI。比较两个代码示例:

命令式代码

<button id="toggle-button">Toggle Element</button>
<p>This element is now visible!</p>
<script>
    const button = document.getElementById( 'toggle-button' );

    button.addEventListener( 'click', () => {
        const element = document.getElementById( 'element' );
        if ( element ) {
            element.remove();
        } else {
            const newElement = document.createElement( 'p' );
            newElement.textContent = 'This element is visible';
            document.body.appendChild( newElement );
        }
    } );
</script>

声明式代码

这是上面共享的相同用例,但用作使用此新系统的声明式代码示例。JavaScript 逻辑定义在区块的 view.js 文件中,并在 render.php 中将指令添加到标记中。

// view.js file

import { store, getContext } from '@wordpress/interactivity';

store( 'wpmovies', {
    actions: {
        toggle: () => {
            const context = getContext();
            context.isOpen = ! context.isOpen;
        },
    },
} );
<?php // render.php ?>

<div
  data-wp-interactive="wpmovies"
  <?php echo wp_interactivity_data_wp_context( array( 'isOpen' => false ) ); ?>
>
  <button
    data-wp-on--click="actions.toggle"
    data-wp-bind--aria-expanded="context.isOpen"
    aria-controls="p-1"
  >
    Toggle
  </button>

  <p id="p-1" data-wp-bind--hidden="!context.isOpen">
    This element is now visible!
  </p>
</div>

在创建简单的用户体验时,使用命令式代码可能更容易,但随着应用程序变得越来越复杂,它会变得更加困难。Interactivity API 必须涵盖所有用例,从最简单到最具挑战性。这就是为什么使用指令的声明式方法更适合 Interactivity API 的原因。

高性能

API 的设计尽可能高效:

  • 指令所需的运行时代码仅为 ~10 KB,并且只需为所有区块加载一次。
  • 脚本将在不阻塞页面渲染的情况下加载。

可扩展

指令可以直接从 HTML 中添加、删除或修改。例如,用户可以使用 render_block 过滤器 来修改 HTML 及其行为。

原子化和可组合

每个指令控制 DOM 的一小部分,您可以组合多个指令以创建丰富的交互式用户体验。

与现有的块开发工具兼容

该 API 可与标准的块构建工具(如 wp-scripts)开箱即用。wp-scripts 使用 Interactivity API 正确构建 Script Modules 的唯一要求是,在 build 和 start 脚本中使用 –experimental-modules 标志。

客户端导航

Interactivity API 内置了用于向站点添加客户端导航的原语。此功能完全是可选的,但它为创建此类用户体验提供了可能性,而无需放弃 WordPress 渲染系统。

请访问 客户端导航 指南,了解有关如何使用 Interactivity Router 并在块中实现客户端导航的更多信息。

为什么需要标准?

使用 Interactivity API 的块和使用 jQuery 等其他方法的交互式块可以共存,并且一切都能按预期工作。然而,Interactivity API 为您的交互式块带来了一些好处:

  • 块之间可以轻松通信。通过标准,这种通信默认由系统处理。当不同的块使用不同的前端交互方法时,块间通信会变得复杂,如果由不同的开发者创建块,则几乎不可能实现。
  • 可组合性和兼容性:您可以组合交互式块,并将它们嵌套在具有定义行为的结构中。由于遵循相同的标准,它们完全跨兼容。如果每个块都使用不同的交互方法,它们可能会破坏。
  • 发送到浏览器的 KB 数量更少。如果每个插件作者都使用不同的 JS 框架,前端将加载更多代码。如果所有块都使用同一个框架,代码将被复用。
  • 如果页面上的所有块都使用此标准,则可以启用站点范围的客户端导航等功能。

此外,通过采用标准,WordPress 可以从开发者处吸收最大量的复杂性,因为它将处理创建交互式块所需的大部分工作。

由标准吸收的复杂性

两列表格比较有无标准的一些方面。在没有标准的情况下,块开发者必须处理所有事情,而在有标准的情况下:工具、水合、与 WordPress 集成、交互式部分的 SSR、块间通信和前端性能完全由标准处理;安全性、无障碍性和最佳实践部分处理;开发者负责:块逻辑。在没有标准的列中,所有内容均由开发者负责。

通过这种吸收,创建交互式块所需的知识更少,开发者需要担心的决策也更少。

通过采用标准,从其他交互式块中学习变得更容易,并促进了协作和代码复用。结果是开发过程更精简,对经验较少的开发者也更友好。