53 lines
1.6 KiB
Vue
53 lines
1.6 KiB
Vue
<script setup lang="ts">
|
|
import { NButton, NImage } from 'naive-ui'
|
|
import { computed, ref, watch } from 'vue'
|
|
import { ImageOff } from '@lucide/vue'
|
|
import { referenceImageUrl } from '../../lib/assets'
|
|
|
|
/** 安全图片展示;铺满与原图预览按场景开启,历史选择按钮默认不触发预览。 */
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
src?: string | null
|
|
alt: string
|
|
emptyText?: string
|
|
retryable?: boolean
|
|
objectFit?: 'contain' | 'cover'
|
|
preview?: boolean
|
|
}>(),
|
|
{ retryable: true, objectFit: 'contain', preview: false }
|
|
)
|
|
const failed = ref(false)
|
|
const url = computed(() => (props.src ? referenceImageUrl(props.src) : null))
|
|
watch(
|
|
() => props.src,
|
|
() => {
|
|
failed.value = false
|
|
}
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="asset-image">
|
|
<NImage
|
|
v-if="url && !failed"
|
|
:src="url"
|
|
:preview-src="url"
|
|
:alt="alt"
|
|
lazy
|
|
:preview-disabled="!preview"
|
|
:object-fit="objectFit"
|
|
:img-props="{ referrerpolicy: 'no-referrer' }"
|
|
:previewed-img-props="{ alt, referrerpolicy: 'no-referrer' }"
|
|
@error="failed = true"
|
|
/>
|
|
<span v-else class="asset-image-empty"
|
|
><ImageOff :size="22" :stroke-width="1.3" /><span>{{
|
|
src ? '图片无法加载' : emptyText || '尚未生成图片'
|
|
}}</span
|
|
><NButton v-if="failed && retryable" @click.stop="failed = false" text size="small">
|
|
重试加载
|
|
</NButton></span
|
|
>
|
|
</div>
|
|
</template>
|