<template> <div class='doc-image-upload'> <div class='text-12 description'>{{ description }}</div> <div class='mt-2 py-3 text-center upload-btn' @click='fileSelect'> <doc-icon type='doc-upload' class='mr-2 text-16' /> <span>{{ btText }}</span> </div> <div class='flex flex-wrap mt-4 image-box'> <div v-for="item in innerImage.filter(e => e.fileType != 'pdf')" :key='item.id' class='item-img' @click.stop='toPreview(item)'> <DocImage :src='item.trueDownloadUrl' remove @onRemove='removeImage(item)' /> </div> <div v-for="item in innerImage.filter(e => e.fileType == 'pdf')" :key='item.id' class='item-pdf'> <DocImage isPdf :src='item.trueDownloadUrl' name='pdf文件名称' remove @onRemove='removeImage(item)' /> </div> </div> <!-- accept='.jpg,.jpeg,.png,.pdf' --> <input type='file' accept="image/*" ref='fileElem' style='display: none;' @change='handleFiles' :key='inputKey'> <van-overlay :show='imgShow' @click='imgShow = false'> <div class='wrapper'> <van-swipe class='block' :initial-swipe='initSwipe'> <van-swipe-item v-for="image in innerImage.filter(e => e.fileType != 'pdf')" :key='image'> <img :src='image.trueDownloadUrl' style='width: 100%;height: 100%' /> </van-swipe-item> </van-swipe> </div> </van-overlay> </div> </template> <script> import DocImage from './DocImage.vue' import { showToast } from 'vant' import { fileUpload } from '@/api/base' import { useCustomFieldValue } from '@vant/use'; export default { name: 'DocImageUpload', components: { DocImage }, props: { // 上传描述 description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过10M' }, // 传入的img数据 { id, trueDownloadUrl } imageData: { default: () => [] }, // 上传按键的文字 btText: { default: '上传图片' }, // 图片框大小 size: String, // 上传最大数量 maxLength: { default: 1 }, lengthMessage: { default: '已达到图片上限,请移除后再上传' } }, data() { return { // 内部图片对象 innerImage: [], file: null, spinning: false, inputKey: '1', // viewer显示 visible: false, //显示图片所在位置 initSwipe: 0, imgShow: false } }, computed: { fileElem() { return this.$refs['fileElem'] }, ids() { return this.innerImage.map(e => e.id).join(',') } }, methods: { init() { if (this.imageData?.length) { this.innerImage = [...this.imageData] useCustomFieldValue(() => this.ids) } else { this.innerImage = [ // { fileType: 'pdf', id: 1, trueDownloadUrl: testUrl }, // { fileType: 'png', id: 2, trueDownloadUrl: testUrl }, // { fileType: 'png', id: 3, trueDownloadUrl: testUrl }, // { fileType: 'png', id: 4, trueDownloadUrl: testUrl } ] } }, fileSelect() { console.log(this.innerImage, this.maxLength) if (this.innerImage?.length >= this.maxLength) { showToast(this.lengthMessage) return } const dom = this.$refs['fileElem'] if (dom) { dom.click() } }, upload() { let formData = new FormData() formData.append('file', this.file) this.spinning = true fileUpload(formData).then(res => { // this.$message.success('上传成功') let result = res.data || {} this.$emit('upload', result) this.addImage(result) this.inputKey = Math.random().toString(16).substring(2, 6) this.$emit('change', this.ids, this.innerImage) useCustomFieldValue(() => this.ids) }).finally(() => { this.spinning = false }) }, handleFiles() { let files = this.$refs['fileElem'].files if (files.length <= 0) { showToast('未选中文件,请尝试重新选择') return } if (files[0].size / 1024 / 1024 > 10) { showToast('图片大小不能超过10M') return } this.file = files[0] this.upload() }, addImage(data = {}) { if (!data.id) { console.warn('addImage 文件为空') return } if (!this.innerImage.find(e => e.id === data.id)) { this.innerImage.push(data) } }, removeImage(item) { if (!item) return this.innerImage = this.innerImage.filter(e => e.id != item.id) this.$emit('change', this.ids, this.innerImage) useCustomFieldValue(() => this.ids) }, //图片预览 toPreview(val) { let res = this.innerImage.filter(e => e.fileType != 'pdf') let index = res.findIndex(e => val.id == e.id) this.initSwipe = index this.imgShow = true } }, watch: { imageData: { handler(value) { this.init() }, immediate: true } } } </script> <style lang='less' scoped> .description { color: #A5AEBE; } .upload-btn { color: var(--van-primary-color); border: 1px solid #eee; background-color: #FAFAFA; border-radius: 8px; } .image-box { row-gap: 8px; column-gap: 12px; .item-img { width: calc(33.3% - 8px); } .item-pdf { width: 100%; } > div { width: calc(33.3% - 8px); position: relative; border-radius: 2px; img { object-fit: contain; } } } .wrapper { display: flex; align-items: center; justify-content: center; height: 100%; .block { width: 100%; } } </style>