Skip to content

Image 图片 ​

用于展示图片,并支持加载态、错误态、底部信息和预览。

何时使用 ​

  • 展示图片缩略图、封面、附件预览或带标题说明的图片内容。
  • 需要提供单图预览、预览组切换、缩放、旋转或自定义预览操作时。
  • 需要在图片加载中、加载失败时提供明确反馈时。

基础用法 ​

示例图片
vue
<template>
  <x-image :src="imageSrc" width="160" height="120" fit="cover" alt="示例图片" />
</template>

<script setup lang="ts">
  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
</script>

适应方式 ​

vue
<template>
  <x-image
    :src="imageSrc"
    width="120"
    height="90"
    fit="cover"
    title="cover"
    footer-position="outer"
  />
  <x-image
    :src="imageSrc"
    width="120"
    height="90"
    fit="contain"
    title="contain"
    footer-position="outer"
  />
  <x-image
    :src="imageSrc"
    width="120"
    height="90"
    fit="fill"
    title="fill"
    footer-position="outer"
  />
</template>

<script setup lang="ts">
  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
</script>

底部信息 ​

底部信息覆盖在图片内部
footerPosition 设置为 outer
vue
<template>
  <x-image
    :src="imageSrc"
    width="180"
    height="120"
    title="组件封面"
    description="底部信息覆盖在图片内部"
    fit="cover"
  />
  <x-image
    :src="imageSrc"
    width="180"
    height="120"
    title="外置说明"
    description="footerPosition 设置为 outer"
    footer-position="outer"
    fit="cover"
  />
  <x-image :src="imageSrc" width="240" height="140" title="底部操作" fit="cover">
    <template #extra>
      <x-button size="mini" @click="footerActionCount++">收藏 {{ footerActionCount }}</x-button>
    </template>
  </x-image>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const footerActionCount = ref(0);
  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
</script>

加载和错误 ​

失败占位使用中性色背景,并保留图片圆角。可通过 error / error-icon 自定义内容;修改 src 后会重新进入加载流程,支持从失败地址恢复。

图片加载中
图片加载失败
vue
<template>
  <x-image :src="imageSrc" width="160" height="110" show-loader fit="cover" />
  <x-image src="data:image/png;base64,broken-image" width="160" height="110" alt="图片加载失败" />
  <x-image src="data:image/png;base64,broken-image" width="160" height="110">
    <template #error-icon><span aria-hidden="true">◇</span></template>
  </x-image>
  <x-image src="data:image/png;base64,broken-image" width="160" height="110">
    <template #error>
      <div class="image-error">无法加载图片</div>
    </template>
  </x-image>
</template>

<script setup lang="ts">
  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
</script>

<style scoped>
  .image-error {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--x-color-text-secondary);
    background: var(--x-color-fill-2);
  }
</style>

更换图片与错误恢复 ​

直接更新 src。组件会重置加载状态和旧图片节点;加载失败后可通过插槽中的按钮改回有效地址。下面的图片均是离线可用的低饱和风景插画,加载通常很快。

可替换风景
正在准备风景图片…
已选择湖畔
vue
<template>
  <x-button @click="src = landscapes[0]">湖畔</x-button>
  <x-button @click="src = landscapes[1]">山丘</x-button>
  <x-button @click="src = 'data:image/png;base64,broken-image'">模拟失败</x-button>
  <x-image
    :src="src"
    width="240"
    height="150"
    fit="cover"
    show-loader
    alt="可替换风景"
    @load="state = '图片已加载'"
    @error="state = '加载失败'"
  >
    <template #loader><div class="placeholder">正在准备图片…</div></template>
    <template #error>
      <div class="placeholder">
        <span>图片暂时无法加载</span>
        <x-button size="mini" @click="src = landscapes[0]">恢复图片</x-button>
      </div>
    </template>
  </x-image>
  <span aria-live="polite">{{ state }}</span>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  const landscape = (sky: string, hills: string) =>
    'data:image/svg+xml,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="480" height="300"><rect width="480" height="300" fill="${sky}"/><path d="M0 230Q120 110 240 220T480 180V300H0Z" fill="${hills}"/></svg>`,
    );
  const landscapes = [landscape('#e8efec', '#a6bdb1'), landscape('#f0ebe4', '#bca996')];
  const src = ref(landscapes[0]);
  const state = ref('图片已选择');
</script>

<style scoped>
  .placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    width: 100%;
    height: 100%;
    color: var(--x-color-text-secondary);
    background: var(--x-color-fill-2);
  }
</style>

受控预览 ​

当前:已关闭
vue
<template>
  <x-button @click="previewVisible = true">打开预览</x-button>
  <x-image
    v-model:preview-visible="previewVisible"
    :src="imageSrc"
    width="180"
    height="120"
    fit="cover"
    @preview-visible-change="onPreviewVisibleChange"
  />
  <p>当前:{{ previewVisible ? '已打开' : '已关闭' }}</p>
  <p v-for="(log, index) in logs" :key="index">{{ log }}</p>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
  const previewVisible = ref(false);
  const logs = ref<string[]>([]);
  const onPreviewVisibleChange = (visible: boolean) => {
    logs.value = [visible ? '已打开' : '已关闭', ...logs.value].slice(0, 4);
  };
</script>

预览组 ​

设置 srcList 时,预览内容以该列表为准,子图片作为打开对应下标的缩略图;缩略图与列表应保持相同顺序,也可以使用不同的缩略图与高清图片地址。不传 srcList 时,预览组自动收集子图片。

当前图片:1 / 3
vue
<template>
  <x-image-preview-group
    v-model:visible="visible"
    v-model:current="current"
    :src-list="images"
    infinite
    @change="onChange"
  >
    <x-image
      v-for="(item, index) in images"
      :key="item"
      :src="item"
      width="120"
      height="84"
      fit="cover"
      :title="`风景 ${index + 1}`"
      footer-position="outer"
    />
  </x-image-preview-group>
  <p>当前图片:{{ current + 1 }} / {{ images.length }}</p>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const visible = ref(false);
  const current = ref(0);
  const images = [
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E',
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23f0ebe4%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23fcf5e6%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23d7cbbd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23bca996%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%23998571%22%2F%3E%3C%2Fsvg%3E',
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e9edf2%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23f7f5ef%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c7d1df%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a7b7ca%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%238098b2%22%2F%3E%3C%2Fsvg%3E',
  ];
  const onChange = (index: number) => {
    console.log('current image:', index);
  };
</script>

自定义预览操作 ​

vue
<template>
  <x-image :src="imageSrc" width="180" height="120" fit="cover">
    <template #preview-actions>
      <x-image-preview-action name="记录" @click="record">
        <span>记</span>
      </x-image-preview-action>
    </template>
  </x-image>
  <p v-for="(log, index) in logs" :key="index">{{ log }}</p>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
  const logs = ref<string[]>([]);
  const record = () => {
    logs.value = ['点击了自定义预览操作', ...logs.value].slice(0, 4);
  };
</script>

关闭缩略图预览 ​

preview=false 时点击缩略图不会打开预览;在自动收集的预览组中,方向键和箭头切换会跳过该图片。

vue
<template>
  <x-image
    :src="imageSrc"
    width="180"
    height="120"
    fit="cover"
    :preview="false"
    title="仅展示图片"
  />
</template>

<script setup lang="ts">
  const imageSrc =
    'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22480%22%20height%3D%22300%22%20viewBox%3D%220%200%20480%20300%22%3E%3Crect%20width%3D%22480%22%20height%3D%22300%22%20fill%3D%22%23e8efec%22%2F%3E%3Ccircle%20cx%3D%22356%22%20cy%3D%2276%22%20r%3D%2230%22%20fill%3D%22%23faf6e9%22%2F%3E%3Cpath%20d%3D%22M0%20186Q94%2098%20196%20174T480%20150V300H0Z%22%20fill%3D%22%23c8d6cd%22%2F%3E%3Cpath%20d%3D%22M0%20216Q120%20160%20230%20202T480%20190V300H0Z%22%20fill%3D%22%23a6bdb1%22%2F%3E%3Cpath%20d%3D%22M0%20264Q124%20210%20260%20250T480%20242V300H0Z%22%20fill%3D%22%237f9e90%22%2F%3E%3C%2Fsvg%3E';
</script>

动态图片列表 ​

不传 srcList 时,修改子图片地址会更新当前预览,并保留注册顺序;移除图片后下标会调整,清空列表会关闭预览。使用稳定的 key 标识每张图片。

当前图片:1 / 3
vue
<template>
  <x-button :disabled="!images.length" @click="replaceFirst">替换第一张</x-button>
  <x-button :disabled="!images.length" @click="images.shift()">移除第一张</x-button>
  <x-button @click="images = []">清空图片</x-button>
  <x-button @click="restore">恢复图片</x-button>
  <x-image-preview-group v-model:visible="visible" v-model:current="current">
    <x-image
      v-for="item in images"
      :key="item.id"
      :src="item.src"
      width="120"
      height="84"
      fit="cover"
      :title="`风景 ${item.id}`"
      footer-position="outer"
    />
  </x-image-preview-group>
  <p>{{ images.length ? `当前图片:${current + 1} / ${images.length}` : '图片列表为空' }}</p>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const makeImage = (color: string) =>
    'data:image/svg+xml,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="320" height="200"><rect width="320" height="200" fill="${color}"/></svg>`,
    );
  const createImages = () =>
    ['#a6bdb1', '#bca996', '#a7b7ca'].map((color, index) => ({
      id: index + 1,
      src: makeImage(color),
    }));
  const images = ref(createImages());
  const visible = ref(false);
  const current = ref(0);
  const replaceFirst = () => {
    if (images.value[0]) images.value[0].src = makeImage('#b8c9ba');
  };
  const restore = () => {
    visible.value = false;
    current.value = 0;
    images.value = createImages();
  };
</script>

独立预览与自定义工具条 ​

预览工具条使用深色半透明背景,亮暗主题保持一致。将 actionsLayout 设为空数组可仅保留自定义操作;关闭后焦点返回打开预览的按钮。

已记录 0 次
vue
<template>
  <x-button @click="visible = true">打开独立预览</x-button>
  <span>已记录 {{ count }} 次</span>
  <x-image-preview v-model:visible="visible" :src="src" :actions-layout="[]">
    <template #actions>
      <x-image-preview-action name="记录" @click="count++"><span>记</span></x-image-preview-action>
    </template>
  </x-image-preview>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  const visible = ref(false);
  const count = ref(0);
  const src =
    'data:image/svg+xml,' +
    encodeURIComponent(
      '<svg xmlns="http://www.w3.org/2000/svg" width="480" height="300"><rect width="480" height="300" fill="#c8d6cd"/></svg>',
    );
</script>

容器内预览 ​

通过 popupContainer 指定宿主,可将预览限制在局部容器内;设置宽高并保留定位上下文。defaultScale 会限制在 0.25~5 倍,滚轮速率需大于 1,非法值会使用默认值。

预览仅覆盖此区域
vue
<template>
  <x-button @click="visible = true">在容器内预览</x-button>
  <div ref="host" class="preview-host">
    <x-image-preview
      v-model:visible="visible"
      :src="src"
      :popup-container="host"
      :default-scale="0.75"
    />
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  const host = ref<HTMLElement>();
  const visible = ref(false);
  const src =
    'data:image/svg+xml,' +
    encodeURIComponent(
      '<svg xmlns="http://www.w3.org/2000/svg" width="480" height="300"><rect width="480" height="300" fill="#a7b7ca"/></svg>',
    );
</script>

<style scoped>
  .preview-host {
    position: relative;
    width: 100%;
    height: 300px;
    overflow: hidden;
  }
</style>

按需导入 ​

ts
import { Image, ImagePreview, ImagePreviewGroup, ImagePreviewAction } from 'x-next';

样式按需引入(base.css 为共享基础层,多个组件只需引入一次):

ts
import 'x-next/style/base.css';
import 'x-next/style/image.css';

Image Props ​

参数说明类型默认值
src图片地址string-
width图片宽度string | number-
height图片高度string | number-
title标题string-
description描述string-
fit图片适应方式'contain' | 'cover' | 'fill' | 'none' | 'scale-down'-
alt图片文字描述string-
hideFooter是否隐藏底部信息;传 'never' 时加载错误也显示 footerboolean | 'never'false
footerPosition底部信息位置'inner' | 'outer''inner'
showLoader是否显示加载中效果booleanfalse
preview是否开启预览booleantrue
previewVisible预览是否打开booleanundefined
defaultPreviewVisible默认是否打开预览booleanfalse
previewProps预览配置ImagePreviewProps-
footerClass底部区域类名string | array | object-
renderToBody预览是否挂载到 bodybooleantrue

Image Events ​

事件名说明回调参数
update:previewVisible预览显隐变化时触发visible: boolean
preview-visible-change预览显隐变化时触发visible: boolean
load当前图片加载成功event: Event
error当前图片加载失败event: Event

Image Slots ​

插槽名说明
error-icon自定义错误图标
error自定义错误内容
loader自定义加载内容
extra底部额外内容
preview-actions预览额外操作项

ImagePreview Props ​

参数说明类型默认值
src图片地址string-
visible是否显示预览booleanundefined
defaultVisible默认是否显示预览booleanfalse
maskClosable点击遮罩是否关闭booleantrue
closable是否显示关闭按钮booleantrue
actionsLayout操作项布局string[]['fullScreen', 'rotateRight', 'rotateLeft', 'zoomIn', 'zoomOut', 'originalSize']
popupContainer弹出层挂载容器string | HTMLElementdocument.body
escToClose是否支持 Esc 关闭booleantrue
wheelZoom是否支持滚轮缩放booleantrue
keyboard是否支持键盘控制booleantrue
defaultScale默认缩放比number1
zoomRate缩放速率number1.1
renderToBody是否通过 Teleport 挂载到宿主容器booleantrue

ImagePreview Events ​

事件名说明回调参数
update:visible预览显隐变化时触发visible: boolean
close点击关闭按钮、遮罩或按 Esc 关闭时触发-

ImagePreview Slots ​

插槽名说明
actions自定义额外操作项

ImagePreviewGroup Props ​

参数说明类型默认值
srcList图片列表;设置后不再收集子 Image 的图片信息string[]-
current当前图片下标numberundefined
defaultCurrent默认图片下标number0
infinite是否无限循环booleanfalse
visible是否显示预览booleanundefined
defaultVisible默认是否显示预览booleanfalse
maskClosable点击遮罩是否关闭booleantrue
closable是否显示关闭按钮booleantrue
actionsLayout操作项布局string[]['fullScreen', 'rotateRight', 'rotateLeft', 'zoomIn', 'zoomOut', 'originalSize']
popupContainer弹出层挂载容器string | HTMLElement-
renderToBody是否挂载到 bodybooleantrue

ImagePreviewGroup Events ​

事件名说明回调参数
change切换图片时触发index: number
update:current当前图片下标变化时触发index: number
visible-change预览显隐变化时触发visible: boolean
update:visible预览显隐变化时触发visible: boolean

ImagePreviewGroup Slots ​

插槽名说明
default图片列表内容
actions自定义额外操作项,插槽参数为 { url }

ImagePreviewAction Props ​

参数说明类型默认值
name操作项名称,会用于 tooltip 和可访问标签string-
disabled是否禁用booleanfalse

交互说明 ​

  • 预览打开后支持鼠标拖拽图片、滚轮缩放图片。
  • 图片加载成功后可聚焦缩略图,通过 Enter / Space 打开预览;加载中、错误或 preview=false 时不会打开。
  • Tab 在预览内循环,关闭或卸载时恢复打开前的焦点;快捷键仅作用于最上层弹层。
  • 工具条默认深色半透明,悬浮和焦点使用浅色透明高亮。可覆盖 --x-image-preview-color-toolbar-bg 等 token 定制。
  • 满屏按容器较小轴缩放以保留完整图片,并遵守 0.25~5 倍范围。预览失败显示明确反馈,组内可继续切换下一张。
  • keyboard 为 true 时,Esc 关闭预览,左右方向键切换预览组,上下方向键缩放,Space 还原到原始大小。
  • 使用受控的 current / visible 时,请接收对应更新事件或使用 v-model;列表为空时预览不会显示。
  • srcList 初始下标超界时会发送 update:current 请求修正,受控模式等待父组件更新下标后显示有效图片。