gutenbergdocs/docs/reference-guides/block-api/block-context.md
2025-10-22 01:40:18 +08:00

168 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 上下文
区块上下文是一项功能,允许祖先区块提供可供其自身层次结构内的后代区块使用的值。这些后代区块可以继承这些值,而无需依赖硬编码值,也无需明确知晓提供这些值的区块。
这在全站编辑中尤其有用。例如某个区块的内容可能取决于显示它的文章上下文。博客目录模板可能显示许多不同文章的摘要。通过使用区块上下文仍然可以有一个单一的“文章摘要”区块根据继承的文章ID显示文章内容。
如果您熟悉 [React Context](https://react.dev/learn/passing-data-deeply-with-context),区块上下文采用了许多相同的理念。实际上,客户端区块编辑器对区块上下文的实现是 React Context 的一个非常简单的应用。区块上下文在服务器端 `render_callback` 实现中也受支持,如下面的示例所示。
## 定义区块上下文
区块上下文在区块的注册设置中定义。一个区块可以提供一个上下文值,或者使用它希望继承的值。
### 提供区块上下文
区块可以通过在其注册设置中分配一个 `providesContext` 属性来提供上下文值。这是一个将上下文名称映射到区块自身某个属性的对象。该属性值对应的值将提供给后代区块,并可以通过相同的上下文名称引用。目前,区块上下文仅支持源自区块自身属性的值。未来可能会增强以支持其他上下文值来源。
```js
attributes: {
recordId: {
type: 'number',
},
},
providesContext: {
'my-plugin/recordId': 'recordId',
},
```
有关完整示例,请参阅下面的部分。
#### 包含命名空间
如上例所示,建议您在上下文键的名称中包含命名空间,以避免与其他插件或 WordPress 提供的默认上下文值发生潜在冲突。上下文命名空间应特定于您的插件,并且在大多数情况下可以与区块本身的名称相同。
### 使用区块上下文
区块可以通过在其注册设置中分配一个 `usesContext` 属性来从祖先提供者继承上下文值。这应分配为区块希望继承的上下文名称数组。
```js
registerBlockType('my-plugin/record-title', {
title: 'Record Title',
category: 'widgets',
usesContext: ['my-plugin/recordId'],
```
## 使用区块上下文
一旦区块定义了它希望继承的上下文,就可以在 `edit`JavaScript`render_callback`PHP的实现中访问它。它作为上下文值的对象JavaScript或关联数组PHP提供这些值已为区块定义。请注意只有在区块明确定义了希望继承该值的情况下上下文值才会可用。
注意:区块上下文不适用于 `save`
### JavaScript
```js
registerBlockType('my-plugin/record-title', {
edit({ context }) {
return 'The record ID: ' + context['my-plugin/recordId'];
},
```
### PHP
区块的上下文值可以从 `$block` 参数的 `context` 属性中获取,该参数作为第三个参数传递给 `render_callback` 函数。
```php
register_block_type( 'my-plugin/record-title', array(
'render_callback' => function( $attributes, $content, $block ) {
return 'The current record ID is: ' . $block->context['my-plugin/recordId'];
},
) );
```
## 示例
1. 创建一个 `record` 区块。
```
npm init @wordpress/block --namespace my-plugin record
cd record
```
2. 编辑 `src/index.js`。在 `registerBlockType` 函数中插入 `recordId` 属性和 `providesContext` 属性,并在底部添加 `record-title` 区块的注册:
```js
registerBlockType( 'my-plugin/record', {
// ... 省略 ...
attributes: {
recordId: {
type: 'number',
},
},
providesContext: {
'my-plugin/recordId': 'recordId',
},
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
registerBlockType( 'my-plugin/record-title', {
title: 'Record Title',
category: 'widgets',
usesContext: [ 'my-plugin/recordId' ],
edit( { context } ) {
return 'The record ID: ' + context[ 'my-plugin/recordId' ];
},
save() {
return null;
},
} );
```
3. 编辑 `record` 区块的 `src/edit.js`。将 `Edit` 函数替换为以下代码:
```js
import { TextControl } from '@wordpress/components';
import { InnerBlocks } from '@wordpress/block-editor';
export default function Edit( props ) {
const MY_TEMPLATE = [ [ 'my-plugin/record-title', {} ] ];
const {
attributes: { recordId },
setAttributes,
} = props;
return (
<div>
<TextControl
__nextHasNoMarginBottom
__next40pxDefaultSize
label={ __( 'Record ID' ) }
value={ recordId }
onChange={ ( val ) =>
setAttributes( { recordId: Number( val ) } )
}
/>
<InnerBlocks template={ MY_TEMPLATE } templateLock="all" />
</div>
);
}
```
4. 编辑 `record` 区块的 `src/save.js`。将 `save` 函数替换为以下代码:
```js
export default function save( props ) {
return <p>The record ID: { props.attributes.recordId }</p>;
}
```
5. 创建一篇新文章并添加 `record` 区块。如果您在文本框中输入一个数字,您会看到其下方的 `record-title` 区块中显示相同的数字。
![区块上下文示例](https://user-images.githubusercontent.com/8876600/93000215-c8570380-f561-11ea-9bd0-0b2bd0ca1752.png)