Image 图片
图片容器,在保留所有原生 img 的特性下,支持懒加载,自定义占位、加载失败等
基础用法
export function ImageBasic() { return ( <div> <div style={EQUAL_BLOCK_STYLE}> <span style={DEMONSTRATION_STYLE}>fill</span> <ElImage src={URL} fit="fill" style={IMAGE_BOX_STYLE} /> </div> <div style={EQUAL_BLOCK_STYLE}> <span style={DEMONSTRATION_STYLE}>contain</span> <ElImage src={URL} fit="contain" style={IMAGE_BOX_STYLE} /> </div> <div style={EQUAL_BLOCK_STYLE}> <span style={DEMONSTRATION_STYLE}>cover</span> <ElImage src={URL} fit="cover" style={IMAGE_BOX_STYLE} /> </div> <div style={EQUAL_BLOCK_STYLE}> <span style={DEMONSTRATION_STYLE}>none</span> <ElImage src={URL} fit="none" style={IMAGE_BOX_STYLE} /> </div> <div style={EQUAL_BLOCK_STYLE}> <span style={DEMONSTRATION_STYLE}>scale-down</span> <ElImage src={URL} fit="scale-down" style={IMAGE_BOX_STYLE} /> </div> </div> );}
占位内容
可通过slot = placeholder可自定义占位内容
export function ImagePlaceholder() { const src = "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"; const slotStyle: CSSProperties = { display: "flex", justifyContent: "center", alignItems: "center", width: "100%", height: "100%", background: "var(--el-fill-color-light)", color: "var(--el-text-color-secondary)", fontSize: 14, }; return ( <div> <div style={{ ...EQUAL_BLOCK_STYLE, width: "49%" }}> <span style={DEMONSTRATION_STYLE}>Default</span> <ElImage src={src} style={{ maxWidth: 300, maxHeight: 200, padding: "0 5px" }} /> </div> <div style={{ ...EQUAL_BLOCK_STYLE, width: "49%", borderRight: "none", }} > <span style={DEMONSTRATION_STYLE}>Custom</span> <ElImage src={src} style={{ maxWidth: 300, maxHeight: 200, padding: "0 5px" }} renderPlaceholder={() => ( <div style={slotStyle}> Loading <span style={{ animation: "dot 2s infinite steps(3, start)", overflow: "hidden", }} > ... </span> </div> )} /> </div> </div> );}
加载失败
通过 slot = error and slot = viewer-error自定义图像加载错误时的内容。
export function ImageLoadFailed() { const [showPreview, setShowPreview] = useState(false); const srcList = [ "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg", "https://errorSrc", ]; const errorSlotStyle: CSSProperties = { display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column", fontSize: 30, height: 200, background: "#fff", }; const imageStyle: CSSProperties = { maxWidth: 300, maxHeight: 200, width: "100%", }; return ( <ElConfigProvider locale={en}> <div style={{ display: "flex", gap: 8 }}> <ElImage style={imageStyle} /> <ElImage style={imageStyle} renderError={() => ( <div style={errorSlotStyle}> <ElIcon> <Picture /> </ElIcon> </div> )} /> <ElImage style={imageStyle} src={srcList[0]} previewSrcList={srcList} showProgress renderViewerError={({ activeIndex, src }: ImageViewerErrorScope) => ( <div style={{ ...errorSlotStyle, color: "#000" }}> <ElIcon> <Picture /> </ElIcon> <span> this is viewer-error slot. current index: {activeIndex}. src: {src} </span> </div> )} /> <ElButton onClick={() => setShowPreview(true)}>preview controlled</ElButton> {showPreview && ( <ElImageViewer showProgress urlList={srcList} onClose={() => setShowPreview(false)} renderViewerError={({ activeIndex, src }: ImageViewerErrorScope) => ( <div style={{ ...errorSlotStyle, color: "#000" }}> <ElIcon> <Picture /> </ElIcon> <span> this is viewer-error slot. current index: {activeIndex}. src: {src} </span> </div> )} /> )} </div> </ElConfigProvider> );}
懒加载
浏览器原生支持的 loading属性在 2.2.3版本加入。 您可以使用 loading="lazy" 替换之前的lazy= true。
如果当前浏览器支持原生图片延迟加载,则先使用原生能力,否则将使用滚动监听实现相同效果。
可通过lazy开启懒加载功能,当图片滚动到可视范围内才会加载。可通过 scroll-container 来设置滚动容器,若未定义,则为最近一个 overflow 值为 auto 或 scroll 的父元素。
export function ImageLazyLoad() { return ( <div style={{ height: 400, overflowY: "auto" }}> {SRC_LIST.map((url, index) => ( <ElImage key={url} src={url} lazy style={{ display: "block", minHeight: 200, marginBottom: index < SRC_LIST.length - 1 ? 10 : 0, }} /> ))} </div> );}
图片预览
可通过 previewSrcList 开启预览大图的功能。你可以通过 initial-index 初始化第一张预览图片的位置。默认初始位置为 0。
export function ImagePreview() { return ( <div> <ElImage style={IMAGE_BOX_STYLE} src={PREVIEW_URL} zoomRate={1.2} maxScale={7} minScale={0.2} previewSrcList={SRC_LIST} showProgress initialIndex={4} fit="cover" /> </div> );}
手动打开预览 2.9.4
export function ImageManuallyPreview() { const imageRef = useRef<ImageExpose>(null); const [showPreview, setShowPreview] = useState(false); return ( <div style={{ display: "flex", gap: 48 }}> <div style={{ display: "grid", gap: 12 }}> <ElButton onClick={() => imageRef.current?.showPreview()}> openPreview with showPreview method </ElButton> <ElImage ref={imageRef} style={IMAGE_BOX_STYLE} src={PREVIEW_URL} showProgress previewSrcList={SRC_LIST} fit="cover" /> </div> <div> <ElButton onClick={() => setShowPreview(true)}>preview controlled</ElButton> {showPreview && ( <ElImageViewer urlList={SRC_LIST} showProgress initialIndex={4} onClose={() => setShowPreview(false)} /> )} </div> </div> );}
自定义工具栏2.9.4
可通过 toolbar 插槽自定义工具栏内容,自版本 2.9.7 起,插槽中添加了 setActiveItem 方法,用于根据索引切换图片。
export function ImageCustomToolbar() { const download = (index: number) => { const url = SRC_LIST[index]; const suffix = url.slice(url.lastIndexOf(".")); const filename = Date.now() + suffix; fetch(url) .then((response) => response.blob()) .then((blob) => { const blobUrl = window.URL.createObjectURL(new Blob([blob])); const link = document.createElement("a"); link.href = blobUrl; link.download = filename; document.body.appendChild(link); link.click(); window.URL.revokeObjectURL(blobUrl); link.remove(); }); }; return ( <div> <ElImage style={IMAGE_BOX_STYLE} src={PREVIEW_URL} previewSrcList={SRC_LIST} fit="cover" showProgress renderToolbar={(scope: ImageViewerToolbarScope) => ( <> <ElIcon onClick={scope.prev}> <Back /> </ElIcon> <ElIcon onClick={scope.next}> <Right /> </ElIcon> <ElIcon onClick={() => scope.setActiveItem(SRC_LIST.length - 1)}> <DArrowRight /> </ElIcon> <ElIcon onClick={() => scope.actions("zoomOut")}> <ZoomOut /> </ElIcon> <ElIcon onClick={() => scope.actions("zoomIn", { enableTransition: false, zoomRate: 2 }) } > <ZoomIn /> </ElIcon> <ElIcon onClick={() => scope.actions("clockwise", { rotateDeg: 180, enableTransition: false, }) } > <RefreshRight /> </ElIcon> <ElIcon onClick={() => scope.actions("anticlockwise")}> <RefreshLeft /> </ElIcon> <ElIcon onClick={scope.reset}> <Refresh /> </ElIcon> <ElIcon onClick={() => download(scope.activeIndex)}> <Download /> </ElIcon> </> )} /> </div> );}
自定义进度条 2.9.4
可通过 show-progress 控制是否在预览图片时显示进度条。自版本 2.9.8 起,进度条会在使用 progress 插槽时显示。
export function ImageCustomProgress() { return ( <div> <ElImage style={IMAGE_BOX_STYLE} src={PREVIEW_URL} previewSrcList={SRC_LIST} fit="cover" renderProgress={({ activeIndex, total }: ImageViewerProgressScope) => ( <span>{activeIndex + 1 + "-" + total}</span> )} /> </div> );}
Image API
Image Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|
| src | 图片地址,同原生 | string | '' |
| fit | 图片填充方式,同原生 object-fit | enum | '' |
| hide-on-click-modal | 开启预览时,点击遮罩是否关闭预览 | boolean | false |
| loading | 浏览器加载方式,同原生 loading | enum | — |
| lazy | 是否使用懒加载 | boolean | false |
| scroll-container | 懒加载时监听滚动的容器 | string / HTMLElement | — |
| alt | 原生 alt | string | — |
| referrer-policy | 原生 referrerPolicy | string | — |
| cross-origin | 原生 crossorigin | enum | — |
| preview-src-list | 允许大图预览的链接列表 | array | [] |
| z-index | 预览层级 | number | — |
| initial-index | 初始预览下标 | number | 0 |
| close-on-press-escape | 预览时按 ESC 是否关闭 | boolean | true |
| preview-teleported | 是否把预览查看器传送到 body | boolean | false |
| infinite | 预览是否循环 | boolean | true |
| zoom-rate | 缩放比例基数 | number | 1.2 |
| scale | 预览图片缩放值 | number | 1 |
| min-scale | 最小缩放值 | number | 0.2 |
| max-scale | 最大缩放值 | number | 7 |
| show-progress | 是否显示预览进度 | boolean | false |
| class-name / style | 根元素类名与样式 | string / object | — |
Image Events
| 事件名 | 说明 | 参数 |
|---|
| onLoad | 同原生 load | Function |
| onError | 同原生 error | Function |
| onSwitch | 切换预览图片时触发 | Function |
| onClose | 关闭预览时触发 | Function |
| onShow | 打开预览时触发 | Function |
Image Slots
| 插槽名 | 说明 | React 写法 |
|---|
| placeholder | 图片未加载完成时的占位内容 | renderPlaceholder |
| error | 图片加载失败时的内容 | renderError |
| viewer | 预览查看器自定义内容 | viewer |
| progress | 预览进度自定义内容 | renderProgress |
| toolbar | 预览工具栏自定义内容 | renderToolbar |
| viewer-error | 预览图片加载失败时的内容 | renderViewerError |
Image Exposes
| 名称 | 说明 | 类型 |
|---|
| showPreview | 手动打开大图预览 | Function |
通过 ref 拿到 expose:const ref = useRef<ImageExpose>(null),再调用 ref.current?.showPreview()。
Image Viewer API
Image Viewer Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|
| url-list | 预览链接列表 | array | [] |
| z-index | 预览遮罩层级 | number | — |
| initial-index | 初始预览下标 | number | 0 |
| infinite | 预览是否循环 | boolean | true |
| hide-on-click-modal | 点击遮罩是否关闭 | boolean | false |
| teleported | 是否把查看器传送到 body | boolean | false |
| close-on-press-escape | 按 ESC 是否关闭 | boolean | true |
| zoom-rate | 缩放比例基数 | number | 1.2 |
| scale | 预览图片缩放值 | number | 1 |
| min-scale | 最小缩放值 | number | 0.2 |
| max-scale | 最大缩放值 | number | 7 |
| show-progress | 是否显示进度 | boolean | false |
| crossorigin | 原生 crossorigin | enum | — |
Image Viewer Events
| 事件名 | 说明 | 参数 |
|---|
| onClose | 关闭时触发 | Function |
| onError | 图片加载失败时触发 | Function |
| onSwitch | 切换图片时触发 | Function |
| onRotate | 旋转时触发 | Function |
Image Viewer Slots
| 插槽名 | 说明 | React 写法 / 作用域 |
|---|
| viewer | 自定义内容 | children |
| progress | 自定义进度内容 | renderProgress({ activeIndex, total }) |
| toolbar | 自定义工具栏内容 | renderToolbar({ actions, prev, next, reset, activeIndex, setActiveItem }) |
| viewer-error | 自定义加载失败内容 | renderViewerError({ activeIndex, src }) |
Image Viewer Exposes
| 名称 | 说明 | 类型 |
|---|
| setActiveItem | 手动切换图片 | Function |