| | |
| | | <template> |
| | | <el-dialog |
| | | :model-value="dialogVisible" |
| | | @opened="$emit('update:dialogVisible', true)" |
| | | @closed="$emit('update:dialogVisible', false)" |
| | | @opened="handleOpen" |
| | | @closed="handleClose" |
| | | width="66%" |
| | | destroy-on-close |
| | | > |
| | | <div class="main"> |
| | | <div class="main" v-loading="loading"> |
| | | <el-row justify="end" v-if="!readonly"> |
| | | <el-text size="small" type="info" class="m-r-8" |
| | | >最多选择{{ maxSelect }}张图片</el-text |
| | |
| | | class="imgs" |
| | | > |
| | | <el-image |
| | | v-loading="img.loading" |
| | | v-for="(img, i) in typeImgMap.get(activeId)" |
| | | :key="i" |
| | | :class="[img.isSelect ? 'selected' : 'noActive', 'image']" |
| | | fit="cover" |
| | | :src="img.url" |
| | | lazy |
| | | @click="onSelect(img, i)" |
| | | @load="onOneImgLoadSuccess(img)" |
| | | @error="onOneImgLoadError(img)" |
| | | /> |
| | | </el-scrollbar> |
| | | <el-row v-else justify="space-between"> |
| | |
| | | </el-dialog> |
| | | </template> |
| | | <script setup> |
| | | import { ref, watch } from 'vue'; |
| | | import { ref, watch, computed, onMounted, onUnmounted } from 'vue'; |
| | | |
| | | const props = defineProps({ |
| | | dialogVisible: Boolean, |
| | |
| | | // const typeImgMap = ref(new Map()); |
| | | const selectedImgUrlList = ref([]); |
| | | |
| | | let loadedImgCount = ref(0); |
| | | // 加载状态 |
| | | const loading = computed(() => { |
| | | if (activeId.value == '') { |
| | | return false; |
| | | } |
| | | // 保证最开始是加载状态,三分之一加载之后停止展示加载状态 |
| | | return !( |
| | | props.typeImgMap.get(activeId.value).length / 3 <= |
| | | loadedImgCount.value |
| | | ); |
| | | }); |
| | | function onOneImgLoadError(img) { |
| | | img.loading = false |
| | | loadedImgCount.value++; |
| | | } |
| | | function onOneImgLoadSuccess(img) { |
| | | img.loading = false |
| | | loadedImgCount.value++; |
| | | } |
| | | watch( |
| | | () => activeId.value, |
| | | (nV, oV) => { |
| | | loadedImgCount.value = 0; |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | function onSelect(img, i) { |
| | | if (props.readonly) { |
| | | return; |
| | |
| | | img.isSelect = false; |
| | | } |
| | | } |
| | | |
| | | function handleOpen() { |
| | | // if (props.typeImgMap.get(activeId.value) == undefined) { |
| | | // return; |
| | | // } |
| | | // props.typeImgMap.get(activeId.value).forEach((i) => { |
| | | // if (i.isSelect == true) { |
| | | // return; |
| | | // } |
| | | // props.defaultFile.forEach((imgItem) => { |
| | | // if (imgItem.url == i.url) { |
| | | // i.isSelect = true; |
| | | // selectedImgUrlList.value.push(i); |
| | | // } |
| | | // }); |
| | | // }); |
| | | emit('update:dialogVisible', true) |
| | | } |
| | | function handleClose() { |
| | | selectedImgUrlList.value.forEach(item => item.isSelect = false) |
| | | selectedImgUrlList.value = [] |
| | | emit('update:dialogVisible', false) |
| | | } |
| | | function handleSubmit() { |
| | | emit('submit', selectedImgUrlList.value); |
| | | emit('update:dialogVisible', false); |
| | |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | // watch( |
| | | // () => props.defaultFile, |
| | | // (nV, oV) => { |
| | | // if (props.typeImgMap.get(activeId.value) == undefined) { |
| | | // return; |
| | | // } |
| | | // props.typeImgMap.get(activeId.value).forEach((i) => { |
| | | // if (i.isSelect == true) { |
| | | // return; |
| | | // } |
| | | // nV.forEach((imgItem) => { |
| | | // if (imgItem.url == i.url) { |
| | | // i.isSelect = true; |
| | | // selectedImgUrlList.value.push(i); |
| | | // } |
| | | // }); |
| | | // }); |
| | | // }, |
| | | // { deep: true, immediate: true } |
| | | // ); |
| | | |
| | | watch( |
| | | () => props.typeImgMap, |
| | | (newMap, oldMap) => { |
| | | if (newMap.get(activeId.value) == undefined) { |
| | | return; |
| | | } |
| | | newMap.get(activeId.value).forEach((i) => { |
| | | if (i.isSelect == true) { |
| | | return; |
| | | } |
| | | props.defaultFile.forEach((imgItem) => { |
| | | if (imgItem.url == i.url) { |
| | | i.isSelect = true; |
| | | selectedImgUrlList.value.push(i); |
| | | } |
| | | }); |
| | | }); |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | // watch( |
| | | // () => props.typeImgMap, |
| | | // (newMap, oldMap) => { |
| | | // if (newMap.get(activeId.value) == undefined) { |
| | | // return; |
| | | // } |
| | | // newMap.get(activeId.value).forEach((i) => { |
| | | // if (i.isSelect == true) { |
| | | // return; |
| | | // } |
| | | // props.defaultFile.forEach((imgItem) => { |
| | | // if (imgItem.url == i.url) { |
| | | // i.isSelect = true; |
| | | // selectedImgUrlList.value.push(i); |
| | | // } |
| | | // }); |
| | | // }); |
| | | // }, |
| | | // { immediate: true } |
| | | // ); |
| | | </script> |
| | | <style scoped> |
| | | .center { |
| | |
| | | |
| | | .main { |
| | | margin: 0 auto; /* 使父元素居中 */ |
| | | height: 100%; |
| | | height: 72vh; |
| | | width: 100%; |
| | | } |
| | | |
| | | .imgs { |
| | | height: 50vh; |
| | | height: 60vh; |
| | | width: 100%; |
| | | min-height: 100px !important; |
| | | /* border-style:solid; |
| | |
| | | } |
| | | |
| | | ::v-deep .el-dialog__body { |
| | | height: 60vh; |
| | | padding: 10px calc(var(--el-dialog-padding-primary) + 10px) !important; |
| | | } |
| | | </style> |