### 原子化与可组合性

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

### 兼容现有区块开发工具

该API可直接与标准区块构建工具（如[`wp-scripts`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/)）配合使用。要使`wp-scripts`正确构建使用交互式API的[脚本模块](https://make.wordpress.org/core/2024/03/04/script-modules-in-6-5/)，只需在[`build`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/#build)和[`start`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/#start)脚本中使用`--experimental-modules`标志即可。

### 客户端导航

交互式API内置了为站点添加客户端导航的基础功能。此功能完全可选，但它使得在无需脱离WordPress渲染系统的情况下创建此类用户体验成为可能。

<div class="callout callout-info">
  基于交互式API的全页客户端导航仍在开发中（参见<a href="https://github.com/WordPress/gutenberg/issues/60951">#60951</a>）。但预计所有交互区块都需要使用交互式API来实现全页客户端导航。仅在此情况下，交互式API可能无法完全兼容其他库（如jQuery）。
</div>

该API还能与[视图过渡API](https://developer.chrome.com/docs/web-platform/view-transitions/)完美配合，让开发者轻松实现页面转场动画。

## 为何要建立标准？

使用交互式API的区块与使用jQuery等其他方案的交互区块可以共存，且所有功能均能正常运作。但交互式API为交互区块带来了独特优势：

- **区块间可轻松通信**：采用标准后，区块通信默认即可实现。若不同区块使用不同的前端交互方案，当由不同开发者创建区块时，跨区块通信会变得复杂且几乎无法实现
- **组合性与兼容性**：您可以组合交互区块，并将其嵌套至具有定义行为的结构中。遵循同一标准确保了它们的完全跨兼容性。若每个区块采用不同交互方案，很可能导致功能冲突
- **减少浏览器加载量**：若每个插件作者使用不同JS框架，前端将加载更多代码。统一标准可实现代码复用
- 当页面所有区块采用此标准时，**可启用全站级功能（如客户端导航）**

此外，通过建立标准，**WordPress可为开发者承担最大程度的复杂性**——系统将处理创建交互区块所需的大部分工作。

_标准所吸纳的复杂性_

<img alt="双列对比表展示有无标准时的差异。无标准时区块开发者需处理所有事项；有标准时：完全由标准处理——工具链、水合作用、与WordPress集成、交互部件服务端渲染、区块间通信、前端性能；部分由标准处理——安全性、无障碍访问、最佳实践；开发者负责——区块逻辑。无标准列中所有事项均需开发者承担" width=60% src="https://make.wordpress.core/files/2023/03/standard-graph.png">

这种复杂性吸收机制降低了对开发知识的要求，使开发者无需纠结过多技术决策。

采用标准后，从其他交互区块学习变得简单，促进了协作与代码复用。最终使开发流程更精简，对经验较少的开发者更友好。

### 向后兼容

由于交互性 API 与服务器端渲染完美配合，您可以继续使用所有 WordPress API，包括：

- **WordPress 过滤器和操作**：您可以继续使用 WordPress 钩子来修改 HTML，甚至修改指令。此外，现有钩子将按预期正常工作。
- **核心翻译 API**：例如 `__()` 和 `_e()`。您可以用它来翻译 HTML 中的文本（像往常一样），甚至可以在指令的服务器端使用这些 API。

### 可选且渐进式采用

交互性 API 流程建立在 WordPress 坚实的基础上和模式之上，推动**渐进式增强**。

例如，带有指令的块可以与其他（交互式或非交互式）块共存。这意味着如果页面上有其他使用 jQuery 等其他框架的块，所有内容都将按预期工作。

<div class="callout callout-warning">
  使用交互性 API 进行全页面客户端导航将是与其他库兼容规则的例外。详情请参阅 <a href="#客户端导航">客户端导航</a>。
</div>

### 声明式与响应式

交互性 API 遵循与其他流行 JS 框架类似的方法，通过分离状态、操作和回调并以声明方式定义它们。为什么是声明式？

声明式代码描述程序**应该做什么**，而命令式代码描述程序**应该如何做**。使用声明式方法，UI 会自动响应底层数据的变化而更新。使用命令式方法，您必须在数据每次变化时手动更新 UI。比较以下两个代码示例：

_命令式代码_

```html
<button id="toggle-button">切换元素</button>
<p>此元素现在可见！</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 = "此元素可见";
      document.body.appendChild(newElement);
    }
});
</script>
```

_声明式代码_

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

```js
// view.js 文件
 
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' => true ) ); ?>
>
  <button
    data-wp-on--click="actions.toggle"
    data-wp-bind--aria-expanded="context.isOpen"
    aria-controls="p-1"
  >
    切换
  </button>
 
  <p id="p-1" data-wp-bind--hidden="!context.isOpen">
    此元素现在可见！
  </p>
</div>
```

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

### 高性能

该 API 旨在尽可能高效：

- **指令所需的运行时代码仅约 10 KB**，并且只需为所有块加载一次。
- **脚本加载不会阻塞页面渲染**。

### 可扩展

指令可以直接从 HTML 中添加、删除或修改。例如，用户可以使用 [`render_block` 过滤器](https://developer.wordpress.org/reference/hooks/render_block/)来修改 HTML 及其行为。

# 关于交互性 API

交互性 API 是**一套基于声明式代码的[指令系统](#为什么采用指令)，用于[为区块添加前端交互功能](#api-目标)**的[标准化方案](#为什么需要标准)。

**指令通过特殊属性扩展 HTML**，告知交互性 API 为 DOM 元素附加指定行为甚至进行元素转换。若您熟悉 [Alpine.js](https://alpinejs.dev/)，会发现这是类似的实现方式，但本 API 是专为与 WordPress 无缝协作而设计的。

## API 目标

交互性 API 的主要目标是**为 Gutenberg 区块的前端交互提供标准化且简单的处理方式**。

标准化能让**开发者更轻松地创建丰富的交互式用户体验**，无论是简单的计数器或弹窗，还是更复杂的即时页面导航、即时搜索、购物车与结算功能。

目前即使不借助交互性 API，这些用户体验在技术上也能实现。但随着用户体验复杂度的提升以及区块间交互的增多，开发者构建和维护网站的难度会大幅增加。他们需要自行解决大量技术挑战。本 API 旨在为这类交互需求提供开箱即用的解决方案。

为应对这些挑战，我们为交互性 API 设定了以下要求/目标：

- **区块优先与 PHP 优先**：API 必须与 PHP 及当前区块系统良好兼容（包括在 WordPress 中被广泛使用的动态区块），必须支持服务端渲染，且服务端渲染的 HTML 与客户端水合的 HTML 必须完全一致——这对 SEO 和用户体验至关重要
- **向后兼容**：API 必须兼容 WordPress 钩子机制（例如可修改服务端渲染的 HTML），同时需支持国际化特性并与站点现有 JS 库（如 jQuery）兼容
- **可选性与渐进式采用**：延续前一点，API 必须保持可选特性，支持渐进式采用——即未使用本 API 的交互区块可与使用本 API 的区块共存
- **声明式与响应式**：API 需采用声明式代码，监听数据变化，并仅更新依赖该数据的 DOM 部分
- **高性能**：运行时必须快速轻量，以确保最佳用户体验
- **可扩展性**：如同 WordPress 始终注重扩展性，新系统必须提供扩展模式以覆盖大多数使用场景
- **原子化与可组合性**：通过小型可复用部件的组合构建复杂系统，是创建灵活可扩展解决方案的必要条件
- **兼容现有区块开发工具**：API 必须与现有区块构建工具集成，无需开发者配置额外工具

除上述要求外，在任何解决方案之上集成**客户端导航**都应简单高效。客户端导航是实现页面间跳转无需整页刷新的技术，正是网页开发者最迫切需求的用户体验之一。因此该功能必须与新系统保持兼容。

## 为什么采用指令？

指令是[对各种可行方案深度研究](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/iapi-faq/#what-approaches-have-been-considered-instead-of-using-directives)的成果。我们发现这种设计能最高效地满足需求。

### 区块优先与 PHP 友好

本 API 专为区块生态设计，并秉承 WordPress 恪守 Web 标准的历史传统。

由于指令以 HTML 属性形式存在，它们天然适合动态区块与 PHP 环境。

*动态区块示例*
```html
<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"
  >
    切换
  </button>
 
  <p id="p-1" data-wp-bind--hidden="!context.isOpen">
    此元素现已可见！
  </p>
</div>
```

如您所见，[`data-wp-on--click`](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#wp-on) 或 [`data-wp-bind--hidden`](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#wp-bind) 等指令以自定义 HTML 属性形式添加。WordPress 可在服务端处理此 HTML，执行指令逻辑并生成对应标记。