当前位置: 首页 > news >正文

封装el-upload组件,用于上传图片和视频的组件

使用环境 vue3+element plus
需要根据后端返回结构修改的函数:onPreview onRemove onSuccess

组件使用

基本使用

在这里插入图片描述
源代码:

<script setup>
import AutoUploadFile from '@/components/auto-upload-file/index.vue'
function change(urls){console.log(urls)
}
</script><template><AutoUploadFile @change="change"/>
</template><style lang="scss" scoped>
</style>

初始文件列表回显

在这里插入图片描述
源代码:

<script setup>
import AutoUploadFile from '@/components/auto-upload-file/index.vue'
import {ref} from "vue";const initUrls = ref(['http://127.0.0.1:9090/file/local-plus/6700f235df13a72064bf9167.png'
])function change(urls) {console.log(urls)
}
</script><template><AutoUploadFile :init-file-urls="initUrls" accept=".jpg,.jpeg,.png" @change="change"></AutoUploadFile>
</template><style lang="scss" scoped>
</style>

定义上传格式

如果有mp4类型,文件展示列表就会变为text

在这里插入图片描述
源代码:

<script setup>
import AutoUploadFile from '@/components/auto-upload-file/index.vue'
function change(urls){console.log(urls)
}
</script><template><AutoUploadFile accept=".jpg,.jpeg,.png,.mp4" :max-size="100" @change="change"/>
</template><style lang="scss" scoped>
</style>

自定义上传按钮样式

在这里插入图片描述
源代码:

<script setup>
import AutoUploadFile from '@/components/auto-upload-file/index.vue'
function change(urls){console.log(urls)
}
</script><template><AutoUploadFile accept=".jpg,.jpeg,.png,.mp4" :max-size="100" @change="change"><el-button>自定义上传样式</el-button></AutoUploadFile>
</template><style lang="scss" scoped>
</style>

组件属性

属性名属性类型默认值是否必填说明
initFileUrlsArray[]用于上传列表的回显,接收外部初始化url数组
listTypeStringpicture-card上传列表展示格式。可选项:picture-card/picture/text , 但是如果accept允许mp4,那么listType就会自动转化为text
actionString#上传文件时的接口服务
headersObject{}请求头
nameStringfile提交文件时的字段名
withCredentialsBooleantrue是否支持cookie凭证信息
showFileListBooleantrue是否展示上传列表
acceptString“.jpg,.jpeg,.png”可以上传的文件类型
limitNumber5允许上传的最大文件数量
maxSizeNumber5最大文件大小,单位MB
tipPrefixString“”提示信息前缀
showTipBooleantrue是否展示提示信息
showOverflowTooltipBooleantruetip过长是否使用省略号显示
multipleBooleantrue可以多选文件
autoUploadBooleantrue默认自动上传
sizeString100pxpicture-card的尺寸大小

组件事件

事件名事件参数列表说明
onProgress(e,file,fileList)用于监控文件上传进度
change(urls)上传列表改变时的回调

组件暴露方法

方法名参数列表说明
clearFiles()清空文件列表
submit()用于手动提交

组件插槽

插槽名插槽回显参数说明
default上传文件时的点击区域,用于自定义样式
file{ file }文件列表样式,用于自定义缩略图
trigger用于手动提交,只选择文件,不发起提交请求的插槽

组件源码:(auto-upload-file.vue)

<!--需要根据后端返回结构修改的函数:onPreview onRemove onSuccess -->
<script setup>
import {computed, onMounted, onUpdated, ref} from "vue";
import {ElMessage} from "element-plus";const prop = defineProps({// 文件列表initFileUrls: {type: Array,default: []},// 展示格式listType: {type: String,default: 'picture-card'},// 上传文件的默认接口action: {type: String,default: 'http://localhost:9090/upload/file'},// 请求头(添加token等)headers: {type: Object,default: {}},// 上传时的文件名(需要与后端接收时的字段保持一致)name: {type: String,default: 'file'},// 默认支持cookie凭证信息withCredentials: {type: Boolean,default: true},// 默认展示上传文件列表showFileList: {type: Boolean,default: true},// 可接受文件的类型accept: {type: String,default: '.jpg,.jpeg,.png'},// 允许上传的最大文件数量limit: {type: Number,default: 5},// 单位MBmaxSize: {type: Number,default: 5},// 提示前缀tipPrefix: {type: String,default: ''},// 是否展示提示showTip: {type: Boolean,default: true},// tip过长使用省略号显示showOverflowTooltip: {type: Boolean,default: true},// 可以多选文件multiple: {type: Boolean,default: true},// 默认自动上传autoUpload: {type: Boolean,default: true},// picture-card尺寸大小size: {type: String,default: '6.25rem'}
})const emit = defineEmits(['onProgress', 'change'])
defineExpose({clearFiles,submit
})// el-upload使用的文件列表
const fileList = ref(prop.initFileUrls.map(item => {return {name: getFileName(item),url: item}
}))const uploadRef = ref()// 存放后端返回的url,及初始化url
const urls = ref([...prop.initFileUrls])// 如果允许上传视频,则默认只能使用text显示上传列表
const listTypeCmp = computed(() => {return prop.accept.indexOf('mp4') !== -1 ? 'text' : prop.listType
})// 提示信息
const tip = computed(() => {return `${prop.tipPrefix ? prop.tipPrefix + ',' : ''}文件类型:${prop.accept.replaceAll(',', '/').replaceAll('.', '')},文件大小不能超过:${prop.maxSize}MB`
})// 文件上传之前的钩子
function beforeUpload(e) {const MB = e.size / (1024 * 1024)if (MB > prop.maxSize) {ElMessage.error(`文件的大小不能超过:${prop.maxSize}MB`)return false}
}// 上传成功的回调(根据后端返回值不同需要略作修改)
function onSuccess(e, file) {urls.value.push(e)emit('change', urls.value)
}const dialogFileUrl = ref()
const dialogVisible = ref(false)// 预览图片(根据后端返回值不同需要略作修改)
function onPreview(e) {dialogFileUrl.value = e.response || e.urldialogVisible.value = true
}// 移除文件(根据后端返回值不同需要略作修改)
function onRemove(e) {urls.value = urls.value.filter(item => item !== (e.response || e.url))emit('change', urls.value)
}// 超出最大文件限制时,执行的钩子函数
function onExceed(e) {ElMessage.error(`超出要求的文件最大数量:${prop.limit}`)
}// 文件上传失败时的回调
function onError() {ElMessage.error('文件上传失败')
}// 上传进度回调
function onProgress(e, file, fileList) {emit('onProgress', e, file, fileList)
}// 清空文件列表
function clearFiles() {uploadRef.value.clearFiles()urls.value = []emit('change', urls.value)
}// 手动提交
function submit() {uploadRef.value.submit()
}// 获取后缀
function getSuffix(url) {return url.substring(url.lastIndexOf('.') + 1)
}// 获取文件名
function getFileName(url) {return url.substring(url.lastIndexOf('/') + 1)
}// 阻止点击tip时触发的上传行为
function preventClick(event) {event.stopPropagation()
}// 初始化picture-card大小
function initSize() {const uploadListItem = document.querySelector('.el-upload-list--picture-card')const uploadPictureCard = document.querySelector('.el-upload--picture-card')if (uploadListItem) {uploadListItem.style.setProperty('--el-upload-list-picture-card-size', prop.size)}if (uploadPictureCard) {uploadPictureCard.style.setProperty('--el-upload-picture-card-size', prop.size)if (listTypeCmp.value==='picture-card'){uploadPictureCard.style['margin-bottom']='1.56rem'}}
}// 动态处理展示样式
function handleStyle() {initSize()
}onUpdated(() => {handleStyle()
})
onMounted(() => {handleStyle()
})</script><template><el-uploadref="uploadRef"class="upload-box"v-model:file-list="fileList":list-type="listTypeCmp":action="action":headers="headers":with-credentials="withCredentials":name="name":show-file-list="showFileList":before-upload="beforeUpload":on-success="onSuccess":on-remove="onRemove":on-preview="onPreview":accept="accept":limit="limit":on-exceed="onExceed":on-error="onError":on-progress="onProgress":auto-upload="autoUpload":multiple="multiple"><template #default v-if="autoUpload"><div class="upload"><div class="upload-default"><slot><el-icon v-if="listTypeCmp==='picture-card'"style="width: 100%;height: 100%;font-size: 1.88rem;color: #888888"><Plus/></el-icon><el-button v-else>上传文件</el-button></slot></div><div v-if="listTypeCmp==='picture-card' && showTip" class="upload-tip abs-tip" @click="preventClick"><div class="tip-div" :title="tip":class="{'text-overflow-ellipsis':showOverflowTooltip}"><span>{{ tip }}</span></div></div></div></template><template #tip v-if="listTypeCmp!=='picture-card' && showTip"><div class="upload-tip" @click="preventClick"><div class="tip-div" :title="tip":class="{'text-overflow-ellipsis':showOverflowTooltip}"><span>{{ tip }}</span></div></div></template><!--    自定义缩略图--><template #file="{file}"><slot name="file" :file="file"></slot></template><template #trigger v-if="!autoUpload"><slot name="trigger"></slot></template></el-upload><!--文件预览--><el-dialog v-model="dialogVisible" width="80%"><video style="height: 100%;width: 100%" v-if="getSuffix(dialogFileUrl)==='mp4'" :src="dialogFileUrl" controls/><el-image v-else style="height: 80vh" w-full :src="dialogFileUrl" alt="Preview Image"/></el-dialog>
</template><style lang="scss" scoped>.upload-box {box-sizing: border-box;.upload {position: relative;height: 100%;width: 100%;display: flex;justify-content: center;align-items: center;.abs-tip{position: absolute;bottom: -1.88rem;left: 0;}}.upload-tip {width: 100%;.tip-div {width: 100%;cursor: pointer;color: red;font-weight: 200;font-size: 0.75rem;}.text-overflow-ellipsis {display: inline-block;overflow: hidden;white-space: nowrap; /* 不换行 */text-overflow: ellipsis; /* 超出部分显示为省略号 */}}
}
</style>
http://www.lryc.cn/news/458797.html

相关文章:

  • 6.将扩散模型与其他生成模型的关联(2)
  • 【C++】基于红黑树封装set和map
  • 24最新新手入门指南:Stable Diffusion!
  • Java-基础
  • 二、后台管理系统布局菜单可拖动
  • socket和http区别
  • 算法:974.和可以被K整除的子数组
  • QD1-P8 HTML 格式化标签(font、pre、b、strong、i、u、del、s、sub、sup)
  • 红米Turbo 3工程固件预览 修复底层 体验原生态系统 默认开启diag端口
  • sql的调优指南及高级sql技巧
  • 生成式专题的第一节课---GAN图像生成
  • 中科星图GVE(案例)——AI实现建筑用地变化前后对比情况
  • Spring Boot中获取application.yml中属性的几种方式
  • YOLO11改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制
  • Python中函数的使用方法
  • 遨游智能终端赋能“危急特”场景,力推北斗技术规模化应用!
  • 构建流媒体管道:利用 Docker 部署 Nginx-RTMP 从 FFmpeg RTMP 推流到 HLS 播放的完整流程
  • 【汇编语言】寄存器(CPU工作原理)(六)—— 修改CS,IP的指令以及代码段
  • 机器学习与神经网络:从技术前沿到诺贝尔奖的跨越与未来展望
  • java 洛谷题单【数据结构1-2】二叉树
  • 项目优化内容及实战
  • 科研绘图系列:R语言蝴蝶图(Butterfly Chart)
  • 【FPGA开发】Modelsim如何给信号分组
  • Apache SeaTunnel 9月份社区发展记录
  • 系统架构设计师:数据库系统相关考题预测
  • 污水排放口细粒度检测数据集,污-水排放口的类型包括10类目标,10000余张图像,yolo格式目标检测,9GB数据量。
  • c++(多态)
  • 【网络协议】TCP协议常用机制——延迟应答、捎带应答、面向字节流、异常处理,保姆级详解,建议收藏
  • 财政部官宣: 国家奖学金,涨了!
  • antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头