首页
/ Ant Design Image 组件完全指南:加载占位、容错回退与可定制图片预览(Preview)

Ant Design Image 组件完全指南:加载占位、容错回退与可定制图片预览(Preview)

2026-09-07 11:56:55作者:冯爽妲Honey

作为一套面向企业级应用的前端组件库,antd 的 Image 组件承担着"展示可预览图片"这一基础而高频的职责:它不止是 <img> 标签的封装,还内置了渐进式加载占位、加载失败容错、单图/多图全屏预览(支持缩放、旋转、拖拽、翻转)以及语义化 DOM 定制等一整套图片交互能力。本篇指南将完全围绕 components/image/index.en-US.md 展开,从基础用法到 placeholder/fallback 两种加载策略,再到 previewImage.PreviewGroup 的全部配置项、受控预览、工具栏与预览内容自定义,最后结合 Image 组件的源码结构(入口、hooks、Progress 渲染层)与语义化 DOM 深入剖析其内部原理,帮助你在实际项目中按需选用每一份能力。

使用场景(When To Use)

按照官方文档的定位,Image 适合在两类场景中使用:

  • 需要展示图片时,使用基础形态的 <Image />,它具备优雅的悬浮遮罩与点击预览能力;
  • 大图加载或加载失败容错场景,例如需要展示"加载进度/渐变占位",或希望在图片资源出错时优雅降级,而不是出现破碎的图标。

从实现上看,Image 组件在 index.tsx 中对 @rc-component/image 做了二次封装:统一前缀 class、合并 ConfigProvider 的上下文配置、接入语义化 classNames/styles 与组件 Token,并扩展了 placeholder(进度占位)与 cover(悬浮预览遮罩)等上层能力。

快速上手:从一张图到一组图

最简单的用法只需要 srcwidth 与描述性 alt 即可(参见 demo/basic.tsx):

import React from 'react';
import { Image } from 'antd';

const App: React.FC = () => (
  <Image
    width={200}
    alt="basic"
    src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
  />
);

export default App;

默认情况下,鼠标悬浮在图片上会显示一层"眼睛"样式的预览遮罩(cover),点击后即进入全屏 Preview。当多张图片需要联动预览(左右切换、显示总数与当前序号)时,使用 Image.PreviewGroup 包裹即可(参见 demo/preview-group.tsx):

import React from 'react';
import { Image } from 'antd';

const App: React.FC = () => (
  <Image.PreviewGroup
    preview={{
      onChange: (current, prev) => console.log(`current index: ${current}, prev index: ${prev}`),
    }}
  >
    <Image width={200} alt="svg image" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
    <Image width={200} alt="svg image" src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg" />
  </Image.PreviewGroup>
);

Image.PreviewGroupPreviewGroup.tsx 中被实现为 InternalPreviewGroup,并通过 Image.PreviewGroup = PreviewGroup 挂载到 Image 上(index.tsx)。预览的旋转/缩放/翻转等默认图标(icons)也定义在此文件内,且它会根据 ConfigProvider 的 direction 自动在 RTL 模式下对调左右切换箭头。

加载体验优化:placeholder 与渐进式加载

文档明确指出 placeholder 有双重能力:既可以渲染 ReactNode,也可以传配置对象来控制进度 UI。对应地,placeholder 的 Type 为 ReactNode | { progress?: boolean | ImageProgressConfig }

ReactNode 形式的占位

直接把任意 ReactNode 传给 placeholder,图片加载期间就会渲染该节点。官方示例 demo/placeholder.tsx 展示了把一张半透明模糊层作为占位的方式:

<Image
  width={200}
  height={200}
  src="...原图URL..."
  placeholder={
    <div
      style={{
        width: '100%',
        height: '100%',
        background: 'rgba(255, 255, 255, 0.3)',
        backdropFilter: 'blur(10px)',
      }}
    />
  }
/>

进度型占位(Progress Placeholder)

当希望模仿"AI 生图 / 大图渐进加载"这类带进度反馈的场景时,改用配置对象:

  • placeholder={{ progress: true }}:显示带有水彩墨迹流动动画的渐变占位,不展示百分比;
  • placeholder={{ progress: { percent: 50 } }}:显示当前进度条与 50% 文本;
  • placeholder={{ progress: { percent, render } }}:用 render 自定义整个进度内容的展示。

一个完整的"生成式加载"示例(改写自官方 demo)长这样:

const [percent, setPercent] = useState(0);

<Image
  width={200}
  height={200}
  placeholder={{
    progress: {
      percent: Math.round(percent),
      render: (progress, p) => (
        <>
          {progress}
          <div style={{ marginTop: 8 }}>Generating {p}%</div>
        </>
      ),
    },
  }}
/>

render 的函数签名为 (progress: React.ReactNode, percent: number) => React.ReactNode:第一个参数是内置的进度条 UI,第二个参数是当前百分比,你可以自由组合。

源码级原理解析:配置化与 ReactNode 两种形态的区分,由 hooks/usePlaceholderConfig.ts 中的 isPlaceholderConfig 完成——只有"普通对象且不是合法 React 元素"才会被当作进度配置解析。真正的进度渲染层在 Progress.tsx

  • 当传入有限数值 percent 时,进度条宽度通过 CSS 变量 --progress-percent 驱动,并把数值收敛在 0–100 之间;
  • 无百分比(仅开启动画)时,会输出 role="status" aria-live="polite" 的隐藏区域(内容为 "Loading"),同时根节点带 aria-busy,为屏幕阅读器提供加载状态;
  • 两个 .progress-ink-* 墨迹层 + 伪元素共叠加出 5 层水彩流光动画,其关键帧动画定义在 style/progressAnimation.ts
  • 动画时长由组件 Token progressAnimationDuration 控制(默认 3s,见 style/index.ts)。

值得注意的边界行为(见 index.tsx):当 placeholder 是 ReactNode 且未提供 src 时,该占位会被当作覆盖层渲染(shouldRenderPlaceholderOverlay),因为此时底层 rc-image 会把空 src 判为 error 状态;只有提供进度配置或正常 src 时才走常规图片流程。

加载失败容错:fallback

src 加载失败时,fallback 会指定一张替代图。官方示例 demo/fallback.tsx 直接把 src 指向无效地址 "error",并传入一张 base64 内嵌图作为兜底:

<Image
  alt="basic image"
  width={200}
  height={200}
  src="error"
  fallback="data:image/png;base64,iVBORw0KGgo..." // 加载失败时展示的兜底 URL
/>

fallback 也支持通过 ConfigProvider 做全局配置(自 5.28.0 起),在 index.tsx 中通过 mergedFallback = fallback ?? contextFallback 实现"组件级优先、上下文兜底"的合并逻辑。失败时触发的 onError 回调可用于埋点或自定义后续处理。

预览功能全解:preview 配置与受控预览

单图预览

默认 previewtrue(点击放大)。设置 preview={false} 即关闭预览。传对象时则进行精细定制,例如官方示例 demo/controlled-preview.tsx 展示的完全受控预览——预览的开关由外部 state 驱动:

const [open, setOpen] = useState(false);
const [scaleStep, setScaleStep] = useState(0.5);

<Button type="primary" onClick={() => setOpen(true)}>show image preview</Button>

<Image
  width={200}
  style={{ display: 'none' }} // 原图隐藏仅作为预览入口
  alt="basic image"
  src="...缩略图URL..."
  preview={{
    open,
    scaleStep,
    src: '...高清大图URL...',   // 预览时使用的大图与缩略图分离
    onOpenChange: (value) => setOpen(value),
  }}
/>

自定义预览大图(thumbnail → HD)

缩略图与预览大图分离是相册类产品非常实用的能力。官方示例 demo/previewSrc.tsx 中,展示的 src 是一张经过模糊/压缩的缩略图(URL 上带 blurresize 处理参数),而 preview.src 指向原图:

<Image
  width={200}
  alt="basic image"
  src="...?x-oss-process=image/blur,r_50,s_50/quality,q_1/resize,m_mfit,h_200,w_200" // 列表中的小图
  preview={{
    src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', // 预览大图
  }}
/>

这个模式在"列表缩略、点击看原图"的典型场景中,既能保证首屏性能,又不牺牲预览清晰度。

从任意一张图进入组预览

多图联动不只局限于 JSX 包裹这一种形式。demo/preview-group-visible.tsx 演示了先给 Image.PreviewGroup 配置 items(图片数组),再通过某个 Image 直接进入组预览。此外 PreviewGroupitems 还支持 { src: string, crossOrigin: string, ... } 形式以携带额外属性。

预览中的操作能力

进入 Preview 全屏浮层后,默认支持:放大/缩小(步进为 1 + scaleStep)、向左/向右旋转、水平/垂直翻转、大图拖拽(movable)、鼠标滚轮缩放(wheel,6.6.0 起)、双击放大、复位与关闭。各项能力均有对应开关与上下限:

  • maxScale 最大缩放倍数,默认 50
  • minScale 最小缩放倍数,默认 1
  • scaleStep 缩放步进因子,默认 0.5,即每次缩放为上一状态的 1 + 0.5 = 1.5 倍;
  • movable 图片大于视口时是否可拖拽,默认 true
  • wheel 是否开启滚轮缩放,默认 true(6.6.0 引入);
  • focusTrap 打开预览时是否将焦点圈定在预览内部,默认 true(6.4.0 引入,配合无障碍键盘浏览)。

打开/切换/变换回调

Preview 体系提供了三类关键回调:

回调 说明 适用组件
onOpenChange(visible) 预览开关状态变化时触发 Image / PreviewGroup
onChange(current, prevCurrent) 切换预览图片时触发(携带当前索引与上一次索引) PreviewGroup
onTransform({ transform, action }) 预览发生任何变换(缩放/旋转/翻转/拖拽/复位等)时触发 Image / PreviewGroup

其中 onTransformactiontransform 分别由 TransformActionTransformType 描述(见下文 Interface 小节),你既可以用它来做"当前是滚轮缩放还是按钮缩放"的区分,也可以据此同步外部的自定义工具栏状态。注意 PreviewGroup 的 onOpenChange 额外携带当前索引:(visible, info: { current }) => void

工具栏与预览内容自定义

actionsRender:替换整条操作栏

从 5.x 开始官方推荐使用 actionsRender(取代已废弃的 toolbarRender)接管预览底部操作栏。回调签名(即 ToolbarRenderInfoType)如下:

(originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode

ToolbarRenderInfoType 中包含默认图标集合 icons(翻转、旋转、缩放、关闭图标),以及可直接调用的动作集合 actions

{
  icons: {
    flipYIcon: React.ReactNode; flipXIcon: React.ReactNode;
    rotateLeftIcon: React.ReactNode; rotateRightIcon: React.ReactNode;
    zoomOutIcon: React.ReactNode; zoomInIcon: React.ReactNode;
  };
  actions: {
    onActive?: (index: number) => void; // support after 5.21.0
    onFlipY: () => void; onFlipX: () => void;
    onRotateLeft: () => void; onRotateRight: () => void;
    onZoomOut: () => void; onZoomIn: () => void;
    onReset: () => void; // support after 5.17.3
    onClose: () => void;
  };
  transform: TransformType;
  current: number;
  total: number;
  image: ImgInfo;
}

注意:Image 与 PreviewGroup 的 actionsRender 签名在 info 上略有差异,PreviewGroup 场景下 current/total 才真正有意义。对应 demo 为 demo/toolbarRender.tsx(组件内 toolbarRender 的旧用法会自动转换为 actionsRender,见 hooks/usePreviewConfig.ts)。

imageRender:替换预览主体内容

若不想用默认的 <img> 展示,可通过 imageRender 自定义预览内容(例如叠加自定义绘制、水印或形状处理)。单图场景签名:

(originalNode: React.ReactElement, info: { transform: TransformType; image: ImgInfo }) => React.ReactNode

PreviewGroup 场景下 info 中额外携带 current。对应 demo:demo/imageRender.tsx

cover / mask:悬浮遮罩与预览遮罩

文档对遮罩体系做了清晰划分,且在 6.0 之后有明显演进:

  • preview.cover(6.0 起支持配置对象):自定义"点击进入预览"的悬浮遮罩节点,即缩略图上方悬浮的提示层。可传 ReactNodeCoverConfig
    type CoverConfig = {
      coverNode?: React.ReactNode;                  // 预览遮罩的自定义节点
      placement?: 'top' | 'bottom' | 'center';      // 预览遮罩的显示位置
    };
    
    demo 参见 demo/coverPlacement.tsx(自定义放置位置)与 demo/preview-mask.tsx(自定义遮罩节点)。在 PreviewGroup.tsx 中维护了 iconscover 相关合并逻辑。
  • preview.mask(对象化):控制预览弹层自身背景遮罩的显示/模糊/点击关闭行为,类型为 boolean | { enabled?: boolean; blur?: boolean; closable?: boolean },默认 true。其中 closable(点击遮罩关闭)自 6.4.0 引入;blur 会在遮罩上叠加 backdrop-filter: blur(4px)(对应 class 见 style/index.tspreview-mask-blur)。注意:旧版把 mask 当作 ReactNode 传入的用法已被废弃,请改用 cover(源码中会发出对应 deprecation 警告)。

语义化 classNames / styles 定制

6.0.0 起,Image 全面支持 classNames/styles 两种定制方式(均可传对象或 (info: { props }) => ... 函数形式),分别注入 class 与内联样式,覆盖以下语义节点:

  • root:根元素(相对定位 + inline-block 布局);
  • image<img> 本身;
  • cover:悬浮预览提示层;
  • placeholder.progress:进度占位内部结构(root/content/rail/indicator,由 Progress.tsx 定义 ProgressClassNames/ProgressStyles);
  • popup.*:预览弹层内部结构,包括 popup.rootpopup.maskpopup.bodypopup.footerpopup.actionspopup.close(6.4.0 起)。

语义结构演示见 demo/_semantic.tsx,配套测试在 semantic.test.tsx。在实现上,index.tsx 借助 useMergeSemanticcontextClassNames/contextStyles(来自 ConfigProvider 组件级配置)、props 上的 classNames/styles 以及旧版遗留的 wrapperStyle/rootClassName/maskClassName 合并归一,其中 popup._default 指向 root,使得旧写法能平滑迁移。

其他预览配置

  • closeIcon:自定义关闭按钮(ConfigProvider 全局配置自 5.14.0 支持);
  • getContainer:指定预览浮层挂载的容器(默认挂到 body);传 false 表示挂载在当前图片位置。仍以全屏尺寸呈现;
  • rootClassName:预览根 DOM 类名(PreviewGroup 中已废弃,改用 classNames.root);
  • countRender:仅在 PreviewGroup 中存在,用于自定义 (current, total) 计数展示。

全局统一配置(ConfigProvider)

Image 是一个支持 ConfigProvider 组件级全局配置 的组件:fallback(5.28.0 起)、preview.closeIcon(5.14.0 起)、preview.mask(6.0.0 起)、preview.mask.closable(6.4.0 起)均可下沉到 ConfigProvider,通过一次配置全局生效(上述 API 表格中标注 Global Config 的列)。例如给全站图片统一兜底图:

import { ConfigProvider, Image } from 'antd';

<ConfigProvider
  image={{ fallback: 'https://example.com/placeholder.png' }}
>
  {/* 内部所有 Image 加载失败均展示 fallback */}
</ConfigProvider>

index.tsx 中通过 useComponentConfig('image') 读取该上下文,并将其中的 previewfallbackclassNamesstyles 与组件 props 做合并(合并逻辑集中在 hooks/useMergedPreviewConfig.ts,其中还包括 z-index 自动递增、遮罩 blur 状态与 getContainer 兜底等细节)。

图片 API 参考

通用属性可参考 Common props;其余透传属性遵循原生 <img>(如 crossOriginloading 等)。

Image

Property Description Type Default Version Global Config
alt Image description string - ×
classNames Customize class for each semantic structure inside the component. Supports object or function. Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 6.0.0
fallback Fallback URL when load fails string - 5.28.0
height Image height string | number - ×
placeholder Loading placeholder, supports ReactNode or config object PlaceholderType - ×
preview Preview configuration; set to false to disable boolean | PreviewType true preview.closeIcon: 5.14.0, preview.mask: 6.0.0, preview.mask.closable: 6.4.0
src Image URL string - ×
styles Customize inline style for each semantic structure inside the component. Supports object or function. Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 6.0.0
width Image width string | number - ×
onError Callback when loading error occurs (event: Event) => void - ×

PlaceholderType

Property Description Type Default Version
progress Progress config, set to true to show gradient animation, set { percent: number } to show progress, render for custom rendering boolean | ImageProgressConfig -

ImageProgressConfig

Property Description Type Default Version
percent Progress value number -
render Custom rendering, receives default progress UI and percentage (progress: React.ReactNode, percent: number) => React.ReactNode -

PreviewType

Property Description Type Default Version
actionsRender Custom toolbar render (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode -
closeIcon Custom close icon React.ReactNode -
cover Custom preview mask React.ReactNode | CoverConfig - CoverConfig support after v6.0
focusTrap Whether to trap focus within the preview when open boolean true 6.4.0
destroyOnClose Destroy child elements on preview close (removed, no longer supported) boolean false
forceRender Force render preview image (removed, no longer supported) boolean -
getContainer Specify container for preview mounting; still full screen; false mounts at current location string | HTMLElement | (() => HTMLElement) | false -
imageRender Custom preview content (originalNode: React.ReactElement, info: { transform: TransformType, image: ImgInfo }) => React.ReactNode -
mask preview mask effect boolean | { enabled?: boolean, blur?: boolean, closable?: boolean } true mask.closable: 6.4.0
maskClassName Thumbnail mask class name; please use 'classNames.cover' instead string -
maxScale Maximum zoom scale number 50
minScale Minimum zoom scale number 1
movable Whether the preview image can be dragged when it is larger than the viewport boolean true
open Whether to display preview boolean -
rootClassName Root DOM class name for preview; applies to both image and preview wrapper string -
scaleStep Each step's zoom multiplier is 1 + scaleStep number 0.5
src Custom preview src string -
styles Custom semantic structure styles Record<SemanticDOM, CSSProperties> -
wheel Whether to enable mouse wheel zoom boolean true 6.6.0
toolbarRender Custom toolbar; please use 'actionsRender' instead (originalNode: React.ReactElement, info: Omit<ToolbarRenderInfoType, 'current' | 'total'>) => React.ReactNode -
visible Whether to show; please use 'open' instead boolean -
onOpenChange Callback when preview open state changes (visible: boolean) => void -
onTransform Callback for preview transform changes { transform: TransformType, action: TransformAction } -
onVisibleChange Callback when 'visible' changes; please use 'onOpenChange' instead (visible: boolean, prevVisible: boolean) => void -

PreviewGroup

Property Description Type Default Version
classNames Customize class for each semantic structure inside the component. Supports object or function. Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> -
fallback Fallback URL for load error string -
items Array of preview items string[] | { src: string, crossOrigin: string, ... }[] -
preview Preview configuration; disable by setting to false boolean | PreviewGroupType true

PreviewGroupType

Property Description Type Default Version
actionsRender Custom toolbar render (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode -
closeIcon Custom close icon React.ReactNode -
countRender Custom preview count render (current: number, total: number) => React.ReactNode -
focusTrap Whether to trap focus within the preview when open boolean true 6.4.0
current Index of the current preview image number -
forceRender Force render preview image (removed, no longer supported) boolean -
getContainer Specify container for preview mounting; still full screen; false mounts at current location string | HTMLElement | (() => HTMLElement) | false -
imageRender Custom preview content (originalNode: React.ReactElement, info: { transform: TransformType, image: ImgInfo, current: number }) => React.ReactNode -
mask preview mask effect boolean | { enabled?: boolean, blur?: boolean, closable?: boolean } true mask.closable: 6.4.0
maskClassName Thumbnail mask class name; please use 'classNames.cover' instead string -
minScale Minimum zoom scale number 1
maxScale Maximum zoom scale number 50
movable Whether the preview image can be dragged when it is larger than the viewport boolean true
open Whether to display preview boolean -
rootClassName Root DOM class name for preview; applies to both image and preview wrapper. Use 'classNames.root' instead string -
styles Custom semantic structure styles Record<SemanticDOM, CSSProperties> -
wheel Whether to enable mouse wheel zoom boolean true 6.6.0
scaleStep Each step's zoom multiplier is 1 + scaleStep number 0.5
toolbarRender Custom toolbar; please use 'actionsRender' instead (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode -
visible Whether to show; please use 'open' instead boolean -
onOpenChange Callback when preview open state changes, includes current preview index (visible: boolean, info: { current: number }) => void -
onChange Callback when changing preview image (current: number, prevCurrent: number) => void -
onTransform Callback for preview transform changes { transform: TransformType, action: TransformAction } -
onVisibleChange Callback when 'visible' changes; please use 'onOpenChange' instead (visible: boolean, prevVisible: boolean, current: number) => void -

废弃 API 与迁移路线

hooks/usePreviewConfig.ts 的 dev 警告可以看出完整的迁移矩阵,开发环境下传入旧属性会输出 deprecation/breaking 警告:

  • visibleopenonVisibleChangeonOpenChange
  • toolbarRenderactionsRender
  • maskClassNameclassNames.cover
  • rootClassName(组预览)→ classNames.root
  • wrapperStylestyles.root
  • mask 传 ReactNode 的旧用法 → cover
  • forceRenderdestroyOnClose 已被移除、不再支持:预览在打开后总会渲染。

得益于 hooks/usePreviewConfig.ts 的归一化逻辑(open: open ?? visibleonOpenChange 兼容旧回调、actionsRender: actionsRender ?? toolbarRendercover ?? 旧 mask 元素),这些废弃写法在过渡期内仍可工作,方便分批升级。

Interface 定义

以下为文档定义的核心类型,均在自定义工具栏、预览内容与变换回调中直接使用。

TransformType

{
  x: number;
  y: number;
  rotate: number;
  scale: number;
  flipX: boolean;
  flipY: boolean;
}

TransformAction

type TransformAction =
  | 'flipY'
  | 'flipX'
  | 'rotateLeft'
  | 'rotateRight'
  | 'zoomIn'
  | 'zoomOut'
  | 'close'
  | 'prev'
  | 'next'
  | 'wheel'
  | 'doubleClick'
  | 'move'
  | 'dragRebound'
  | 'reset';

可以看到 onTransformaction 覆盖了按钮缩放、滚轮(wheel)、双击(doubleClick)、拖拽移动(move)乃至拖拽回弹(dragRebound)与复位(reset)等全部变换来源,方便你做数据埋点或状态同步。

ToolbarRenderInfoType

{
  icons: {
    flipYIcon: React.ReactNode;
    flipXIcon: React.ReactNode;
    rotateLeftIcon: React.ReactNode;
    rotateRightIcon: React.ReactNode;
    zoomOutIcon: React.ReactNode;
    zoomInIcon: React.ReactNode;
  };
  actions: {
    onActive?: (index: number) => void; // support after 5.21.0
    onFlipY: () => void;
    onFlipX: () => void;
    onRotateLeft: () => void;
    onRotateRight: () => void;
    onZoomOut: () => void;
    onZoomIn: () => void;
    onReset: () => void; // support after 5.17.3
    onClose: () => void;
  };
  transform: TransformType,
  current: number;
  total: number;
  image: ImgInfo
}

ImgInfo

{
  url: string;
  alt: string;
  width: string | number;
  height: string | number;
}

CoverConfig

type CoverConfig = {
  coverNode?: React.ReactNode; // The custom node of preview mask
  placement?: 'top' | 'bottom' | 'center'; // Set the position of the preview mask display.
};

Semantic DOM 与 Design Token

Image 的语义 DOM 结构与各节点职责如下(交互式演示见 demo/_semantic.tsx,完整结构映射定义在 index.tsxImageSemanticType):

语义节点 职责
root 根元素,相对定位 + inline-block 布局
image 图片元素,负责宽高与垂直对齐
cover 悬浮显示的预览提示层(绝对定位、半透明背景、hover 渐显)
placeholder.progress 进度占位内部结构(rail/indicator 等)
popup.root 预览弹层根节点(fixed 定位、z-index、遮罩与内容区)
popup.mask 预览背景遮罩(半透明底 + 可选 blur 效果)
popup.body 预览内容区(flex 居中、指针事件控制)
popup.footer 预览底部区域(计数与操作栏容器)
popup.actions 底部操作按钮组(圆角胶囊背景)
popup.close 右上角关闭按钮(6.4.0 起纳入语义节点)

Design Token 层面,Image 通过 style/index.tsprepareComponentToken 暴露了以下组件级 Token,可用 ConfigProvidertheme.components.Imagetheme 的 token 覆盖:

  • zIndexPopup:预览浮层 z-index(默认在全局 zIndexPopupBase 基础上 +80);
  • previewOperationSize:预览操作图标尺寸(默认 fontSizeIcon * 1.5);
  • previewOperationColor / previewOperationHoverColor / previewOperationColorDisabled:操作图标的常规、悬浮与禁用颜色(基于 colorTextLightSolid 透明度派生);
  • progressAnimationDuration:加载动画的基础时长(默认 3s,墨迹层动画时长在其上叠加偏移)。

对外的 classNames/styles 与 Token 覆盖、ConfigProvider 的组件级配置共同构成了三套渐进式定制体系:不换框架的全局统一(ConfigProvider)→ 语义化精确打点(classNames/styles)→ 深度主题定制(Design Token)

边界与兼容性提示

  • 语义化 classNames 相关能力以 6.0.0 为分水岭(如 preview.mask 对象化、classNames.cover),6.4.0 又补充了 popup.close 语义节点与 mask.closablefocusTrap;在旧版本中这些字段会被忽略,接入前请核对目标版本的组件版本号(文档 API 表中 Version 列已逐条标注)。
  • 受控预览必须配合 onOpenChange:一旦传入 open,预览开关即由外部接管,若不回调更新将无法关闭。
  • preview.srcsrc 分离是性能利器:列表展示缩略图,打开预览才加载原图。
  • 内置的进度占位、水彩墨迹动画与遮罩 blur 均依赖现代 CSS(backdrop-filter、渐变动画),在低版本浏览器中视觉表现可能退化,但不影响基本功能。

更多可直接运行、逐项演示上述能力的示例位于 components/image/demo 目录;对应的行为测试与语义快照测试(如 tests/index.test.tsxtests/semantic.test.tsx)可帮助你确认各配置项在不同版本下的实际表现。

登录后查看全文
热门项目推荐
相关项目推荐