Gutenberg 渐变工具集解析:Gradients 组件的 slug/value 映射与块渐变支持实现
2026/9/17 3:27:28 网站建设 项目流程

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; }
  • 参数gradientsArray):渐变调色板,元素形如{ slug: 'vivid-cyan-blue-to-vivid-purple', gradient: 'linear-gradient(...)', name: '...' }
  • 参数valuestring):要反查的渐变值;
  • 返回值(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; }
  • 参数gradientsArray):渐变调色板;
  • 参数slugstring):渐变 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 块的属性定义中包含gradientcustomGradient两个字符串属性,并在 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询