Vue2.7 多图片自定义上传组件封装 发表于 2023-02-15 | 分类于 Components 多图片自定义上传 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226<template> <div class="com-multiple-upload"> <el-upload ref="multipleUpload" action="" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-change="change" :auto-upload="autoUpload" :on-exceed="exceed" :accept="accept" :limit="limit" :file-list="fileListArr" multiple :class="{ hide: isDisabled }" > <i class="el-icon-plus"></i> <div slot="file" slot-scope="{file}"> <img class="el-upload-list__item-thumbnail" :src="file.url || `data:${file.contentType};base64,${file.fileContent}`" alt=""/> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)"> <i class="el-icon-zoom-in"></i> </span> <span v-if="!isView" class="el-upload-list__item-delete" @click="handleRemove(file)"> <i class="el-icon-delete"></i> </span> </span> </div> </el-upload> </div></template><script lang="ts">import { defineComponent } from 'vue'export default defineComponent({ name: 'ComMultipleImgUpload'})</script><script setup lang="ts">import { useAttrs, getCurrentInstance, computed, PropType, ref, nextTick } from 'vue'import PreviewPic from '_c/Preview/index'import { changeLimit } from '@/utils'const emit = defineEmits(['emitUploadImgList', 'emitDelImgList'])const root = (getCurrentInstance() as any).proxyconst refs = root.$refsconst attrs = useAttrs()const props = defineProps({ // 图片url imgUrl: { type: String, default: '' }, // 上传框宽度 conWidth: { type: String, default: '146px' }, // 上传框高度 conHeight: { type: String, default: '146px' }, // 类型 accept: { type: String, default: 'image/jpg,image/jpeg,image/png' }, // 上传地址 action: { type: String, default: '' }, showFileList: { type: Boolean, default: false }, // 自动上传 autoUpload: { type: Boolean, default: false }, // 提示文字 uploadText: { type: String, default: '选择照片' }, // 是否需要边框 border: { type: Boolean, default: true }, onChange: { type: Function as PropType<Fn>, default: undefined }, limit: { type: Number, default: 9 }, fileListArr: { type: Array, default: () => [] }, // 最大szie kb maxSize: { type: Number as PropType<Nullable<number>>, default: 400 }, // 最小size kb minSize: { type: Number as PropType<Nullable<number>>, default: 0 }, isView: { type: Boolean, default: false }})// 获取绑定的值const getBindValue = computed(() => { const bindValue = { ...attrs, ...props } as IObj delete bindValue.action delete bindValue.accept delete bindValue.showFileList delete bindValue.autoUpload delete bindValue.onChange return bindValue})// 预览function handleImgPreview(item) { // event.stopPropagation() // refs.elImage.clickHandler() PreviewPic({ index: 9999, list: [item], zIndex: 9999 })}// 获取上传组件function getUploadRef() { return refs.elUpload}// 文件变化的时候function change(file: any, fileList) { const type = file.raw.type const filename = file.raw.name const ext = filename.substr(filename.lastIndexOf('.')) if (props.accept.includes(type) || props.accept.includes(ext)) { const size = (file.size / 1024).toFixed(2) if ((props as any).minSize && size < (props as any).minSize) { root.$message.warning('文件大小小于' + changeLimit((props as any)?.minSize as number)) return } if ((props as any).maxSize && size > (props as any).maxSize) { root.$message.warning('文件大小不超过' + changeLimit((props as any)?.maxSize as number)) // 超出的是第几张图片 const curIdx = fileList.indexOf(file) fileList.splice(curIdx, 1) return } if (props.onChange) { ;(props as any)?.onChange(file) } emit('emitUploadImgList', fileList) } else { root.$message.warning('请选择正确的文件类型') }}const autoUpload = ref<boolean>(false)// 要删除的图片数组const delFileImgArr = ref([])function handleRemove(file) { // 已经上传了的图片 if (file.fileId) { delFileImgArr.value.push(file.fileId) } const index = refs.multipleUpload.uploadFiles.findIndex(e => e.uid === file.uid) refs.multipleUpload.uploadFiles.splice(index, 1) const fileList = refs.multipleUpload.uploadFiles emit('emitUploadImgList', fileList) emit('emitDelImgList', delFileImgArr.value) // console.log(fileList, 'fileList', refs.multipleUpload.uploadFiles)}const isDisabled = computed(() => { return props.fileListArr.length === props.limit})function handlePictureCardPreview(file) { if (file.url) { handleImgPreview(file.url) } else { const backImgUrl = `data:${file.contentType};base64,${file.fileContent}` handleImgPreview(backImgUrl) }}function exceed() { root.$message.warning(`上传文件总数不得超过${props.limit}张!`)}nextTick(() => { console.log(props.fileListArr, 'nextTick')})defineExpose({ getUploadRef})</script><style lang="less" scoped>.com-multiple-upload { /deep/ .hide .el-upload--picture-card { display: none; }}</style>