社区新闻

在区块中按下回车键时会发生一些非常酷的事情

查看官方原文 ↗ 发布于

当你在编辑器中编写列表时,按下回车键,就会自动得到另一个项目符号!

你是否曾想过这是如何发生的?你是否希望让你自己的区块也能实现类似的功能,而不仅仅是列表项?

这正是本文要帮助你的地方。如果你之前写过一些区块,可能会更容易理解。

通常会发生三件事。

当你在编辑一个 Gutenberg 区块时,按下回车键通常会发生以下三件事之一:

  1. 创建一个与你刚刚编写的区块相匹配的新区块。
  2. 添加一个换行符。
  3. 或者添加一个新段落,因为段落是默认区块。

当你通过按回车键来获得一个新区块时,你正在使用 Gutenberg 的 RichText 组件。文档以及撰写 WordPress 相关内容的人将这种行为称为拆分。在区块末尾按回车键会添加一个新区块,而在区块中间按回车键会将其一分为二。

你需要使用两个函数来实现拆分,但还有第三个函数可以让用户撤销拆分,这非常方便。这被称为合并

  • onSplit – 用于创建新区块(必需)
  • onReplace – 用于添加新区块 – (必需)。区块通常应该已经将此作为 prop 接收,通常提供此默认值就足够了。
  • onMerge – 用于将区块粘合在一起(可选)。区块通常应该已经接收一个 mergeBlocks prop,可以使用它。

你可以将这些函数作为props传递给 RichText 组件。

onSplit

onSplit 接收被拆分的值部分,以及该部分是否位于原始区块之后(即,用户是否要在内容开头按回车键)。它应该返回一个新区块,该函数将被调用两次,每次针对拆分后的一个部分。

给定一个字符串 “Test”:

  • 在开头按回车键意味着 onSplit 将在第一次调用时产生 ''false,然后在第二次调用时产生 "Test"true
  • 在中间按回车键意味着 onSplit 将在第一次调用时获得 'Te'true,然后在第二次调用时获得 'st'false
  • 在末尾按回车键意味着 onSplit 将在第一次调用时获得 'Test'true,然后在第二次调用时获得 ''false

在所有情况下,给定的值都应该返回一个区块。因此,一个典型的实现将位于区块编辑组件内部,看起来像这样:

<RichText
	onSplit={ ( value, isAfterOriginal ) => 
		createBlock( 'block/name', { ...attributes, text: value } );
	}
/>

attributes 是传入编辑组件的 attributes prop。

onReplace

onReplace 接收一个数组,该数组包含从 onSplit 返回的区块。它还接收要选择的索引和初始位置。

它不应该返回任何内容;它应该将区块添加到编辑器中。一个简单的实现将位于区块编辑组件内部,看起来像这样:

<RichText
	onReplace={ ( blocks, indexToSelect, initialPosition ) =>
		replaceBlocks( clientId, blocks, indexToSelect, initialPosition );
	}
/>

其中 replaceBlocks 来自 block-editor storeclientId 是当前区块的 clientId

默认的 onReplace prop 的功能与上述类似。除非你需要完全不同的东西,否则不妨将其设置为 RichText prop,而无需重新发明轮子。

onMerge

onMerge 捕获合并的方向。与 onReplace 一样,它也不应该返回任何内容。相反,它应该只是在编辑器中找到你想要合并的区块——然后将它们合并。

你的区块应该已经接收一个 mergeBlocks prop。你当然可以使用它。但请注意,你最终会调用区块的 merge 函数,该函数将传递你想要合并的两个区块的属性。因此,你需要在区块的 index.js 文件中分配区块的 merge 函数。这通常如下所示:

( firstAttribs, secondAttribs ) => { ...firstAttribs, text: firstAttribs.text + secondAttribs.text }

扩展阅读

  • 我在研究这个问题时发现两个有用的区块:list-item 区块button 区块。它们为我提供了在现实世界中使用所有三个函数的可靠示例。
  • 你可能想看看 onSplitonReplace 在上下文中是如何被调用的。查看 rich-text/split-value.js 如何调用 `onSplit`,以及 rich-text/index.js 如何调用 onMerge
  • 你会发现,传递给区块的默认 onMerge prop 的大部分逻辑都位于 mergeBlocks 内部。