Skip to content

v-image-preview

创建模态图片预览,支持移动端优化的手势操作,包括双指缩放、双击和滑动。

起始版本: 1.2.0

用法

基础用法

vue
<template>
  <!-- 使用 data-preview 属性 -->
  <img
    v-image-preview
    src="thumbnail.jpg"
    data-preview="full-size.jpg"
    alt="点击预览"
  />
</template>

带选项

vue
<template>
  <img
    v-image-preview="{
      previewSrc: 'full-size.jpg',
      enablePinchZoom: true,
      enableDoubleTap: true,
      enableSwipeClose: true,
      onOpen: handleOpen,
      onClose: handleClose
    }"
    src="thumbnail.jpg"
    alt="点击预览"
  />
</template>

<script setup>
function handleOpen() {
  console.log('预览已打开')
}

function handleClose() {
  console.log('预览已关闭')
}
</script>

非图片元素

vue
<template>
  <div
    v-image-preview="{ src: 'image.jpg' }"
    class="preview-trigger"
  >
    点击预览图片
  </div>
</template>

API

类型

typescript
interface ImagePreviewOptions {
  /** 图片源 URL */
  src?: string
  /** 预览图片源 URL(高分辨率) */
  previewSrc?: string
  /** 无障碍替代文本 */
  alt?: string
  /** 是否禁用预览 */
  disabled?: boolean
  /** 点击外部关闭 @default true */
  closeOnClickOutside?: boolean
  /** ESC 键关闭 @default true */
  closeOnEsc?: boolean
  /** 显示关闭按钮 @default true */
  showCloseButton?: boolean
  /** 预览层 z-index @default 9999 */
  zIndex?: number
  /** 预览层自定义类名 */
  class?: string
  /** 启用双指缩放 @default true */
  enablePinchZoom?: boolean
  /** 启用双击缩放 @default true */
  enableDoubleTap?: boolean
  /** 启用上滑关闭 @default true */
  enableSwipeClose?: boolean
  /** 显示缩放指示器 @default true */
  showZoomIndicator?: boolean
  /** 最小缩放比例 @default 0.5 */
  minScale?: number
  /** 最大缩放比例 @default 5 */
  maxScale?: number
  /** 预览打开时的回调 */
  onOpen?: () => void
  /** 预览关闭时的回调 */
  onClose?: () => void
}

type ImagePreviewBinding = string | ImagePreviewOptions

选项

选项类型默认值说明
srcstring-图片源 URL
previewSrcstring-高分辨率图片 URL
altstring-无障碍替代文本
disabledbooleanfalse禁用指令
closeOnClickOutsidebooleantrue点击外部关闭
closeOnEscbooleantrueESC 键关闭
showCloseButtonbooleantrue显示关闭按钮
zIndexnumber9999预览层 z-index
classstring-预览层自定义类名
enablePinchZoombooleantrue启用双指缩放
enableDoubleTapbooleantrue启用双击缩放
enableSwipeClosebooleantrue启用上滑关闭
showZoomIndicatorbooleantrue显示缩放百分比指示器
minScalenumber0.5最小缩放比例
maxScalenumber5最大缩放比例
onOpenFunction-预览打开时的回调
onCloseFunction-预览关闭时的回调

移动端手势

手势操作
双指捏合缩放(0.5x - 5x)
双击切换缩放(1x ↔ 2.5x)
上滑关闭预览(未缩放时)
拖拽缩放后平移
滚轮桌面端缩放

Composable 用法

你也可以使用 useImagePreview composable 来实现相同功能:

vue
<script setup>
import { ref, onMounted } from 'vue'
import { useImagePreview } from 'directix'

const imageRef = ref(null)
const { isOpen, bind, open, close } = useImagePreview({
  onOpen: () => console.log('预览已打开'),
  onClose: () => console.log('预览已关闭')
})

onMounted(() => bind(imageRef.value))

function openCustomImage() {
  open('https://example.com/high-res.jpg')
}
</script>

<template>
  <img ref="imageRef" src="thumbnail.jpg" />
  <button @click="openCustomImage">预览其他图片</button>
</template>

API

typescript
interface UseImagePreviewOptions {
  /** 初始图片 URL */
  src?: string | Ref<string>
  /** 点击外部关闭 @default true */
  closeOnClickOutside?: boolean
  /** ESC 键关闭 @default true */
  closeOnEsc?: boolean
  /** 显示关闭按钮 @default true */
  showCloseButton?: boolean
  /** 预览打开时的回调 */
  onOpen?: () => void
  /** 预览关闭时的回调 */
  onClose?: () => void
}

interface UseImagePreviewReturn {
  /** 预览是否打开 */
  isOpen: Readonly<Ref<boolean>>
  /** 当前图片 URL */
  currentSrc: Readonly<Ref<string>>
  /** 打开预览 */
  open: (src?: string) => void
  /** 关闭预览 */
  close: () => void
  /** 绑定点击预览到图片元素 */
  bind: (element: HTMLImageElement) => () => void
}

示例

多图画廊

vue
<template>
  <div class="gallery">
    <img
      v-for="image in images"
      :key="image.id"
      v-image-preview
      :src="image.thumbnail"
      :data-preview="image.full"
      :alt="image.title"
      class="gallery-item"
    />
  </div>
</template>

<script setup>
const images = [
  { id: 1, thumbnail: '/thumb1.jpg', full: '/full1.jpg', title: '图片 1' },
  { id: 2, thumbnail: '/thumb2.jpg', full: '/full2.jpg', title: '图片 2' },
]
</script>

禁用状态切换

vue
<template>
  <img
    v-image-preview="{ disabled: !previewEnabled }"
    src="image.jpg"
    data-preview="full.jpg"
  />
  <button @click="previewEnabled = !previewEnabled">
    {{ previewEnabled ? '禁用' : '启用' }}预览
  </button>
</template>

<script setup>
import { ref } from 'vue'

const previewEnabled = ref(true)
</script>

基于 MIT 许可发布