feat(web): 支持后台列表图片大图预览
This commit is contained in:
1 parent
046400ae4a
commit
8a84f24baf
10 files changed
+202
-13
No files matched your search
@@ -0,0 +1,5 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import AppImage from './src/AppImage.vue'
|
||||
|
||||
export { AppImage }
|
||||
@@ -0,0 +1,94 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { ElImage } from 'element-plus'
|
||||
import { AppIcon } from '@/components/AppIcon'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
|
||||
const props = defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
previewList: {
|
||||
type: Array as () => string[],
|
||||
default: () => []
|
||||
},
|
||||
initialIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
fit: {
|
||||
type: String as PropType<'fill' | 'contain' | 'cover' | 'none' | 'scale-down'>,
|
||||
default: 'cover'
|
||||
},
|
||||
class: {
|
||||
type: [String, Array, Object],
|
||||
default: ''
|
||||
},
|
||||
style: {
|
||||
type: [String, Array, Object],
|
||||
default: undefined
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const resolvedPreviewList = computed(() => {
|
||||
const images = (props.previewList || []).filter(Boolean)
|
||||
return images.length ? images : [props.src]
|
||||
})
|
||||
|
||||
const resolvedInitialIndex = computed(() =>
|
||||
Math.max(0, Math.min(props.initialIndex, resolvedPreviewList.value.length - 1))
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElImage
|
||||
v-bind="$attrs"
|
||||
:src="src"
|
||||
:alt="alt"
|
||||
:fit="fit"
|
||||
:preview-src-list="resolvedPreviewList"
|
||||
:initial-index="resolvedInitialIndex"
|
||||
:preview-teleported="true"
|
||||
:hide-on-click-modal="true"
|
||||
:class="['app-image', props.class]"
|
||||
:style="style"
|
||||
>
|
||||
<template #error>
|
||||
<div class="app-image-error">
|
||||
<AppIcon :icon="AppIcons.error" :size="20" />
|
||||
</div>
|
||||
</template>
|
||||
</ElImage>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.app-image {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.app-image :deep(.el-image__inner) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.app-image-error {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: var(--el-text-color-placeholder);
|
||||
background: var(--el-fill-color-lighter);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -3,10 +3,12 @@
|
||||
import type { App } from 'vue'
|
||||
import { Icon } from './Icon'
|
||||
import { AppIcon } from './AppIcon'
|
||||
import { AppImage } from './AppImage'
|
||||
import { BaseButton } from './Button'
|
||||
|
||||
export const setupGlobCom = (app: App<Element>): void => {
|
||||
app.component('Icon', Icon)
|
||||
app.component('AppIcon', AppIcon)
|
||||
app.component('AppImage', AppImage)
|
||||
app.component('BaseButton', BaseButton)
|
||||
}
|
||||
Reference in new issue
Block a user