交互API為開發人員提供了一種向其塊前端添加交互的標準方法。
該標準旨在使開發人員更輕松地創建豐富的交互式用戶體驗,從計數器或彈出窗口等簡單情況到即時頁面導航、即時搜索、購物車或結帳等更復雜的功能。
塊可以在它們之間共享數據、操作和回調。這使得塊之間的通信更加簡單并且不易出錯。例如,單擊“添加到購物車”塊可以無縫更新單獨的“購物車”塊。
為了更好地理解其背后的原因,您可以查看原始提案,其中有更詳細的解釋。
有關它的更多信息可以在合并公告、狀態更新帖子和交互 API 的Trac 票證中找到。
本開發說明涵蓋了 6.5 中包含的 API 以及如何使用交互 API。
如何使用交互 API 創建交互
需要強調的是,區塊創建*工作流程***不會改變**。
到目前為止,WordPress 一直有意對區塊前端使用的不同解決方案不發表意見。交互 API 改變了這一點。它添加了一種新的標準方法,可以輕松地將前端交互性添加到塊,同時處理塊編輯器的 API 保持不變。
您首先需要通過在文件中的supports內添加交互屬性來聲明其與API的兼容性block.json:
"supports": {
"interactivity": true
},
請參閱塊編輯器手冊以獲取支持屬性的更詳細說明interactivity。
交互 API 腳本需要使用WordPress 6.5 中的新腳本模塊,因此塊應使用 viewScriptModule將JavaScript排入隊列:
// block.json
{
...
"viewScriptModule": "file:./view.js"
}
您可以按照本快速入門指南輕松構建和測試交互式塊,該指南解釋了如何使用CLI**命令來加速此過程。
考慮到這一點,為了向由交互 API 提供支持的塊添加交互性,開發人員需要:
- 向標記添加指令以向塊添加特定交互。
- 使用交互邏輯(狀態、操作或回調)創建存儲。
我們用一個簡單的例子來解釋一下:一個顯示和隱藏一些文本的按鈕。當按鈕隱藏或顯示時,我們還可以在控制臺中發送一條消息。
1. 添加指令
指令是添加到塊標記中的自定義屬性,以向其 DOM 元素添加交互。它們被放置在 render.php 文件中(對于動態塊)。
第一步是添加指令data-wp-interactive。這用于“激活” DOM 元素及其子元素中的交互 API,其值必須是插件或塊的唯一命名空間:
<div data-wp-interactive="myPlugin">
<!-- Interactivity API zone -->
</div>
其余指令可以添加所需的交互。
// render.php
$context = array('isOpen' => false);
<div
<?php echo get_block_wrapper_attributes(); ?>
<?php echo wp_interactivity_data_wp_context($context) ?>
data-wp-interactive='myPlugin'
data-wp-watch="callbacks.logIsOpen"
>
<button
data-wp-on--click="actions.toggle"
data-wp-bind--aria-expanded="context.isOpen"
>
Toggle
</button>
<p id="p-1" data-wp-bind--hidden="!context.isOpen">
This element is now visible!
</p>
</div>
此外,還可以使用HTML 標簽處理器動態注入指令。
如果您還不明白它是如何工作的,請不要擔心。到目前為止,重要的部分是上面的示例使用wp-on和等指令向HTMLwp-bind添加交互性。這是 WordPress 6.5 中可用的指令列表:
您可以在相關鏈接中找到每個指令的更深入解釋以及如何使用它的示例。
- wp-interactive:此屬性必須設置為您的插件或塊的唯一標識符,以便它使用交互 API。
- wp-context:它提供了特定 HTML 節點及其子節點可用的本地狀態。它接受字符串化的JSON作為值。推薦使用PHP
wp_interactivity_data_wp_context()來設置。 - wp-bind:它允許基于布爾值或字符串值在元素上設置 HTML 屬性。它遵循語法
data-wp-bind--[attribute]。(喜歡data-wp-bind--value) - wp-class:它根據布爾值向 HTML 元素添加或刪除類。它遵循語法
data-wp-class--[classname]。 - wp-style:它根據其值向 HTML 元素添加或刪除內聯樣式。它遵循語法
data-wp-style--[css-property]. - wp-text:它設置 HTML 元素的內部文本。它只接受字符串作為參數。
- wp-on:它在調度的 DOM 事件(例如單擊或 keyup)上運行代碼。它的語法是
data-wp-on--[event](如data-wp-on--click或data-wp-on--keyup)。 - wp-watch :它在創建節點時運行回調,并在狀態或上下文更改時再次運行它。
- wp-init :僅在創建節點時運行回調。
- wp-run :它在節點渲染執行期間運行傳遞的回調。
- wp-key:它為元素分配一個唯一的鍵,以幫助交互 API 在迭代元素數組時識別它。
- wp-each:旨在呈現元素列表。
- wp-each-child:確保水合按預期工作,在 wp-each 指令的服務器處理中自動添加。
2. 創建商店
存儲用于創建將指令與該邏輯內使用的數據鏈接起來的邏輯。
所有存儲都由唯一的命名空間引用,分離邏輯并避免不同存儲屬性和函數之間的名稱沖突。
如果使用相同的命名空間定義了多個存儲,它們將被合并到一個存儲中。
存儲通常在每個塊的 view.js 文件中創建,盡管狀態可以在后端初始化,例如在塊的渲染文件中。
狀態是一個全局對象,可用于頁面的所有 HTML 節點。它是由store()函數定義的。如果您只需要節點及其子節點的本地狀態,請檢查上下文定義。
該對象可以接受任何屬性,為了保持項目之間的一致性,建議使用此約定。
-
State
:定義頁面 HTML 節點可用的數據。該州內的房產將在全球范圍內開放。如果您需要編輯它們,推薦的方法是使用 getter。
- 派生狀態。如果您需要任何狀態屬性的修改版本,建議使用getter方法(下面將詳細介紹如何導出狀態)。
-
操作:通常由指令觸發
data-wp-on(使用事件偵聽器)。 -
回調:自動對狀態變化做出反應。通常由
data-wp-on-window,data-wp-on-document或data-wp-init指令觸發。
回到我們的示例,這可能是一個塊中的簡單存儲,已添加全局狀態以獲得存儲外觀的完整示例。
// view.js
import { store, getContext } from "@wordpress/interactivity";
const { state } = store( 'myPlugin', {
state: {
likes: 0,
getDoubleLikes() {
return 2 * state.likes;
}
},
actions: {
toggle: () => {
const context = getContext();
context.isOpen = !context.isOpen;
},
},
callbacks: {
logIsOpen: () => {
const context = getContext();
// Log the value of `isOpen` each time it changes.
console.log(`Is open: ${context.isOpen}`);
},
},
});
在某些情況下,商店中可能只定義了操作和回調。
DOM 元素通過指令連接到存儲在狀態和上下文中的數據。如果狀態或上下文更改指令中的數據將對這些更改做出反應,則會相應地更新 DOM(參見圖表)。

創建商店時,有一些重要事項需要注意:
使用派生狀態
派生狀態使用getter返回狀態的計算版本。它可以訪問狀態和上下文。
// view.js
const { state } = store( "myPlugin", {
state: {
amount: 34,
defaultCurrency: 'EUR',
currencyExchange: {
USD: 1.1,
GBP: 0.85,
},
get amountInUSD() {
return state.currencyExchange[ 'USD' ] * state.amount,
},
get amountInGBP() {
return state.currencyExchange[ 'GBP' ] * state.amount,
},
},
} );
通過解構**訪問存儲**
存儲包含所有存儲屬性,例如狀態、操作或回調。它們由store()調用返回,因此您可以通過解構它們來訪問它們:
const { state, actions, callbacks } = store( "myPlugin", {
// ...
} );
請注意,上下文不是存儲的一部分,而是通過getContext函數訪問的。
如果您想更深入地了解該函數的工作原理,請隨時查看此處的store()函數文檔。
異步操作
異步操作應該使用生成器函數而不是 async/await 或 Promise。交互 API 需要能夠跟蹤異步行為,以便恢復正確的范圍。否則,getContext如果與異步操作同時更新,則可能會返回過時的值。不用等待承諾,而是從生成器函數中生成它,并且交互 API 將處理等待其完成的情況。
所以,而不是:
store("myPlugin", {
state: {
get isOpen() {
return getContext().isOpen;
},
},
actions: {
someAction: async () => {
state.isOpen; // This is the expected context.
await longDelay();
state.isOpen; // This may not get the proper context unless it's properly restored.
},
},
});
function longDelay() {
return new Promise( ( resolve ) => {
setTimeout( () => resolve(), 3_000 );
} );
}
商店應該是:
store("myPlugin", {
state: {
get isOpen() {
return getContext().isOpen;
},
},
actions: {
someAction: function* () {
state.isOpen; // This is the expected context.
yield longDelay(); // With generators, the caller controls when to resume this function.
state.isOpen; // This context is correct because the scope was restored before resuming after the yield.
},
},
});
如果您想更深入地了解該示例,請查看api 參考。
使用其他命名空間
交互塊可以在它們之間共享數據,除非它們是私有存儲。
指令
為了訪問指令中不同命名空間的存儲,請在指令值之前添加命名空間。例如:
<!-- This accesses the current store -->
<div data-wp-class--is-hidden="state.isHidden"></div>
<!-- This accesses the "otherPlugin" store -->
<button data-wp-on--click="otherPlugin::actions.addToCart>Button</button>
語境
可以通過提供所需的命名空間作為參數來訪問來自不同命名空間的上下文getContext( namespace ):
import { getContext } from "@wordpress/interactivity";
const otherPluginContext = getContext( "otherPlugin" );
店鋪
與上下文一樣,可以通過將所需的命名空間作為參數傳遞來訪問不同的存儲:
const { state: otherState, actions: otherActions } = store( "otherPlugin" );
私人商店
可以“鎖定”存儲以防止從其他名稱空間訪問其內容。為此,請在 store() 調用中將 lock 選項設置為 true,如下例所示。設置鎖后,具有相同鎖定命名空間的 store() 后續執行將引發錯誤,這意味著該命名空間只能在第一次 store() 調用返回其引用的位置進行訪問。這對于想要隱藏部分插件存儲以使擴展程序無法訪問的開發人員特別有用。
const { state } = store("myPlugin/private", {
state: {
messages: [ "private message" ]
}
},
{ lock: true }
);
// The following call throws an Error!
store( "myPlugin/private", { /* store part */ } );
還有一種方法可以解鎖私有存儲:您可以使用字符串作為鎖定值,而不是傳遞布爾值。然后可以在對同一名稱空間的后續 store() 調用中使用這樣的字符串來解鎖其內容。只有帶有鎖定字符串的代碼才能訪問受保護的存儲區。這對于跨多個文件定義的復雜存儲非常有用。
const { state } = store("myPlugin/private", {
state: {
messages: [ "private message" ]
}
},
{ lock: PRIVATE_LOCK }
);
// The following call works as expected.
store( "myPlugin/private", { /* store part */ }, { lock: PRIVATE_LOCK } );
交互 API 客戶端方法
以下方法適用于 JavaScript,由 WordPress 6.5 中提供的 wordpress/interactivity 腳本模塊提供。
獲取上下文()
data-wp-context可以使用 getContext 函數檢索使用該屬性定義的上下文:
const { state } = store( "myPlugin", {
actions: {
someAction() {
const context = getContext();
const otherPluginContext = getContext( 'otherPlugin' );
// ...
}
}
} );
手冊說明。
獲取元素()
檢索正在評估存儲中的函數的元素的表示。該表示形式是只讀的,并且包含對 DOM 元素及其屬性的引用。
手冊說明。
獲取配置()
通過函數檢索先前在服務器中定義的配置對象wp_interactivity_config()。
配置在客戶端上是不可變的,無法修改。您可以在本文檔后面獲取示例。
店鋪()
創建用于將數據和操作與其各自的指令鏈接起來的存儲。查看主要部分以獲取更多信息。
withScope()
操作可以取決于調用它們時的范圍,例如,當您調用getContext()或時getElement()。
當交互 API 運行時執行回調時,范圍會自動設置。但是,如果您從運行時未執行的回調中調用操作(例如在回調中)setInterval(),則需要確保正確設置范圍。使用該withScope()函數可確保在這些情況下正確設置范圍。
一個示例,如果actions.nextImage沒有包裝器,將觸發未定義的錯誤:
store('mySliderPlugin', {
callbacks: {
initSlideShow: () => {
setInterval(
withScope( () => {
actions.nextImage();
} ),
3_000
);
}
},
})
交互API服務器功能
這些是交互 API 包含的 PHP 函數:
wp_interactivity_state( $store_namespace, $state )
它用于初始化服務器上的狀態并確保其發送的 HTML 與客戶端 Hydration 后的 HTML 相同。它還允許您使用任何 WordPress API,例如核心翻譯。
// render.php
wp_interactivity_state( "movies", array(
"1" => array(
"id" => "123-abc",
"movieName" => __("someMovieName", "textdomain")
),
) );
它接收兩個參數,一個帶有將用作引用的名稱空間的字符串和一個包含值的關聯數組。
此函數中定義的狀態將與 view.js 文件中定義的存儲合并。
wp_interactivity_data_wp_context( $context, $ *store_namespace* )
生成一個data-wp-context準備好在服務器端呈現的屬性。除了手動寫入 JSON 字符串時可能出現的任何錯誤之外,此函數會對數組進行轉義以防止外部攻擊。
$context是一個包含上下文的鍵和值的數組。
$*store_namespace*允許引用不同的存儲,默認為空。
<?php
$context = array(
'id' => $post_id,
'show' => true,
);
?>
<div <?php echo wp_interactivity_data_wp_context($context) ?> >
My interactive div
</div>
將返回
<div data-wp-context="{ "id": 1, "show": "true" } ">
My interactive div
</div>
wp_interactivity_config( $store_namespace, $config )
設置或獲取交互存儲的配置。客戶端可以讀取配置的不可變副本。
將配置視為可以影響整個站點并且不會在客戶端交互時更新的全局設置。例如,確定站點是否可以處理客戶端導航。
<?php
// Sets configuration for the 'myPlugin' namespace.
wp_interactivity_config( 'myPlugin', array( 'setting' => true ) );
// Gets the current configuration for the 'myPlugin' namespace.
$config = wp_interactivity_config( 'myPlugin' );
可以在客戶端中檢索此配置:
// view.js
const { setting } = getConfig();
console.log( setting ); // Will log true.
wp_interactivity_process_directives( $html )
處理 HTML 內容中的指令,并在必要時更新標記。
這是交互 API 的核心功能。它是公開的,因此可以處理任何 HTML,而不僅僅是塊。
For 帶有supports.interactivity,指令的塊會被自動處理。在這種情況下,開發人員不需要調用wp_interactivity_process_directives。
<?php
$html_content = '<div data-wp-text="myPlugin::state.message"></div>';
wp_interactivity_state( 'myPlugin', array( 'message' => 'hello world!' ) );
// Process directives in HTML content.
$processed_html = wp_interactivity_process_directives( $html_content );
// output: <div data-wp-text="myPlugin::state.message">hello world!</div>





