ImageDisplay
Introduction
The ImageDisplay component is a feature-rich image display component that supports image grid layout, click preview, error handling, and more. It’s suitable for scenarios that require displaying multiple images, such as photo albums, product image displays, user avatar lists, etc. The component supports multiple size configurations and provides smooth interaction experience and elegant error handling.
Examples
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="4"
@image-click="handleImageClick"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
// 使用固定的随机种子,确保服务端和客户端一致
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
// 使用固定的标签,确保一致性
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
// 头像使用固定种子
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
// 产品图片使用固定标签
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
// 机器人头像使用固定种子
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
// 占位符图片使用固定文本
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
const handleImageClick = (imageUrl: string) => {
console.log('点击了图片:', imageUrl);
};
</script>
Props
images
Array of image URLs, required property.
<template>
<div>
<ImageDisplay
:images="fewImages"
size="md"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const fewImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable2',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="mediumImages"
size="md"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const mediumImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="manyImages"
size="md"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const manyImages = [
// 使用不同的图片服务提供商,但保持稳定的随机种子
...Array.from({ length: 3 }, (_, i) =>
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: `stable-picsum-${i + 1}`,
})
),
...Array.from({ length: 3 }, (_, i) =>
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: ['nature', 'city', 'food'][i],
randomSeed: `stable-picsum-${i + 1}`,
})
),
...Array.from({ length: 3 }, (_, i) =>
getAvatarImage({ width: 200, height: 200, randomSeed: `user${i + 1}` })
),
...Array.from({ length: 3 }, (_, i) =>
getProductImage({
width: 200,
height: 200,
tag: ['tech', 'fashion', 'home'][i],
randomSeed: `stable-product-${i + 1}`,
})
),
];
</script>
maxDisplay
Maximum number of images to display, overflow will show “+N more” indicator.
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="3"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="4"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
showPreview
Whether to show preview functionality, when set to false, clicking an image will trigger the imageClick event.
点击图片可预览大图
点击图片会触发 imageClick 事件
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="4"
@image-click="handleImageClick"
/>
<p class="text-xs text-gray-500 mt-1">点击图片可预览大图</p>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable2',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable3',
}),
];
const handleImageClick = (imageUrl: string) => {
console.log('点击了图片:', imageUrl);
alert(`点击了图片: ${imageUrl}`);
};
</script>
点击图片可预览大图
点击图片会触发 imageClick 事件
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="false"
:max-display="4"
@image-click="handleImageClick"
/>
<p class="text-xs text-gray-500 mt-1">点击图片会触发 imageClick 事件</p>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable2',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable3',
}),
];
const handleImageClick = (imageUrl: string) => {
console.log('点击了图片:', imageUrl);
alert(`点击了图片: ${imageUrl}`);
};
</script>
size
Image size, supports sm, md, lg three sizes.
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="sm"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
<template>
<div>
<ImageDisplay
:images="sampleImages"
size="lg"
:show-preview="true"
:max-display="6"
/>
</div>
</template>
<script setup lang="ts">
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
getLandscapeImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable2',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable3',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'robohash',
randomSeed: 'robot1',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'placeholder',
tag: 'Image 6',
randomSeed: 'stable4',
}),
];
</script>
Events
imageClick
Image click event, triggered when showPreview is false.
事件处理示例
点击图片查看控制台输出
<template>
<div class="space-y-4">
<div>
<h4 class="text-sm font-medium mb-2">事件处理示例</h4>
<ImageDisplay
:images="sampleImages"
size="md"
:show-preview="false"
:max-display="4"
@image-click="handleImageClick"
/>
<p class="text-xs text-gray-500 mt-1">点击图片查看控制台输出</p>
</div>
<div v-if="clickedImages.length > 0">
<h4 class="text-sm font-medium mb-2">已点击的图片:</h4>
<div class="space-y-2">
<div
v-for="(image, index) in clickedImages"
:key="index"
class="flex items-center space-x-2 p-2 bg-gray-100 rounded"
>
<img
:src="image"
alt="点击的图片"
class="w-8 h-8 object-cover rounded"
/>
<span class="text-sm">{{ image }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ImageDisplay } from '@coffic/cosy-ui/vue';
import {
getExampleImage,
getAvatarImage,
getProductImage,
} from '@coffic/cosy-ui/vue';
// 使用稳定的图片URL,避免水合不匹配
const sampleImages = [
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
randomSeed: 'stable1',
}),
getAvatarImage({ width: 200, height: 200, randomSeed: 'user1' }),
getProductImage({
width: 200,
height: 200,
tag: 'tech',
randomSeed: 'stable2',
}),
getExampleImage({
width: 200,
height: 200,
provider: 'picsum',
tag: 'nature',
randomSeed: 'stable3',
}),
];
const clickedImages = ref<string[]>([]);
const handleImageClick = (imageUrl: string) => {
console.log('点击了图片:', imageUrl);
clickedImages.value.push(imageUrl);
};
</script>