---
title: "ImageGallery 图片预览"
description: "缩略图网格加全屏灯箱预览"
category: Data
status: beta
since: 0.3.4
tags: [image, gallery, preview]
syncStatus: reviewed
verified: true
---

## 用法

### 基础
点击缩略图在全屏灯箱中打开；`startIndex` 指定当前预览的图片。
::::TuffDemoWrapper{demo="ImageGalleryImageGalleryDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  const items = [
    { id: 'one', url: '/images/one.png', name: '工作区概览' },
    { id: 'two', url: '/images/two.png', name: '发布图表' },
  ]
  </script>

  <template>
    <TxImageGallery :items="items" :start-index="1" />
  </template>
---
::::

### 追踪预览打开

```vue
<script setup lang="ts">
function onOpen({ index, item }: { index: number, item: { id: string } }) {
  analytics.track('gallery_open', { index, imageId: item.id })
}
</script>

<template>
  <TxImageGallery :items="images" @open="onOpen" @close="onClose" />
</template>
```

### 控制起始图片
`startIndex` 只选择预览索引，不会打开灯箱。

```vue
<template>
  <TxImageGallery :items="screenshots" :start-index="selectedIndex" />
</template>
```

### 最佳实践

- 使用稳定的 `id`，不要用数组索引作长期图库数据的 key。
- 信息性图片提供 `name`，按钮标签、alt 与预览标题才有意义。
- 列表规模保持适中：组件渲染全部缩略图，不做虚拟化。
- 不可信的远程图片 URL 先在应用边界归一化或代理。
- 不要在 `@open` 中同步改动 `items`，以免已打开的图片失效。

## API 参考

### 属性

| 属性名 | 类型 | 默认值 | 说明 |
|------|------|---------|------|
| `items` | `ImageGalleryItem[]` | 必填 | 缩略图及全屏预览的图片。 |
| `startIndex` | `number` | `0` | 当前预览索引，收敛到有效范围。 |
| `previousLabel` | `string` | `'Previous image'` | 上一张按钮的可访问名称。 |
| `nextLabel` | `string` | `'Next image'` | 下一张按钮的可访问名称。 |
| `previousText` | `string` | `'Prev'` | 上一张按钮的可见文字。 |
| `nextText` | `string` | `'Next'` | 下一张按钮的可见文字。 |
| `previewTitle` | `string` | `'Preview'` | 当前图片没有 `name` 时的预览标题。 |
| `itemLabelFormatter` | `(index: number) => string` | `` (i) => `Image ${i + 1}` `` | 图片没有 `name` 时生成显示名称。 |
| `openLabelFormatter` | `(label: string) => string` | `` (label) => `Open ${label} preview` `` | 由显示名称生成缩略图的 `aria-label`。 |

### 事件

| 事件名 | 参数 | 说明 |
|------|------|------|
| `open` | `{ index: number, item: ImageGalleryItem }` | 缩略图打开全屏预览后触发。 |
| `close` | `void` | 预览关闭时触发。 |

### ImageGalleryItem

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `string` | 缩略图的稳定 key。 |
| `url` | `string` | 缩略图与预览图的 URL。 |
| `name` | `string` | 可选显示名称，用于标签、alt 与预览标题。 |

## 概述

- 每个缩略图是原生 `<button type="button">`，`aria-label` 由 `openLabelFormatter` 生成。
- 缩略图与预览图的 `alt` 取 `item.name`；未命名图片有意使用空 alt。
- 灯箱困住 Tab 焦点，Escape 或关闭按钮关闭，焦点回到触发的缩略图。
- 导航有边界：首张禁用上一张，末张禁用下一张；按钮被禁用时焦点移到另一侧按钮。
- 图片在头栏与底栏之间等比完整显示，不裁切。
- `items` 变为空时预览关闭、索引重置为 `0`。

## 技术实现

- 灯箱即 `TxModal` 的 `fullscreen` 模式（挂载到 `body`），不另写浮层。
- 源码：`packages/tuffex/packages/components/src/image-gallery/`。

<TuffDocSourceLink />
