Files
tra-app/src/components/image-preview/image-preview.vue
T
2025-07-14 17:42:47 +08:00

158 lines
3.3 KiB
Vue

<template>
<view v-bind="$attrs">
<image :src="imgUrlShow" fit="cover" :mode="mode" @click="showDetail" style="width: 100%;height: 100%;"></image>
<uv-overlay :show="showModel" opacity=".6" @click="showModel = false">
<view class="overlay-box">
<image class="detail-img" :src="imgUrlShow" fit="cover" :mode="mode"></image>
</view>
</uv-overlay>
</view>
</template>
<script>
import {previewFile, previewCacheThumbImage} from'@/api/common.js'
import { get_base_url } from '@/api/request.js'
import { useStorageStore } from "@/store/storage.js"
// const storageStore = useStorageStore()
export default {
name:"image-preview",
props:{
imgId:{
default:'',
type:String
},
src:{
default:'',
type:String
},
width:{
default:50,
type:[String, Number]
},
height:{
default:50,
type:[String, Number]
},
isCache:{ // 获取缩略图
type: Boolean,
default: false
},
mode:{
type: String,
default: 'widthFix'
},
previewDetail: {
default: '',
type:[String, Boolean]
}
},
data() {
return {
imgUrlShow: '',
watching: false,
base_url: get_base_url(),
showModel: false
};
},
computed:{
storageStore:() => useStorageStore(),
imageObj() {
return this.storageStore?.imgObj||{}
}
},
watch: {
imgId: {
handler(newval, oldval) {
if(newval.indexOf('http') === 0){
this.imgUrlShow = newval
return
}
if (newval && this.watching) {
this.getPreviewUrlBlob(newval);
}
},
immediate: true,
deep: true,
},
src: {
handler(newval, oldval) {
if (newval && this.watching) {
this.imgUrlShow = this.base_url + this.src
}
},
immediate: true,
deep: true,
}
},
methods: {
showDetail(){
if(!!this.previewDetail){
this.showModel = true
}
},
getPreviewUrlBlob(id) {
if (!id) {
this.imgUrlShow = ''
return
}
if(this.isCache){
let _cache = this.imageObj[`/${id}/${this.width}/${this.height}`] || ''
if(_cache){
this.imgUrlShow = _cache;
return
}
previewCacheThumbImage(id, this.width,this.height).then((res) => {
this.imgUrlShow = res;
this.storageStore.setStorage('image', `/${id}/${this.width}/${this.height}`, res)
});
}else{
let _cache = this.imageObj[`${id}`] || ''
if(_cache){
this.imgUrlShow = _cache;
return
}
previewFile(id).then((result) => {
//#ifdef APP-PLUS
let _header = result.header['Content-Type'].split(';')[0]
// #endif
//#ifndef APP-PLUS
let _header = result.header['content-type'].split(';')[0]
// #endif
let base64 = `data:${_header};base64,` + uni.arrayBufferToBase64(result.data)
this.imgUrlShow = base64;
this.storageStore.setStorage('image', id, base64)
});
}
},
},
mounted() {
if (this.imgId) {
if(this.imgId.indexOf('http') === 0){
this.imgUrlShow = this.imgId
}else{
this.getPreviewUrlBlob(this.imgId);
}
}
this.watching = true
if(this.src) {
this.imgUrlShow = this.base_url + this.src
}
}
}
</script>
<style lang="scss" scoped>
.overlay-box{
position: relative;
height: 100%;
.detail-img{
position: absolute;
left: 50%;
top: 50%;
max-width: 100%;
max-height: 100%;
transform: translate(-50%, -50%);
}
}
</style>