基于vue3,elementPlus的el-upload的二次封装组件,支持多传 数量控制
upload.vue
<template>
<!-- 2022/8/29 Carter -->
<el-upload
v-model:file-list="fileLists"
:action="actionUrl"
:limit="limit"
:disabled="disabled"
list-type="picture-card"
:auto-upload="true"
:multiple="false"
:accept="accept"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:http-request="httpRequest"
:class="{ limitOpctin: limit === fileLists.length }"
>
<el-icon><Plus /></el-icon>
</el-upload>
<el-dialog v-model="dialogVisible">
<img style="width: 90%" w-full :src="dialogImageUrl" alt="图片预览" />
</el-dialog>
</template>
<script setup>
/**
* @desc 封装 element UI el-upload
* @param {fileLists} [v-model] - 双向绑定的值
* @param {Number} [limit] [v-bind]- 上传个数限制
* @param {String} [accept] [v-bind]- 上传后缀的限制
* @param {disabled} [Boolean] [v-bind]- 是否禁用
* @example <UpLoad :limit='1' v-model:fileLists='ruleForm.fileLists' accept='image/png,image/jpg'/>
*/
import { ref, onMounted } from 'vue'
import { Plus, Delete, ZoomIn } from '@element-plus/icons-vue'
import { config } from '@/assets/js/config'
const props = defineProps({
limit: {
type: Number,
default: 1
},
accept: {
type: String,
default: 'image/png,image/jpeg,image/gif,image/jpg'
},
fileLists: {
type: Array,
default: [],
required: true
},
disabled: {
type: Boolean,
default: false
}
})
const infoList = ref([])
const dialogImageUrl = ref('')
const percent = ref(0)
const actionUrl = ref('#')
const dialogVisible = ref(false)
const emit = defineEmits(['update:fileLists'])
onMounted(() => {
infoList.value = props.fileLists || []
})
const handleRemove = uploadFile => {
infoList.value.forEach((v, i) => {
if (v.uid == uploadFile.uid) {
infoList.value.splice(i, 1)
}
})
emit('update:fileLists', infoList.value)
}
const handlePictureCardPreview = uploadFile => {
dialogImageUrl.value = uploadFile.url
dialogVisible.value = true
}
const httpRequest = async params => {
const file = params.file
// 文件名(8位随机数):zokcutz4.jpg
const fileName =
Math.random().toString(36).substr(-8) +
file.name.substr(file.name.lastIndexOf('.'))
// 目录加文件名【上线前修改目录名】
const fileSrc = `test20220824/${fileName}`
try {
params.onProgress({ percent: 0 })
//上传的自定义逻辑都在这里
infoList.value = [
...infoList.value,
{
uid: file.uid,
name: file.name,
url: `${config.awsUrl}${res.key}`
}
]
// console.log(`上传成功 ${res.key}`)
emit('update:fileLists', infoList.value)
params.onSuccess()
} catch (err) {
console.log(err, 'err')
ElMessage.error('网络错误,请稍后重试')
params.onError()
}
}
</script>
<style lang="scss" scoped>
.limitOpctin :deep(.el-upload--picture-card) {
display: none !important;
}
</style>
页面使用
<template>
<!-- 2022/8/30 Carter 页面 -->
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="140px"
class="demo-ruleForm"
size="default"
status-icon
>
<el-form-item label="上传背景图" prop="bgLists">
<!-- 上传使用 -->
<UpLoad
v-model:fileLists="ruleForm.bgLists"
accept="image/png,image/jpg,image/gif"
/>
<div style="width: 500px">支持的图片格式为PNG,JPG,GIF</div>
</el-form-item>
<el-form-item label="上传图片" prop="fileLists">
<UpLoad
v-model:fileLists="ruleForm.fileLists"
accept="image/png,image/jpg,image/gif"
/>
<div style="width: 500px">支持的图片格式为PNG,JPG,GIF</div>
</el-form-item>
</el-form>
</template>
<script setup>
import UpLoad from '@/components/form/upload.vue'
</script>