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="fileList2">
  </business-license-upload>
 <p><span>*</span> <span class="idCardTip">身份证国徽面</span></p>

组件源码:

<template>
  <div>
    <div v-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">
        <i slot="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">
            <span class="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> 
          -->
            <span v-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
    };
  },
  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 < 2;
      if (!isJPGorPNG) {
        this.$message.error('上传的图片只能是 JPG 或 PNG 格式!');
        return false;
      }
      if (!isLt2M) {
        this.$message.error('上传的图片大小不能超过 2MB!');
        return false;
      }
      // 创建本地预览URL
      const reader = new FileReader();

      // 转换文件为base64字符串
      reader.readAsDataURL(file);

      reader.onload = (e) => {
        // 假设后端需要的是base64字符串,则可以直接使用e.target.result
        // 如果后端需要的是文件对象,则可以在此步骤中不处理
        const localPreviewUrl = e.target.result;
        this.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 = true
        const formData = new FormData();
        formData.append('file', file);
        // this.fileList = file
        const 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) {
      // 根据后端返回的数据,更新fileList
      const updatedFile = {
        ...file,
        response: responseData,
        url: responseData.data || '', // 假设后端返回的URL在这里
      };
      this.fileList = [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 >= 1
      this.$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.url;
      this.dialogVisible = true;
    },
    handleDownload(file) {
      // 获取图片的真实URL
      const imageUrl = file.response && file.response.data ? file.response.data : file.url;
      // 创建一个隐藏的可下载链接
      const link = document.createElement('a');
      link.style.display = 'none';
      link.href = imageUrl;
      link.download = file.name || 'image.png'; // 设置下载的文件名,如果没有name属性则默认为'image.png'
      // 触发点击事件以下载图片
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  }
}
</script>

<style 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.mfbz.cn/a/487006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人脸聚类原理和算法解释

人脸聚类是指将大量人脸图像根据它们的相似性分组到不同的群集中的过程。人脸聚类通常利用人脸的特征向量表示来度量人脸之间的相似性&#xff0c;并将相似的人脸图像聚集在一起。 以下是人脸聚类的一般原理&#xff1a; 人脸特征提取&#xff1a;对每张人脸图像提取特征向量。…

FPGA结构与片上资源

文章目录 0.总览1.可配置逻辑块CLB1.1 6输入查找表&#xff08;LUT6&#xff09;1.2 选择器&#xff08;MUX&#xff09;1.3 进位链&#xff08;Carry Chain&#xff09;1.4 触发器&#xff08;Flip-Flop&#xff09; 2.可编程I/O单元2.1 I/O物理级2.2 I/O逻辑级 3.布线资源4.其…

为什么静态成员函数不能是虚函数

在面向对象编程中&#xff0c;静态成员函数和虚函数都是常见的概念&#xff0c;但它们之间存在着本质上的差异。由于其特性上的差异&#xff0c;静态成员函数不能声明为虚函数。下面我们来探讨一下为什么静态成员函数不能是虚函数。 我在网上查到最多的说法是静态函数没有this指…

机场防鸟 | 真驱鸟煤气炮驱鸟器产品分析

机场的机坪跑道上&#xff0c;飞机频繁起降&#xff0c;而在机场的上空&#xff0c;偶尔会有几只灵活的小鸟&#xff0c;趁着飞机起降的间隙&#xff0c;在机坪区穿梭&#xff0c;它们或许在寻找食物&#xff0c;或许只是在享受这片广阔的天空。 对于机场驱鸟员来说&#xff0c…

嵌入式学习44-哈希算法和排序算法

Hash 哈希算法&#xff1a; 在记录的 存储位置 和它的 关键字 之间建立一种去特定的对应关系&#xff0c;使得每个关键字key对应一个存储位置&#xff1b; 查找时&#xff0c;根据确定的对应关系&#xff0c;找到给定的 key 的映射。 记录的存储位置 f&a…

vscode安装mysql相关插件

在Visual Studio Code (VSCode) 中安装 MySQL 客户端插件可以让你在 VSCode 中直接连接到 MySQL 数据库&#xff0c;并执行 SQL 查询。以下是如何安装和使用 MySQL 客户端插件的步骤&#xff1a; 1.打开 VSCode。 2.按下 Ctrl Shift X 打开扩展商店&#xff08;或点击侧边栏…

Mysql - date、datetime、timestamp 的区别

date、datetime 的区别 顾名思义&#xff0c;date 日期&#xff0c;datetime 日期时间&#xff0c;所以 date 是 datetime 的日期部分MySQL 以 格式检索和显示 datetime 值 YYYY-MM-DD hh:mm:ss datetime 支持的日期时间范围 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 d…

SpringBoot学习之ElasticSearch下载安装和启动(Windows版)(三十)

本文先写windows下的下载安装和启动,后续有时间再补充其他环境下(Mac、Linux、Docker)的,这里我们后续对ElasticSearch简称为ES,读者习惯这一称呼就好。 一,ES下载 可以百度【ElasticSearch官网】或者直接点击这里的ES官网下载地址:​​​​​ Download Elasticsearch…

电路笔记 :灯光画 元器件焊接+连锡处理

https://oshwhub.com/qazwsx1987/dengguanghua_0#P3 基础工具 常用的电路焊接工具&#xff1a; 工具描述电烙铁我买了一个便携电烙铁&#xff0c;但是烙铁头温度太低&#xff0c;焊锡总是粘在烙铁头上&#xff08;因为电量不足&#xff09;, 打火机秒变电烙铁焊台用于支撑工…

集成学习 | 集成学习思想:Boosting思想 | XGBoost算法、LightGBM算法

目录 一. XGBoost 算法1. XGBoost 算法流程2. XGBoost 算法评价 二. LightGBM 算法2. LightGBM 算法优势 上一篇文章中&#xff0c;我们了解了Boosting思想的两种算法&#xff1a;Adboost和GBDT&#xff1b;其中对于GBDT算法&#xff0c;存在两种改进&#xff0c;即&#xff1a…

SQLAlchemy操作数据库

数据库是一个网站的基础。 比如 MySQL 、 MongoDB 、 SQLite 、 PostgreSQL 等&#xff0c;这里我们以 MySQL为例进行讲解。 SQLAlchemy 是一个 ORM 框架 我们会以 MySQL SQLAlchemy 组合进行讲解。 在操作数据库操作之前&#xff0c;先确保你已经安装了以下两个插件&#…

阿里云服务器新/老用户优惠价格收费标准(2024最新更新)

2024年阿里云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步到阿里云CLUB中心查看 aliyun.club 当前最新的云服务器优惠券…

鸿蒙(HarmonyOS)版Retrofit网络请求框架

注意 从3.0开始&#xff0c;官方已经废弃Java了。鸿蒙最终选择了高效简洁的JS/eTS语言为主要开发语言&#xff0c;即从3.0 Beta开始&#xff0c;鸿蒙将重心主要放在JS类Web式、eTS声明式两大类开发范式&#xff0c;兼容C/C类。Java类API不再演进&#xff0c;但是会持续运营维护…

前台处理:CO主数据之成本中心-<KS01>

一、背景&#xff1a; 前面讲解了成本要素和成本要素组&#xff0c;我们继续介绍成本控制与核算的主数据之成本中心&#xff0c;成本控制分主数据篇和业务篇&#xff1a; 主数据篇主要内容&#xff1a;成本要素、成本中心、订单、作业类型、工作中心&#xff1b; 业务篇主要…

Spring boot2.7整合jetcache方法缓存 设置定时刷新 解决多系统同时操作数据问题

上文 Spring boot2.7整合jetcache方法缓存 处理数据发生变化时同步更新缓存 删除缓存操作 解决了 缓存更新的问题 但是 现在有个问题 例如 我们 A系统 和 B系统 同时缓存了这一组数据 但是 A系统数据发生了更新 但是 B系统并不知道 其实 也没有特别好的办法同步通知 但可以控…

Git (版本控制,git安装和配置,git代码托管服务,git操作本地远程仓库,分支,idea整合git)【看这一片就够】

目录 一、版本控制介绍 1. 版本控制介绍 2. 版本控制工具 3. git简介 二、git安装与配置 1. 下载git 2. 安装git 2. 配置git 三、git代码托管服务 1. 常见的git代码托管服务 2. 注册码云帐号【这里介绍一种的用法&#xff0c;其它也是一样的操作】 3. 创建远程仓库 …

试试前端自动化测试(基础篇)

众所周知的原因&#xff0c;前端作为一种特殊的 GUI 软件&#xff0c;做自动化测试困难重重。在快速迭代&#xff0c;UI 变动大的业务中&#xff0c;自动化测试想要落地更是男上加男 &#x1f436;。 近期的学习过程中&#xff0c;翻阅了众多前端自动化测试相关的文章&#xf…

微信商家转账到零钱:实用指南,涵盖开通、使用与常见问题

商家转账到零钱是什么&#xff1f; 商家转账到零钱功能整合了企业付款到零钱和批量转账到零钱&#xff0c;支持批量对外转账&#xff0c;操作便捷。如果你的应用场景是单付款&#xff0c;体验感和企业付款到零钱基本没差别。 商家转账到零钱的使用场景有哪些&#xff1f; 这…

路由控制过滤策略出口 filter-policy export实验简述(直连路由)

配置过滤策略 filter-policy实验简述&#xff08;直连路由&#xff09; filter-policy export可以实现对特定流量的筛选和导出。 实验拓扑图&#xff1a; 实验基础配置&#xff1a; 销售部电脑&#xff1a;192.168.1.100/24/192.168.1.254 通过直连路由引入外部路由 财务部电…
最新文章