文件上传
属性与方法
< ! -- 属性1 . multiple多选2 . action上传文件服务器地址3 . before-upload上传前校检格式和大小4 . file-list上传的文件列表5 . limit数量限制6 . on-error上传失败触发7 . on-exceed文件个数超出触发8 . on-success上传成功触发9 . show-file-list是否显示已上传文件列表( 我这块点击文件名要展示文件,所以自定义了一个文件列表,加了触发事件) 10 .headers 设置上传的请求头部-->
完整代码
< template> < div class = "upload-file" > < el-upload multiple :action= "uploadFileUrl" :before-upload= "handleBeforeUpload" :file-list= "fileList" :limit= "limit" :on-error= "handleUploadError" :on-exceed= "handleExceed" :on-success= "handleUploadSuccess" :show-file-list= "false" :headers= "headers" class = "upload-file-uploader" ref = "fileUpload" > < ! -- 上传按钮 --> < el-button type = "primary" > 选取文件< /el-button> < /el-upload> < ! -- 上传提示 --> < div class = "el-upload__tip" v-if= "showTip" > 请上传< template v-if= "fileSize" > 大小不超过 < b style = "color: #f56c6c" > { { fileSize } } MB< /b> < /template> < template v-if= "fileType" > 格式为 < b class = "auto-wrap" > { { fileType.join( "/" ) } } < /b> < /template> 的文件< /div> < ! -- 文件列表 --> < transition-group class = "upload-file-list el-upload-list el-upload-list--text" name = "el-fade-in-linear" tag = "ul" > < li :key= "file.uid" class = "el-upload-list__item ele-upload-list__item-content" v-for= "(file, index) in fileList" > < ! -- 打开新窗口预览文件 --> < el-link :href= "` ${ baseUrl} ${ file.url} ` " :underline= "false" target = "_blank" > < span class = "el-icon-document" > { { file.name } } < /span> < /el-link> < div class = "ele-upload-list__item-content-action" > < el-link :underline= "false" @click= "handleDelete(index)" type = "danger" > 删除< /el-link> < /div> < /li> < /transition-group> < /div>
< /template> < script setup>
import { getToken } from "@/utils/auth" ; const props = defineProps( { modelValue: [ String, Object, Array] , //默认文件列表数据// 数量限制limit: { type: Number,default: 5 ,} ,// 大小限制( MB) fileSize: { type: Number,default: 500 ,} ,// 文件类型, 例如[ 'png' , 'jpg' , 'jpeg' ] fileType: { type: Array,default: ( ) = > [ "doc" , "xls" , "ppt" , "txt" , "pdf" ] ,} ,// 是否显示提示isShowTip: { type: Boolean,default: true }
} ) ; const { proxy } = getCurrentInstance( ) ;
const emit = defineEmits( ) ;
const number = ref( 0 ) ; // 只要通过上传校验就给number+1;上传成功一个-1个,都上传成功后重置为0
const uploadList = ref( [ ] ) ;
const baseUrl = import.meta.env.VITE_APP_BASE_API; //访问的文件前缀
const uploadFileUrl = ref( import.meta.env.VITE_APP_BASE_API + "/common/upload4model" ) ; // 上传文件服务器地址
const headers = ref( { Authorization: "Bearer " + getToken( ) } ) ;
const fileList = ref( [ ] ) ;
const showTip = computed( ( ) = > props.isShowTip && ( props.fileType || props.fileSize)
) ; watch(( ) = > props.modelValue, val = > { if ( val) { let temp = 1 ; // 首先将值转为数组const list = Array.isArray( val) ? val : props.modelValue.split( ',' ) ; // 然后将数组转为对象数组fileList.value = list.map( item = > { if ( typeof item == = "string" ) { item = { name: item, url: item } ; } if ( ! item.url) { item.url = baseUrl + item.fileName; } item.uid = item.uid || new Date( ) .getTime( ) + temp++; return item; } ) ; } else { fileList.value = [ ] ; return [ ] ; }
} , { deep: true, immediate: true } ) ; // 上传前校检格式和大小
function handleBeforeUpload( file) { // 校检文件类型if ( props.fileType.length) { const fileName = file.name.split( '.' ) ; const fileExt = fileName[ fileName.length - 1 ] ; const isTypeOk = props.fileType.indexOf( fileExt) >= 0 ; if ( ! isTypeOk) { proxy.$modal .msgError( ` 文件格式不正确, 请上传${ props.fileType.join( "/" ) } 格式文件! ` ) ; return false ; } } // 校检文件大小if ( props.fileSize) { const isLt = file.size / 1024 / 1024 < props.fileSize; if ( ! isLt) { proxy.$modal .msgError( ` 上传文件大小不能超过 ${ props.fileSize} MB! ` ) ; return false ; } } // proxy.$modal .loading( "正在上传文件,请稍候..." ) ; number.value++; return true ;
} // 文件个数超出
function handleExceed ( ) { proxy.$modal .msgError( ` 上传文件数量不能超过${ props.limit} 个!` ) ;
} // 上传失败
function handleUploadError( err) { proxy.$modal .msgError( "上传文件失败" ) ;
} // 上传成功回调
function handleUploadSuccess( res, file ) { if ( res.code == = 200 ) { uploadList.value.push( res) ; uploadedSuccessfully( ) ; } else { number.value--; // proxy.$modal .closeLoading( ) ; proxy.$modal .msgError( res.msg) ; proxy.$refs .fileUpload.handleRemove( file) ; // 上传失败时手动触发组件的外部方法handleRemoveuploadedSuccessfully( ) ; }
} // 删除文件
function handleDelete( index) { fileList.value.splice( index, 1 ) ; emit( "update:modelValue" , fileList.value) ; // 删除文件后更新父组件文件列表
} // 上传结束处理
function uploadedSuccessfully ( ) { if ( number.value > 0 && uploadList.value.length == = number.value) { fileList.value = fileList.value.filter( f = > f.url != = undefined) .concat( uploadList.value) ; uploadList.value = [ ] ; number.value = 0 ; emit( "update:modelValue" , fileList.value) ; //更新父组件文件列表fileList数据// proxy.$modal .closeLoading( ) ; }
} < /script> < style scoped lang = "scss" >
.upload-file-uploader { margin-bottom: 5px;
} .upload-file-list .el-upload-list__item { border: 1px solid line-height: 2 ; margin-bottom: 10px; position: relative;
} .upload-file-list .ele-upload-list__item-content { display: flex; justify-content: space-between; align-items: center; color: inherit;
} .ele-upload-list__item-content-action .el-link { margin-right: 10px;
} .auto-wrap { width: 100 %; word-wrap: break-word; /* 旧版本浏览器支持 */overflow-wrap: break-word; /* 标准属性 */word-break: break-all; color:
}
< /style>
组件使用
< ! -- 1 . modelValue对应的文件列表数据2 . limit限制文件上传数量3 . fileType限制上传的文件类型4 . @update:modelValue更新文件列表数据
-->
< FileUpload :modelValue= "form.attachmentList" @update:modelValue= "fileUploadInput" :fileType= "fileType[form.dataType]" :limit= "form.dataType == 2 ? 20 : 1" > < /FileUpload>