vue3+ el-upload封装上传组件

  1. 组件功能介绍
    • 上传格式限制
    • 上传大小限制
    • 上传文件数量限制
    • 自定义上传区
    • 上传成功回调
    • 禁用上传开关与点击上传自定义事件
    • 暴露所以上传文件列表(uploadList)与当前文件数据(uploadLatestFile
  2. 组件代码Upload.vue
<template>
  <div>
    <div>
      <el-upload
        class="flx-align-center"
        :file-list="fileList"
        :multiple="multiple"
        :limit="limit"
        :disabled="disabled"
        :accept="fileType"
        :show-file-list="false"
        :http-request="handleHttpUpload"
        :before-upload="beforeUpload"
        :on-exceed="handleExceed"
      >
        <slot name="upload-btn">
          <div class="upload-content">
            <el-button type="primary" :icon="UploadFilled" plain @click="handleClick">点击上传</el-button>
          </div>
        </slot>
      </el-upload>
      <!-- 提示 -->
      <div class="upload-tip" v-if="tipShow">
        <slot name="tip">{{ tipComputed }}</slot>
      </div>
    </div>
    <div class="upload-box">
      <slot></slot>
    </div>
  </div>
</template>

<script setup lang="ts" name="UploadBasics">
import { ref, computed } from "vue";
import { UploadFilled } from "@element-plus/icons-vue";
import type { UploadUserFile } from "element-plus";
import { ElNotification } from "element-plus";
import { uploadImg } from "@/api/modules/upload";
import { getFileType } from "@/utils/assetsFile";

interface UploadFileProps {
  fileType: string;
  fileSize: number; // 允许上传文件的最大尺寸
  limit: number; // 允许上传文件的最大数量
  tipShow: boolean; // 是否显示提示
  multiple: boolean; // 是否可以多选
  fileList: UploadUserFile[];
  disabled: boolean;
  handleClick: () => void; // 点击上传按钮自定义事件, 可在禁用时触发
}

const props = withDefaults(defineProps<Partial<UploadFileProps>>(), {
  fileType: ".pdf, .jpg, .png, .jpeg",
  fileSize: 10,
  tipShow: true,
  multiple: true,
  fileList: () => [],
  disabled: false
});

// 提示
const tipComputed = computed(() => {
  const tip = props.fileType.replace(/\./g, "").replace(/,/g, "、").toUpperCase();
  return `支持${tip}格式,大小不得超过${props.fileSize}M`;
});

// 文件上传前的钩子
const beforeUpload = rawFile => {
  // 判断文件类型, 不显示小数点
  const extension = getFileType(rawFile.name, 1);
  const fileType = props.fileType.replace(/\./g, ""); // 若传入类型有小数点,替换
  const imgType = fileType.includes(extension);
  if (!imgType) {
    ElNotification({
      title: "温馨提示",
      message: "上传图片不符合所需的格式!",
      type: "warning"
    });
    return false;
  }
  // 判断大小
  if (rawFile.size / 1024 / 1024 > props.fileSize) {
    ElNotification({
      title: "温馨提示",
      message: `上传图片大小不能超过 ${props.fileSize}M!`,
      type: "warning"
    });
    return false;
  }
};

const handleExceed = () => {
  ElNotification({
    title: "温馨提示",
    message: `超出文件上传最大数量:${props.limit}`,
    type: "warning"
  });
  return false;
};

// 上传文件请求
const uploadLatestFile = ref<UploadUserFile>(); // 最近上传的文件
const uploadList = ref<UploadUserFile[]>([]); // 所有上传的文件列表

const handleHttpUpload = async options => {
  let formData = new FormData();
  formData.append("file", options.file);

  try {
// 上传请求
    const { data } = await uploadImg(formData);
    uploadLatestFile.value = {
      name: data.data.name as string,
      url: data.data.url
    };

    uploadList.value = [
      ...uploadList.value,
      {
        name: data.data.name as string,
        url: data.data.url
      }
    ];

    emits("upload-success", { uploadLatestFile: uploadLatestFile.value, uploadList: uploadList.value });
  } catch (error) {
    options.onError(error as any);
  }
};

const emits = defineEmits(["upload-success"]);

defineExpose({
  uploadList,
  uploadLatestFile
});
</script>

<style lang="scss" scoped>
// 上传按钮区
.upload-content {
  display: flex;
  flex-direction: column;
}

// 上传文件显示容器
.upload-box {
  max-height: 400px;

  // margin-top: 10px;
  overflow: auto;
}

// 提示
.upload-tip {
  display: flex;
  align-items: center;
  font-size: 12px;
  line-height: 32px;
  color: var(--el-label-color-regular);
}
</style>

  1. 使用示例一:
  • 使用默认的上传按钮
<Upload
  ref="uploadRef"
  :file-size="20"
  :limit="10"
  :file-list="uploadItemRef?.newFileList"
  file-type="zip,png,jpg,jpeg,doc,docx,xls,xlsx,pdf,ppt,pptx"
  direction="horizontal"
>
<UploadItem ref="uploadItemRef" :file-list="fileList" :upload-list="uploadRef?.uploadList" />
</Upload>


// UploadItem 是展示内容
  • 效果图展示:
    image.png
  1. 使用示例二:使用自定义的上传按钮
  • Upload上传组件内部使用UploadItem展示文件,展示文件内部又有上传功能:
<Upload ref="uploadRef">
  <UploadItem :file-list="dataList" :upload-list="uploadRef?.uploadList" />
</Upload>
  • UploadItem.vue 内:
<div class="file-div flx-justify-between" v-for="(item, index) in list" :key="index">
    <div class="flx-align-center">
      <img :src="getFileTypeImg(item.url)" :alt="item.name" />
      <span v-if="isExt">{{ item.name }}</span>
      <!-- <span v-else>{{ item.name }}{{ getFileType(item.url) }}</span> -->
      <span v-else>{{ item.name }}</span>
    </div>

    <div class="upload-btns">
      <el-button v-if="isDown" type="primary" text @click="handleDown(item)"> 下载 </el-button>
      <Upload :tip-show="false" :multiple="false" @upload-success="uploadSuccess($event, item)">
        <template #upload-btn>
          <img src="@/assets/images/disposal/reactupload.png" alt="reactupload" class="reactupload" />
        </template>
      </Upload>
    </div>
  </div>
  • 效果图
    image.png

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

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

相关文章

玩具租赁系统(安装+讲解+源码)

技术栈: 后端: SpringBoot Mysql MybatisPlus 前端: Vue Element 分为 管理员端 用户端 功能: 用户端 管理员端 观看地址: B站搜&#xff1a; 【毕设者】玩具租赁系统(安装讲解源码)

智慧园区综合平台解决方案PPT(75页)

## 智慧园区的理解 ### 从园区1.0到园区4.0的演进 1. 园区1.0&#xff1a;以土地经营为主&#xff0c;成本驱动&#xff0c;提供基本服务。 2. 园区2.0&#xff1a;服务驱动&#xff0c;关注企业成长&#xff0c;提供增值服务。 3. 园区3.0&#xff1a;智慧型园区&#xff…

WordPress免费模板:惊艳动态效果,打造视觉盛宴

WordPress免费模板&#xff1a;惊艳动态效果&#xff0c;打造视觉盛宴 我们为您带来了一款独具特色的WordPress免费模板&#xff0c;这款模板以其独特的动态效果设计&#xff0c;特别是引人注目的动态banner图片效果&#xff0c;为您的网站注入活力&#xff0c;打造一场视觉盛…

[渗透测试] 任意文件读取漏洞

任意文件读取漏洞 概述 漏洞成因 存在读取文件的功能&#xff08;Web应用开放了文件读取功能&#xff09;读取文件的路径客户端可控&#xff08;完全控制或者影响文件路径&#xff09;没有对文件路径进行校验或者校验不严格导致被绕过输出文件内容 漏洞危害 下载服务器中的…

spring boot (shiro)+ websocket测试连接不上的简单检测处理

1、用前端连接测试的demo一切正常&#xff0c;但是到了项目中连接不上了 一开始以为是地址错&#xff0c;但是换了apifox测试也是不可以。 2、考虑是shiro进行了拦截了&#xff0c;所以就访问不到了地址&#xff0c;那么就放行。 3、再次用apifox测试&#xff0c;成功了。 当然…

【CSS in Depth 2 精译】2.2 em 和 rem + 2.2.1 使用 em 定义字号

当前内容所在位置 第一章 层叠、优先级与继承第二章 相对单位 2.1 相对单位的威力 2.1.1 响应式设计的兴起 2.2 em 与 rem ✔️ 2.2.1 使用 em 定义字号 ✔️2.2.2 使用 rem 设置字号 2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 2.…

复分析——第9章——椭圆函数导论(E.M. Stein R. Shakarchi)

第 9 章 椭圆函数导论 (An Introduction to Elliptic Functions) The form that Jacobi had given to the theory of elliptic functions was far from perfection; its flaws are obvious. At the base we find three fundamental functions sn, cn and dn. These functio…

一文解决图论中有向图、无向图、非负加权图的单源最短路径问题【超详细】【通用模板程序】【深入分析】【无需基础】【c++】

本文致力于提供一种解决图论中所有&#xff08;或绝大部分&#xff09;有向图、无向图、非负加权图的单源最短路径问题的通用程序模板&#xff0c;本文提供的模板并不是简单的可行模板&#xff0c;而是经过深入分析解释的一个较高质量和性能的通用程序模版。在每个关键变量存储…

JavaSE期末复习速成笔记

面向对象 1. 面向对象的概念 面向对象编程&#xff08;OOP&#xff09;是一种编程范式&#xff0c;它将现实世界的事物抽象为对象&#xff0c;通过类和对象来创建各种功能模块&#xff0c;以此来设计和开发软件。 2. 类与对象 类&#xff1a;是对象的模板&#xff0c;定义了…

Ros2学习中的话题通信-自定义接口消息:在VScode中不能补全的问题

在学习ros2的过程中&#xff0c;当学习到话题通信-自定义接口消息时&#xff0c;当消息的具体类型并未指定时&#xff0c;常见的操作是在base_interfaces_demo下创建msg文件夹及文件。同理&#xff0c;在动作通信等其他类型的通信中也需要这么做&#xff0c;只是创建的文件夹的…

KV260视觉AI套件--开箱报告

目录 1. 简介 2. 与 Zynq 的渊源 3. 官方的入门步骤 4. 总结 1. 简介 传统的ARMFPGA或DSPFPGA控制方案在软件、逻辑、硬件以及系统工程的协同调试中&#xff0c;往往需要团队成员之间严格按照预定计划和接口规范进行分工合作&#xff0c;这不仅增加了测试过程的复杂性&…

【ElementPlus源码】Container 布局容器

文章目录 index.tsContainerheaderutilswithInstallwithNoopInstall hooksuseNamespace 单元测试 看源码时候做的笔记。如有错误请指出&#xff01; 关于路径的省略&#xff0c;详见button&#xff1a;【ElementPlus源码】Button按钮-CSDN博客 index.ts 导入一堆组件&#xff…

Centos7配置支持ftp文件传输功能

报错信息 适用于不支持ftp协议的centos7的系统。 报错信息&#xff1a;An error occurred while executing the action Connect. Details: No connection could be made because the target machine actively refused it. 解决办法 安装及启动等命令 # 安装vsftpd sudo yum…

Spark SQL 的总体工作流程

Spark SQL 是 Apache Spark 的一个模块,它提供了处理结构化和半结构化数据的能力。通过 Spark SQL,用户可以使用 SQL 语言或 DataFrame API 来执行数据查询和分析。这个模块允许开发者将 SQL 查询与 Spark 的数据处理能力结合起来,实现高效、优化的数据处理。下面是 Spark S…

高级运维工程师讲述银河麒麟V10SP1服务器加固收回权限/tmp命令引起生产mysql数据库事故实战

高级运维工程师讲述银河麒麟V10SP1服务器加固收回权限/tmp命令引起生产MySql数据库事故实战 一、前言 作为运维工程师经常会对生产服务器进行安全漏洞加固&#xff0c;一般服务厂商、或者甲方信息安全中心提供一些安全的shell脚本&#xff0c;一般这种shell脚本都是收回权限&…

C++实现简化版Qt信号槽机制(2):增加内存安全保障

在上一篇文章中《C实现一个简单的Qt信号槽机制》&#xff0c;我们基于前面的反射代码实现了信号槽的功能。 但是上一篇的代码中没有对象生命周期管理的机制&#xff0c;如果在对象的生命周期结束后还存在未断开的信号和槽连接&#xff0c;那么信号触发时可能会尝试访问已经被析…

Redis 7.x 系列【11】数据类型之位图(Bitmap)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 基本命令2.1 SETBIT2.2 GETBIT2.3 BITCOUNT2.4 BITPOS2.5 BITFIELD2.6 BITF…

【产品经理】订单处理10-分配快递策略

本次主要讲解下在订单处理过程中分配快递的策略以及分配快递中需要用到的设置。 一、建立快递档案 在ERP系统中&#xff0c;需要建立快递档案&#xff0c;设置所属快递、快递的服务类型、支持的打印模版以及快递在各个平台的电子面单支持情况。 二、仓库绑定快递 仓库需要设…

【动态规划】279.完全平方数

279. 完全平方数 难度&#xff1a;中等 力扣地址&#xff1a;https://leetcode.cn/problems/perfect-squares/ 没有刷过的小伙伴们请一定要先去刷一次&#xff0c;然后如果感兴趣的话再阅读以下内容&#xff0c;便于交流 ~ 多谢支持 ~ 问题描述 给你一个整数 n &#xff0c;返…

C# 入门—基本语法

一、数据类型 C# 语言中内置了一些基本的数据类型&#xff0c;数据类型用来指定程序中变量可以存储的数据的类型&#xff0c;C# 中的数据类型可以大致分为三类&#xff1a; 值类型&#xff08;Value types&#xff09;&#xff1b;引用类型&#xff08;References types&…