element-ui实现各种证件照上传预览下载组件封装,图片上传回显及长宽自定义功能单个图片上传功能附带源码

element-ui实现证件照上传预览下载组件封装

效果:

![element ui 实现证件的上传下载预览功能](https://img-blog.csdnimg.cn/direct/5a0f2944fbb44902aa2adbc606ecfb53.gi

参数说明

我只写了两个参数,后续有需求再对其组件进行丰富~

参数说明
fileListProp用来存储上传后后端返回的图片UR了
uploadUrl图片上传返回的URL后端接口地址
widthProp图片上传框的宽度
heightProp图片上传框的高度

方法说明

参数说明
beforeUpload(file)在文件上传前的钩子函数。用于检查文件的类型和大小,如果文件不符合条件,则显示相应的错误信息并停止上传。该方法也负责创建本地预览URL,并通过直接调用directUpload方法来处理文件的上传逻辑,同时避免使用el-upload组件默认的上传行为。
handleUploadFailure(file)处理文件上传失败的逻辑。该方法从fileList中移除当前文件,并显示上传失败的消息。
handleUploadResponse(responseData, file)处理文件上传成功的响应。该方法根据后端返回的数据更新fileList,并确保上传的文件在列表中显示。
handleRemove(file, fileList, name)处理文件的删除操作。从fileList中移除指定的文件,并清空临时存储的图片信息。
handleExceed(files, fileList, num)处理文件超出限制数量的情况。显示警告信息,告知用户已超出文件选择的限制。
handlePictureCardPreview(file)处理点击预览图片的逻辑。显示一个对话框来展示被点击的图片。
handleAvatarSuccess(file, fileList)处理文件上传成功后的回调。主要用于界面的更新,比如调整上传组件的大小以适应上传的文件。
handleDownload(file)处理下载图片的逻辑。根据文件对象中的URL创建一个隐藏的链接,并触发点击事件来下载图片。

方法解析

此Vue组件是一个图片上传功能,包含了一系列的方法来处理文件的上传、预览、删除等操作。

  • beforeUpload(file)
    在文件上传前的钩子函数。用于检查文件的类型和大小,如果文件不符合条件,则显示相应的错误信息并停止上传。该方法也负责创建本地预览URL,并通过直接调用directUpload方法来处理文件的上传逻辑,同时避免使用el-upload组件默认的上传行为。
    参数:
    file - 当前要上传的文件对象。
    返回: 返回false以阻止el-upload组件的默认上传行为。

  • handleLocalPreview(localPreviewUrl, file)
    处理文件的本地预览。该方法更新fileList,将包含本地预览URL的文件对象添加到列表中,以便在界面上显示。
    参数:
    localPreviewUrl: 文件的本地预览URL
    file: 当前操作的文件对象。

  • directUpload(file)
    直接上传文件到服务器。该方法创建一个FormData对象,将文件添加到其中,并使用axios发送POST请求到指定的上传URL
    参数:
    file - 要上传的文件对象。
    操作:
    成功上传后,调用handleUploadResponse来处理响应数据。
    如果上传失败,调用handleUploadFailure来处理错误。

  • handleUploadFailure(file)
    处理文件上传失败的逻辑。该方法从fileList中移除当前文件,并显示上传失败的消息。
    参数:
    file - 上传失败的文件对象。

  • handleUploadResponse(responseData, file)
    处理文件上传成功的响应。该方法根据后端返回的数据更新fileList,并确保上传的文件在列表中显示。
    参数:
    responseData: 后端返回的响应数据。
    file: 当前上传的文件对象。

  • handleRemove(file, fileList, name)
    处理文件的删除操作。从fileList中移除指定的文件,并清空临时存储的图片信息。
    参数:
    file: 要删除的文件对象。
    fileList: 当前的文件列表(此参数未在方法体中直接使用)。
    name: 文件的名称(此参数未在方法体中直接使用)。

  • handleExceed(files, fileList, num)
    处理文件超出限制数量的情况。显示警告信息,告知用户已超出文件选择的限制。
    参数:
    files: 当前选择的文件列表。
    fileList: 已经上传的文件列表。
    num: 允许上传的最大文件数量。

  • handleAvatarSuccess(file, fileList)
    处理文件上传成功后的回调。主要用于界面的更新,比如调整上传组件的大小以适应上传的文件。
    参数:
    file: 成功上传的文件对象。
    fileList: 当前的文件列表。

  • handlePictureCardPreview(file):处理点击预览图片的逻辑。显示一个对话框来展示被点击的图片。
    参数:
    file - 被点击的文件对象,用于获取图片的URL进行预览。

  • handleDownload(file)
    处理下载图片的逻辑。根据文件对象中的URL创建一个隐藏的链接,并触发点击事件来下载图片。
    参数:
    file - 要下载的文件对象。

组件通过这些方法实现了一个具有上传前验证、文件预览、直接上传到后端、处理上传成功或失败响应、删除已上传文件等功能的图片上传器。

父组件调用:

  <business-license-upload :key="componentKey" :widthProp="140" :heightProp="140":uploadUrl="'http://192.168.60.27:8888/file-storage-center/object/uploadObjectByMultipartFile'":fileListProp.sync="fileList2"></business-license-upload><p><span>*</span> <span class="idCardTip">身份证国徽面</span></p>

如果通过异步进行回显操作的话,在每次异步后执行componentKey++操作,更新DOM 强制回显

组件源码:

<template><div><divv-loading="loading":style="{ width: width + 'px', height: height + 'px' }"><el-upload:style="{ width: width + 'px', height: height + 'px' }"class="avatar-uploader":class="noneBtnDealImg ? 'disUoloadSty' : ''"ref="uploader":file-list="fileList":before-upload="beforeUpload":action="uploadUrl":on-exceed="(files, fileList) => handleExceed(files, fileList, 1)":on-change="(file, fileList) => this.handleAvatarSuccess(file, fileList)"list-type="picture-card":auto-upload="true"><islot="default"class="el-icon-plus":style="{ lineHeight: height + 'px' }"></i><div slot="file" slot-scope="{ file }"><img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /><span class="el-upload-list__item-actions"><spanclass="el-upload-list__item-preview"@click="handlePictureCardPreview(file)"><i class="el-icon-zoom-in"></i></span><!-- <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)"><i class="el-icon-download"></i></span> --><spanv-if="!disabled"class="el-upload-list__item-delete"@click="handleRemove(file)"><i class="el-icon-delete"></i></span></span></div></el-upload></div><el-dialog :modal="false" width="60%" :visible.sync="dialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog></div>
</template>
<script>
import { getToken } from '@/utils/auth'
import axios from 'axios' // 导入axios
export default {props: {widthProp: {typeof: Number,default: () => 200},heightProp: {typeof: Number,default: () => 140},fileListProp: {typeof: Array,default: () => []},uploadUrl: {typeof: String,default: () => ''}},data() {return {width: this.widthProp,height: this.heightProp,fileList: this.fileListProp,headerObj: {authorization: getToken(),tenant_id: 0},img: '',noneBtnDealImg: false,uploadfileurl: this.uploadFileURL,dialogImageUrl: '',dialogVisible: false,loading: false,disabled: false}},watch: {fileListProp: {deep: true,handler(oldVal, newVla) {this.fileList = this.fileListPropthis.$nextTick(() => {if (this.fileList.length >= 1) {const uploadBox1 =document.getElementsByClassName('avatar-uploader')uploadBox1[0].style.height = this.height + 'px'}this.noneBtnDealImg = this.fileList.length >= 1})}}},created() {},mounted() {this.noneBtnDealImg = this.fileList.length >= 1},methods: {beforeUpload(file) {// 检查文件类型、大小等const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png'const isLt2M = file.size / 1024 / 1024 < 2if (!isJPGorPNG) {this.$message.error('上传的图片只能是 JPG 或 PNG 格式!')return false}if (!isLt2M) {this.$message.error('上传的图片大小不能超过 2MB!')return false}// 创建本地预览URLconst reader = new FileReader()// 转换文件为base64字符串reader.readAsDataURL(file)reader.onload = (e) => {// 假设后端需要的是base64字符串,则可以直接使用e.target.result// 如果后端需要的是文件对象,则可以在此步骤中不处理const localPreviewUrl = e.target.resultthis.handleLocalPreview(localPreviewUrl, file)}// 发起上传请求this.directUpload(file)// 返回false阻止el-upload组件的默认上传行为return false},handleLocalPreview(localPreviewUrl, file) {// 根据需要更新的fileList,为了预览,临时添加一个带有本地URL的文件对象const fileForPreview = {...file,url: localPreviewUrl // 使用本地预览URL}this.fileList = [fileForPreview] // 假设您只希望回显一个文件// 注意:根据您的逻辑,您可能需要在上传成功或失败的回调中相应地更新或清除这个临时的预览文件//当前只保留一张照片this.$nextTick(() => {if (this.fileList.length >= 1) {const uploadBox1 = document.getElementsByClassName('avatar-uploader')uploadBox1[0].style.height = this.height + 'px'}this.noneBtnDealImg = this.fileList.length >= 1})},async directUpload(file) {try {this.loading = trueconst formData = new FormData()formData.append('file', file)// this.fileList = fileconst response = await axios.post(this.uploadUrl, formData, {headers: this.headerObj})// 处理上传成功this.handleUploadResponse(response.data, file)} catch (error) {this.handleUploadFailure(file)// 处理上传错误} finally {this.loading = false}},//上传出错handleUploadFailure(file) {//清除临时文件this.fileList = this.fileList.filter((item) => item.uid !== file.uid)// 向用户展示失败消息this.$message.error('图片上传失败,请重试。')// 检查fileList长度,更新noneBtnDealImg状态以正确显示上传按钮this.noneBtnDealImg = this.fileList.length >= 1// 因为文件上传组件可能依赖fileList的变化来更新UI,这里确保UI能够响应fileList的变化this.$forceUpdate()},//上传成功handleUploadResponse(responseData, file) {// 根据后端返回的数据,更新fileListconst updatedFile = {...file,response: responseData,url: responseData.data || '' //后端返回的URL在这里}// this.fileList = [updatedFile];this.$emit('update:fileListProp', [updatedFile])//当前只保留一张照片this.$nextTick(() => {if (this.fileList.length >= 1) {const uploadBox1 = document.getElementsByClassName('avatar-uploader')uploadBox1[0].style.height = this.height + 'px'}this.noneBtnDealImg = this.fileList.length >= 1})},//图片删除handleRemove(file, fileList, name) {const index = this.fileList.indexOf(file)if (index > -1) {this.fileList.splice(index, 1)}this.img = ''this.noneBtnDealImg = this.fileList.length >= 1this.$refs['uploader'].clearFiles()this.$forceUpdate()},handleExceed(files, fileList, num) {this.$message.warning(`当前限制选择 ${num} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)},handleAvatarSuccess(file, fileList) {this.$nextTick(() => {if (fileList.length >= 1) {const uploadBox1 = document.getElementsByClassName('avatar-uploader')uploadBox1[0].style.height = this.height + 'px'}this.noneBtnDealImg = fileList.length >= 1})},handlePictureCardPreview(file) {this.dialogImageUrl = file.urlthis.dialogVisible = true},handleDownload(file) {// 获取图片的真实URLconst imageUrl =file.response && file.response.data ? file.response.data : file.url// 创建一个隐藏的可下载链接const link = document.createElement('a')link.style.display = 'none'link.href = imageUrllink.download = file.name || 'image.png' // 设置下载的文件名,如果没有name属性则默认为'image.png'// 触发点击事件以下载图片document.body.appendChild(link)link.click()document.body.removeChild(link)}}
}
</script><style lang="less" scoped>
.el-form-item__label::after {content: '(最多1张)';display: block;font-size: 12px;color: #999;line-height: 12px;
}/deep/ .allUpload .el-form-item__content {display: flex;
}/deep/ .el-upload-list__item {transition: none !important;
}/deep/ .disUoloadSty .el-upload--picture-card {/* 上传按钮隐藏 */display: none !important;
}/deep/ .el-upload--picture-card {width: 100%;height: 100%;
}/deep/ .el-upload-list--picture-card .el-upload-list__item {margin-right: 0px !important;margin-bottom: 0px !important;
}/deep/ .el-upload-list__item {width: 100% !important;height: 100% !important;
}/deep/ .el-upload-list__item div:nth-child(1) {width: 100% !important;height: 100% !important;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/571874.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bash and a Tough Math Puzzle 线段树维护区间gcd

还是一道很不错的题目&#xff0c;很容易想到用一棵线段树来维护区间gcd 注意用倍数来剪枝就好了&#xff0c;很是一到很好的题目的 #include<iostream> #include<vector> using namespace std; const int N 5e510; int n,q; struct Segment{int l,r;int d; }tr[…

智慧体育场馆的优势都有哪些?

体育场馆作为体育产业和事业发展的重要载体&#xff0c;全民对健康和运动的需求越来越大&#xff0c;体育馆的需求也更大。而以前的体育场馆管理不仅人工成本高&#xff0c;人民的使用和消费也不方便。因此智慧体育馆的出现大大降低了运营人力成本及现金管理风险&#xff0c;大…

20240320-2-线性回归+逻辑回归

线性回归于逻辑回归面试题 1. 简单介绍一下线性回归。 **线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。**这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简…

day35 贪心算法 part04● 860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球

一遍过&#xff0c;就是有10的时候尽量把10用掉&#xff0c;20是用不掉的&#xff0c;如果发现不够找回了&#xff0c;就return false。 class Solution { public:bool lemonadeChange(vector<int>& bills) {unordered_map<int,int> mp;for(int i0;i<bill…

利用正则表达式,在idea上搜索匹配替换

工作中需要改字 正则表达式记录下 block-?[1-9]\d*"

spring-boot-devtools配置和原理

一、前言 昨天&#xff0c;一个同事Eclipse在启动SpringBoot项目时一直不停地加载&#xff0c;后来发现是因为spring-boot-devtools造成的问题&#xff0c;因为我们把日志输出的目录设置在当前项目里&#xff08;~/mnt/logs/&#xff0c;这样设置是因为mac电脑没有根目录权限&…

I/O模型之A、B、C、D、E、F、G去火锅店吃火锅

目录 BIO Blocking I/O 即同步阻塞I/O NIO Non-Blocking I/O 即同步非阻塞I/O I/O多路复用 AIO Asynchronous I/O 异步I/O 总结 I/O&#xff1a;Input和Output BIO Blocking I/O 即同步阻塞I/O 应用程序发起read调用后&#xff0c;一直会阻塞&#xff0c;直到系统内核将…

【c++模板】泛型编程(你真的懂模版特化、分离编译和非类型参数吗)

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今日主菜&#xff1a;模板 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在…

【2024系统架构设计】案例分析- 3 数据库

目录 一 基础知识 二 真题 一 基础知识 1 ORM ORM(Object—Relationl Mapping

【OS探秘】【虚拟化】【软件开发】在Windows 11上安装mac OS虚拟机

一、所需原料 Windows 11主机、Oracle VM VirtualBox虚拟化平台、mac OS 11镜像文件 二、安装步骤 1、 在VBox管理器中&#xff0c;点击“新建”&#xff0c;进入向导模式&#xff0c;指定各个字段&#xff1a;

46秒AI生成真人视频爆火,遭在线打假「换口型、声音」

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 发布在https://it.weoknow.com 更多资源欢迎关注 是炒作还是真正的 AI 视频能力进化&#xff1f; AI 生成视频已经发展到这个程…

03---java面试八股文——mybatis-------8题

21、MyBatis实现一对一查询 MyBatis 有两种不同的方式加载关联&#xff1a; 嵌套 Select 查询&#xff1a;通过执行另外一个 SQL 映射语句来加载期望的复杂类型。嵌套结果映射&#xff1a;使用嵌套的结果映射来处理连接结果的重复子集。查看mybatis的关联 MyBatis是一种流行的J…