Gutenberg 渐变工具集解析:Gradients 组件的 slug/value 映射与块渐变支持实现
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
Gutenberg(WordPress 块编辑器)的Gradients组件位于 packages/block-editor/src/components/gradients,它向外暴露一组用于操作渐变(gradient)调色板的纯函数与 React Hook,是 Cover、Featured Image(特色图片)等块实现渐变背景的核心支撑。阅读本文后,你将掌握渐变数据的 slug↔value 双向转换原理、__experimentalUseGradient在真实块内的读写链路,以及 PHP 端如何为编辑器提供渐变调色板设置。
组件定位与导出入口
Gradients模块的官方定义只有一句话:"TheGradientscomponent exposes tools for working with gradients",即提供一组操作渐变的工具,而非某个具体的 UI 控件。其目录结构十分精简:
- README.md:API 文档(即本文讲解的主体);
- index.js:仅一行
export * from './use-gradient';,统一对外出口; - use-gradient.js:全部实现所在。
通过 block-editor 包的主 README 可以看出,该模块的__experimentalUseGradient、__experimentalGetGradientClass等均以__experimental前缀对外暴露,属于实验性 API——意味着其签名在后续版本中可能调整,第三方开发者在生产代码中引用时需要评估兼容性风险。
核心 API:slug 与 value 的双向转换
README 文档收录了两个纯函数,它们构成了"渐变调色板数据"与"块属性数据"之间的桥梁。理解它们之前,先明确两个概念:
- gradient value:CSS 渐变字符串,如
linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%); - gradient slug:调色板中为渐变定义的唯一标识符,如
vivid-cyan-blue-to-vivid-purple。
块属性中存储的是slug(紧凑、可移植、便于生成语义化 class),而真正渲染到样式表/CSS 变量中的是value,因此两个方向都需要转换函数。
getGradientSlugByValue:由 value 反查 slug
export function getGradientSlugByValue( gradients, value ) { const gradient = __experimentalGetGradientObjectByGradientValue( gradients, value ); return gradient && gradient.slug; }- 参数
gradients(Array):渐变调色板,元素形如{ slug: 'vivid-cyan-blue-to-vivid-purple', gradient: 'linear-gradient(...)', name: '...' }; - 参数
value(string):要反查的渐变值; - 返回值(
string):匹配项的slug;未命中时返回undefined(__experimentalGetGradientObjectByGradientValue通过gradients?.find( ( g ) => g.gradient === value )做严格相等匹配,源码见 use-gradient.js)。
典型用法:用户通过渐变选择器选中一个自定义渐变值,组件需要判断它是否命中调色板中的某个预设项——命中则存 slug,未命中则作为自定义渐变单独存储(详见下文__experimentalUseGradient)。
getGradientValueBySlug:由 slug 反查 value
export function getGradientValueBySlug( gradients, slug ) { const gradient = gradients?.find( ( g ) => g.slug === slug ); return gradient && gradient.gradient; }- 参数
gradients(Array):渐变调色板; - 参数
slug(string):渐变 slug; - 返回值(
string):对应的渐变值;未命中时返回undefined。
典型用法:块属性中已存有gradientslug,渲染时需要还原为实际 CSS 渐变值。
配套导出:__experimentalGetGradientClass
use-gradient.js还导出了一个文档中未单独列出、但被 color 块支持钩子广泛使用的工具函数:
export function __experimentalGetGradientClass( gradientSlug ) { if ( ! gradientSlug ) { return undefined; } return `has-${ gradientSlug }-gradient-background`; }它根据 slug 生成语义化 CSS 类名(如has-vivid-cyan-blue-to-vivid-purple-gradient-background),该 class 由主题或 Gutenberg 的渐变样式表提供实际background渐变声明。源码见 use-gradient.js。
__experimentalUseGradient:编辑器中读写渐变属性的 Hook
useGradient是模块中唯一的 React Hook(以__experimentalUseGradient导出),它把「从全局设置读取调色板」「从块属性读取当前渐变」「写入属性」三件事封装成一个易于消费的接口。
数据来源:三源合并的渐变调色板
Hook 通过useSettings同时订阅三类来源的渐变设置(源码见 use-gradient.js):
const [ userGradientPalette, themeGradientPalette, defaultGradientPalette, ] = useSettings( 'color.gradients.custom', 'color.gradients.theme', 'color.gradients.default' ); const allGradients = useMemo( () => [ ...( userGradientPalette || [] ), ...( themeGradientPalette || [] ), ...( defaultGradientPalette || [] ), ], [ userGradientPalette, themeGradientPalette, defaultGradientPalette ] );这三层来源分别对应 WordPress 主题 JSON 中的分级配置:
color.gradients.default:内核默认渐变调色板;color.gradients.theme:主题定义的渐变调色板;color.gradients.custom:用户在站点编辑器中自定义的渐变。
合并顺序为 custom → theme → default(后者兜底)。这种「多来源(multiple origins)」的设计在 block-editor 中也被useMultipleOriginColorsAndGradients组件复用以渲染完整选择器,详见 use-multiple-origin-colors-and-gradients.js(colors-gradients 目录为渐变选择 UI 的主战场)。
读写块属性:slug 与自定义渐变的双属性策略
const { gradient, customGradient } = useSelect( ( select ) => { const { getBlockAttributes } = select( blockEditorStore ); const attributes = getBlockAttributes( clientId ) || {}; return { customGradient: attributes[ customGradientAttribute ], gradient: attributes[ gradientAttribute ], }; }, [ clientId, gradientAttribute, customGradientAttribute ] );Hook 默认读取两个属性(可通过gradientAttribute/customGradientAttribute参数覆盖,默认分别为'gradient'与'customGradient'):
gradient:命中的预设渐变 slug;customGradient:未命中调色板的原始 CSS 渐变字符串。
setGradient回调(源码见 use-gradient.js)体现了完整的写入策略:
const setGradient = useCallback( ( newGradientValue ) => { const slug = getGradientSlugByValue( allGradients, newGradientValue ); if ( slug ) { updateBlockAttributes( clientId, { [ gradientAttribute ]: slug, [ customGradientAttribute ]: undefined, } ); return; } updateBlockAttributes( clientId, { [ gradientAttribute ]: undefined, [ customGradientAttribute ]: newGradientValue, } ); }, [ allGradients, clientId, updateBlockAttributes ] );即:新值能匹配到调色板中的预设项 → 存 slug、清空自定义值;匹配不到 → 清空 slug、将原始值存入 customGradient。这种"双属性"策略让预设渐变保持语义化、可主题化,而自定义渐变保留用户原始的 CSS 表达式。
返回值
Hook 最终返回三个字段:
gradientClass:由__experimentalGetGradientClass( gradient )生成的语义化 class;gradientValue:优先通过getGradientValueBySlug( allGradients, gradient )把 slug 还原为 value;否则回退为customGradient原始值;setGradient:上述写入回调。
由于 hook 内部调用useBlockEditContext()获取当前块的clientId,它只能工作于正在编辑的块上下文(如块编辑组件内部),这与getGradientValueBySlug等纯函数可在任意环境使用的特性互补。
真实落地:Cover 与 Featured Image 块的集成方式
Gradients模块并非孤立的工具代码,而是被 block-library 中的多个块深度使用,以下选取两个典型场景印证调用链。
Cover 块:编辑与保存双端使用
Cover 块的属性定义中包含gradient与customGradient两个字符串属性,并在 block supports 中开启"color": { ..., "background": false, "__experimentalSkipSerialization": [ "gradients" ] },见 block.json。在编辑端:
- edit/index.jsx 调用
const { gradientClass, gradientValue } = __experimentalUseGradient();获取当前渐变的 class 与真实值,用于渲染编辑器内的预览背景; - edit/inspector-controls.jsx 调用
const { gradientValue, setGradient } = __experimentalUseGradient();并把二者绑定到ColorGradientSettingsDropdown,用户在选择器中切换渐变时即调用setGradient写入块属性; - 保存端 save.jsx 通过
__experimentalGetGradientClass( gradient )生成has-{slug}-gradient-background类名,输出到前端 HTML。
此外 Cover 块所有历史版本的 deprecated.jsx 也都使用__experimentalGetGradientClass还原旧版本保存结构,保证迁移兼容。
Featured Image(特色图片)块:覆盖层渐变
- overlay.jsx 中
const { gradientClass, gradientValue } = __experimentalUseGradient();读取当前渐变,将其应用到图片覆盖层; - overlay-controls.jsx 别名引入
__experimentalUseGradient as useGradient,同样配合ColorGradientSettingsDropdown渲染设置 UI。
颜色块支持钩子:序列化与内联样式
Gradients的另一类消费者是 hooks/color.js 与 hooks/use-color-props.js:
- color.js 在
addSaveProps中调用__experimentalGetGradientClass( gradient )向保存元素注入渐变 class,同时通过shouldSkipSerialization控制是否跳过gradients特性的序列化(Cover 块的 block.json 正是利用这一点自行处理渐变输出); - use-color-props.js 中,当块属性携带
gradientslug 时,调用getGradientValueBySlug( gradients, gradient )将 slug 解析为真实 CSS 渐变并强制写入style.background内联样式——注释说明这是为了在主题未加载颜色样式表时,编辑器内仍能正确呈现渐变。
PHP 侧数据供给:渐变调色板如何进入编辑器
编辑器端useSettings('color.gradients.*')读取的设置,来自 PHP 端对主题 JSON 特性的展开。相关证据在 lib/block-editor-settings.php:
if ( isset( $settings['__experimentalFeatures']['color']['gradients'] ) ) { $gradients_by_origin = $settings['__experimentalFeatures']['color']['gradients']; $settings['gradients'] = $gradients_by_origin['custom'] ?? $gradients_by_origin['theme'] ?? $gradients_by_origin['default']; }可见 PHP 端按 custom → theme → default 的优先级把三级渐变调色板聚合到settings.gradients,与前端allGradients的合并策略保持一致(前端按 custom → theme → default 顺序拼接数组,PHP 则取最高优先级来源)。同时,服务端渐变支持逻辑位于 lib/block-supports/colors.php,其中$has_gradients_support = $color_support['gradients'] ?? false;判断块是否开启渐变支持,并据此注入gradient属性定义、渲染输出渐变 class。
总结与使用建议
Gradients模块提供了三层能力:
| 能力 | 导出名称 | 适用场景 |
|---|---|---|
| 纯函数:slug ↔ value 转换 | getGradientSlugByValue/getGradientValueBySlug | 任意位置解析渐变调色板数据 |
| 纯函数:生成渐变 class | __experimentalGetGradientClass | 保存端 / 块支持钩子生成has-{slug}-gradient-background |
| React Hook:读写块渐变属性 | __experimentalUseGradient | 块编辑组件内联动属性与选择器 UI |
对第三方块开发者而言,若要为自定义块接入渐变背景,可遵循 Cover 块的模式:在 block.json 中声明gradient/customGradient属性并开启color.gradients支持,然后在编辑组件内调用__experimentalUseGradient()绑定选择器 UI。需要留意的是,__experimental前缀意味着 API 仍处于实验阶段,升级 Gutenberg 版本时应对照 block-editor 包 CHANGELOG 确认签名变更。
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考