快速开始
包裹任意元素即可 —— 缩略图可以是原生 <img>、next/image、<picture>,
或者你自己设计系统里的组件。ImageView 只负责挂上行为和 ref,
它不会替你渲染触发用的 <img>。
import { ImageView } from 'react-img-view'import zhCN from 'react-img-view/locales/zh-CN'import 'react-img-view/styles.css'
function SingleImagePreview({ image }: { image: { thumb: string; full: string; name: string } }) { return ( <ImageView src={image.full} alt={image.name} name={image.name} labels={zhCN}> <img src={image.thumb} alt={image.name} /> </ImageView> )}
多图共享一个预览器
Section titled “多图共享一个预览器”Group 会把它下面所有的 ImageView 收集成一组。点击任意一个都会打开预览器并定位到那张图,
方向键和滑动可以在其余图片之间切换。这里没有写 Content ——
Group 会自动补上同一套默认界面。
import { ImageView } from 'react-img-view'import zhCN from 'react-img-view/locales/zh-CN'import 'react-img-view/styles.css'
function ImageList({ images }: { images: { src: string; name: string }[] }) { return ( <ImageView.Group images={images} labels={zhCN}> <div className="grid grid-cols-4 gap-3"> {images.map((image, i) => ( <ImageView key={image.src} index={i} {...image}> <img src={image.src} alt={image.name} className="h-24 w-full object-cover" /> </ImageView> ))} </div> </ImageView.Group> )}



打开计数器或缩略图轨
Section titled “打开计数器或缩略图轨”两者默认都关闭:图片不多时,左右箭头已经足够说明位置。 当图片数量较多、仅靠箭头说明不了情况时再打开:
<ImageView.Group images={images}> {/* triggers */} <ImageView.DefaultContent counter thumbnails /></ImageView.Group>如果不想自己维护 open 和 index,可以直接调用函数式 API:
import { ImagePreview } from 'react-img-view/imperative'import zhCN from 'react-img-view/locales/zh-CN'
function ViewButton({ images }) { return ( <button onClick={() => ImagePreview.open({ images, index: 2, labels: zhCN })}> 查看第 3 张 </button> )}调用时传入图片数组和初始序号。再次调用会替换当前预览,并返回带有
close()、go()、next()、prev() 的句柄。ImagePreview.close() 可以关闭
当前预览;关闭后会自动清理。
函数式调用没有对应的缩略图元素,因此会直接打开预览器,不播放缩略图到大图的过渡动画。
受控的打开状态
Section titled “受控的打开状态”从应用里的任何地方打开预览器 —— 比如表格行里的「查看」按钮 —— 自己控制
open 和 index 就行。当外围组件本来就需要持有这两个值时,优先用这种形式:
const [open, setOpen] = useState(false);const [index, setIndex] = useState(0);
<ImageView.Group images={images} open={open} index={index} onOpenChange={setOpen} onIndexChange={setIndex}> {/* 以编程方式打开时,triggers 是可选的 */}</ImageView.Group>
<Button onClick={() => { setIndex(2); setOpen(true); }}> 查看第 3 张</Button>用 DefaultContent 所使用的同一批部件,自己拼出界面。控件和布局区域支持
asChild,ImageView 始终直接复用自己的子元素;每个控件都会暴露
data-active / data-boundary / data-disabled 供你写样式。
使用主入口时,请让 Content 或 DefaultContent 成为 Group 的直接子节点;
Group 正是通过这一层判断是否还需要补上默认界面。
import { ImageView } from 'react-img-view/primitives'import zhCN from 'react-img-view/locales/zh-CN'
function CustomViewer({ images }) { return ( <ImageView.Group images={images} labels={zhCN}> {images.map((image, i) => ( <ImageView key={image.src} index={i} {...image}> <img src={image.src} alt={image.name} /> </ImageView> ))}
<ImageView.Content className="riv-dialog"> <ImageView.Header className="riv-header"> <ImageView.Close>关闭</ImageView.Close> <ImageView.Title /> <ImageView.Download>下载</ImageView.Download> </ImageView.Header>
<ImageView.Stage className="riv-stage"> <ImageView.Image /> <ImageView.Prev>‹</ImageView.Prev> <ImageView.Next>›</ImageView.Next> <ImageView.Loading>载入中…</ImageView.Loading> <ImageView.Error> {({ retry }) => ( <div> <p>无法加载这张图片</p> <button onClick={retry}>重试</button> </div> )} </ImageView.Error>
<ImageView.Toolbar className="riv-toolbar"> <ImageView.ZoomOut /> <ImageView.ZoomIn /> <ImageView.RotateLeft /> <ImageView.RotateRight /> <ImageView.FitToWindow /> <ImageView.ActualSize /> </ImageView.Toolbar> </ImageView.Stage> </ImageView.Content> </ImageView.Group> )}读取预览器状态
Section titled “读取预览器状态”useViewer() 在 Group 内部任意位置都能用 —— 自定义控件、状态展示、埋点:
import { useViewer } from 'react-img-view/primitives'
function ZoomReadout() { const viewer = useViewer() return <span>{Math.round(viewer.scale * 100)}%</span>}useViewer() 的完整返回值和每个部件的属性,见 API 文档。
| 按键 | 操作 |
|---|---|
← / → |
上一张 / 下一张 |
Home / End |
第一张 / 最后一张 |
+ / - |
放大 / 缩小 |
0 |
适应窗口 |
1 |
原始尺寸(1:1) |
R / Shift+R |
向右 / 向左旋转 |
Esc |
关闭 |