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

news2024/9/20 1:24:24

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

效果:

element ui 实现证件的上传下载预览功能

参数说明

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

参数说明
fileListProp用来存储上传后后端返回的图片UR了
uploadUrl图片上传反悔的URL后端接口地址

父组件调用:

 <au-upload :uploadUrl="'http://192.168.60.27:8888/file-storage-center/object/uploadObjectByMultipartFile'" :fileListProp="fileList1">
 </au-upload>
 <p><span>*</span> <span class="idCardTip">身份证国徽面</span></p>

组件源码:

<template>
  <div>
    <el-upload v-loading="loading" element-loading-text="上传中..." :style="{ 'width': width + 'px', 'height': height + 'px' }" class="avatar-uploader"
      :class="noneBtnDealImg ? 'disUoloadSty' : ''" ref="uploader" 
      :file-list="fileList" 
      :action="uploadUrl"
      :before-upload="beforeUpload" 
      :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"></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>
    <el-dialog :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: {
    fileListProp: {
      typeof: Array,
      default: () => []
    },
    uploadUrl: {
      typeof: String,
      default: () => ''
    },
  },
  data() {
    return {
      width: 140,
      height: 140,
      fileList: this.fileListProp,
      headerObj: {
        authorization: getToken(),
        tenant_id: 0,
      },
      img: '',
      noneBtnDealImg: false,
      uploadfileurl: this.uploadFileURL,
      dialogImageUrl: '',
      dialogVisible: false,
      disabled: false,
      loading: 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;
      }
      // 发起上传请求
      this.directUpload(file);

      // 返回false阻止el-upload组件的默认上传行为
      return false;
    },
    async directUpload(file) {
      try {
        this.loading = true
        const formData = new FormData();
        formData.append('file', file);
        const response = await axios.post(this.uploadUrl, formData, {
          headers: this.headerObj,
        });
        // 处理上传成功
        this.handleUploadResponse(response.data, file);
      } catch (error) {
        // 处理上传错误
        console.error('Upload error:', error);
      } finally {
        this.loading = false;
      }
    },
    handleUploadResponse(responseData, file) {
      // 根据后端返回的数据,更新fileList
      const updatedFile = {
        ...file,
        response: responseData,
        url: responseData.data || '', // 假设后端返回的URL在这里
      };
      this.fileList.push(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: 140px;
  height: 140px;
}

/deep/ .el-upload-list--picture-card .el-upload-list__item {
  margin-right: 0px !important;
  margin-bottom: 0px !important;
}

/deep/ .el-upload-list__item {
  width: 140px !important;
  height: 140px !important;
}

/deep/ .el-upload-list__item div:nth-child(1) {
  width: 100% !important;
  height: 100% !important;
}
/deep/ .el-loading-spinner .el-loading-text{
  text-align: center;
  margin-top: -18px;
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OSPF-1类Router LSA学习

前面我们又复习了一遍OSPF概述&#xff0c;在OSPF建立关系后有几种交互报文&#xff0c;通过LSU类型报文包含LSA信息实现路由信息传递&#xff0c;常见了1、2、3、4、5、7类LSA&#xff0c;分别对应不同功能使用。这里先看下1类LSA-Router LSA。 一、LSA概述 LSA&#xff0c;全…

vscode中断无法识别npm的命令解决方案

在cmd中可以正常执行npm -v等指令,但是在vs code终端中,无法执行npm -v,node -v等指令 出现报错&#xff1a; 解决办法&#xff1a; 方法一&#xff1a;【右键单击Vscode】以【管理员身份运行】&#xff0c;【重启Vscode】&#xff08;这种办法每次打开都用管理员身份比较麻烦…

【实例】React 组件传值方法: Props、回调函数、Context、路由传参

React原始传值方法 借用状态管理库的传值见下篇文&#xff1a;MobX 和 Redux 【实例】React 状态管理库 MobX Redux 入门及对比 文章目录 React原始传值方法父组件->子组件 props子组件->父组件 回调函数Context路由传值 父组件->子组件 props 父组件可以通过属性&a…

字符串筛选排序 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 输入一个由n个大小写字母组成的字符串, 按照 ASCII 码值从小到大的排序规则,查找字符串中第 k 个最小ASCII 码值的字母(k>=1) , 输出该字母所在字符串的位置索引(字符串的第一个字符位置索引为0) 。…

电源配小了,是不是容易烧?是的!

电源小的话会不会容易烧毁&#xff1f; 是的。 功率电压*电流。 随着功率增大&#xff0c;电压不变&#xff0c;电流增大&#xff0c;发热量增大&#xff0c;可能会烧毁。 今天给大家推荐一款650w的电脑电源&#xff0c;不过在推荐之前&#xff0c;首先要确认自己的电脑功耗…

OpenCV4.9.0在Android 开发简介

查看&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;使用 Clojure 进行 OpenCV 开发简介 下一篇&#xff1a;暂无 引言&#xff1a; OpenCV是一个跨平台计算机视觉库&#xff0c;广泛用于图像处理、计算机视觉和机器学习等领域…

【翻译】Attentive Pooling Networks

摘要&#xff1a; 在这项工作中&#xff0c;我们提出了注意力池化&#xff08;AP&#xff09;&#xff0c;一种用于判别模型训练的双向注意力机制。在使用神经网络进行成对排序或分类的背景下&#xff0c;AP使得池化层能够意识到当前的输入对&#xff0c;使得两个输入项的信息…

AI系统性学习03—ChatGPT开发教程

文章目录 1、OpenAI关键概念⭐️2、OpenAI SDK介绍3、OpenAI API KEY&API 认证3.1 REST API安全认证 4、OpenAI模型⭐️4.1 模型分类4.2 GPT44.3 GPT-3.54.4 Embeddings 5、OpenAI快速入门6、Function calling(函数调用)⭐️⭐️⭐️6.1 应用场景6.2 支持function calling的…

稀碎从零算法笔记Day23-LeetCode:相同的树

题型&#xff1a;二叉树的遍历、链表 链接&#xff1a;100. 相同的树 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;…

ERP系统在企业管理中的重要作用

效率和盈利能力是企业在商业领域取得成功的两大关键要素。企业希望以尽可能高效的方式执行必要的、有利可图的业务流程&#xff0c;但又需要在保持最低运营成本的同时最大化企业的底线利润。要实现这种高效和高盈利的水平&#xff0c;企业需要扩展其业务流程管理策略&#xff0…

python网络爬虫实战教学——urllib的使用(3)

文章目录 专栏导读1、urlsplit2、urlunsplit3、urljoin4、urlencode 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对大学生、…

三级数据库技术考点(详解!!)

1、 答疑:【解析】分布式数据库系统按不同层次提供的分布透明性有:分片透明性;②位置透明性;③局部映像透明性&#xff0c;位置透明性是指数据分片的分配位置对用户是透明的&#xff0c;用户编写程序时只需 要考虑数据分片情况&#xff0c;不需要了解各分片在各个场地的分配情…

CMake学习(上)

1. CMake概述 CMake 是一个项目构建工具&#xff0c;并且是跨平台的。关于项目构建我们所熟知的还有Makefile&#xff08;通过 make 命令进行项目的构建&#xff09;&#xff0c;大多是IDE软件都集成了make&#xff0c;比如&#xff1a;VS 的 nmake、linux 下的 GNU make、Qt …

关于Rust的项目结构的笔记

层级 PackageCrateModulePath Package cargo的特性, 构建、测试、共享Crate 组成: 一个 Cargo.toml 文件, 描述了如何构建这些 Crates至少包含一个 crate最多只能包含一个 library crate可以包含任意个 binary crate cargo new demo-pro 会产生一个名为 demo-pro 的 Packa…

蓝桥杯-礼物-二分查找

题目 思路 --刚开始想到暴力尝试的方法&#xff0c;但是N太大了&#xff0c;第一个测试点都超时。题目中说前k个石头的和还有后k个石头的和要小于s&#xff0c;在这里要能想到开一个数组来求前n个石头的总重&#xff0c;然后求前k个的直接将sum[i]-sum[i-k-1]就行了&#xff0…

Vue+SpringBoot打造快乐贩卖馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 搞笑视频模块2.3 视频收藏模块2.4 视频评分模块2.5 视频交易模块2.6 视频好友模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 搞笑视频表3.2.2 视频收藏表3.2.3 视频评分表3.2.4 视频交易表 四、系…

蓝桥杯-python-递归

递归&#xff1a;通过自我调用解决问题的函数 注意&#xff1a; #1.递归出口 #2.当前问题如何变成子问题 例子&#xff1a;利用递归写一个阶乘函数&#xff0c;F(n),求n的阶乘 def f(n):if n < 1:return 1ans n * f(n-1)return ans print(f(5)) 例子&#xff1a;汉诺塔…

大数据Doris(六十九):项目线上表现

文章目录 项目线上表现 一、查询响应时间

【Linux第三课-基础开发工具的使用】yum、vim、gcc/g++编译器、gdb、Make/Makefile编写、进度条程序、git命令行简单操作

目录 yum - 软件包管理器快速认识yum快速使用yumyum搜索yum安装yum卸载 yum的周边 - yum的整个生态问题 vim快速介绍vimvim的模式命令模式插入模式低行模式 常见模式 -- 命令、低行命令模式 -- 光标的移动命令模式 -- 复制粘贴、剪贴、删除命令模式 -- 小写/大写替换模式命令模…

个人开发App成功上架手机应用市场的关键步骤

目录 1. 苹果审核和APP备案 2. APP上架操作步骤 3. 审核和发布 4. 上线工作 总结 参考资料 在当前移动应用市场竞争激烈的背景下&#xff0c;个人开发App如何成功上架成为开发者们必须面对的重要任务。本文将重点介绍自建App上架至手机应用市场的流程&#xff0c;包括苹果…