vue3+ el-upload封装上传组件

news2024/11/25 15:30:10
  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.coloradmin.cn/o/1873528.html

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

相关文章

Vue-cli搭建一个项目

目录 vue-cli搭建项目 主要的功能 需要的环境 用 HbuilderX 搭建 vue-cli 项目 1、创建一个vue项目(2.6.10) 2、组件路由 首先&#xff1a;安装 其次&#xff1a; 1.在src文件夹下创建router目录,创建index.js 2.使用路由——在App.vue中添加路由视图 3.在main.js 中…

C语言学习记录(十一)——指针基本知识及运算

文章目录 前言1. 指针的概念2.指针变量的说明3. 指针的含义4. 指针运算①指针加减&#xff1a;②指针的关系运算符 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 1. 指针的概念 在C语言中&…

天正T20 专业建筑软件分享,天正T20全家桶软件安装包齐全!

天正T20 V9.0&#xff0c;在建筑工程领域中占据了举足轻重的地位。该软件以其高效、精确和易用的特点&#xff0c;赢得了广大工程师的青睐和信赖。 天正T20 V9.0软件具有强大的计算功能&#xff0c;可以精确地对建筑结构进行力学分析&#xff0c;包括静力分析、动力分析、稳定性…

使用Python实现钉钉Stream模式服务开发及内部程序通信

1、什么是Stream模式 Stream 模式是钉钉开放平台提供的一种集成方式&#xff0c;它可以监听机器人回调、事件订阅回调和注册卡片回调。使用 Stream 模式接入&#xff0c;钉钉开放平台将通过 Websocket 连接与应用程序通讯&#xff0c;Stream 模式将极大降低接入门槛和资源依赖…

Windows系统开启python虚拟环境

.\env4socre\Scripts\activate : 无法加载文件 E:\SocreMan\env4socre\Scripts\Activate.ps1&#xff0c;因为在此系统上禁止运行脚本。 环境&#xff1a;windows 11、vscode 1、用管理员权限打开powershell 输入set-executionpolicy remotesigned&#xff0c;选择Y 2、返回v…

信创认证 | Smartbi Insight V11成功适配申威3231处理器

在信息技术飞速发展的浪潮中&#xff0c;软硬件的深度融合与协同发展已成为推动行业创新的关键因素。 近日&#xff0c;思迈特商业智能与数据分析软件[简称&#xff1a;Smartbi Insight]V11在统信服务器操作系统V20和中电科申泰信息科技有限公司产品申威3231处理器环境下完成适…

【Linux 命令行参数解析函数getopt()】原理及直白理解

最近写代码恰好碰见getopt()这个函数&#xff0c;去网上找了很久&#xff0c;说实话&#xff0c;其他人写的有点看不懂&#xff0c;所以将我认为可以便于理解的地方描述一下&#xff1a; int getopt(int argc, char * const argv[], const char *optstring);首先理解这个函数的…

pdf合并,这三种方法学会了吗?

在信息爆炸的时代&#xff0c;PDF文档凭借其跨平台、不易修改的特性&#xff0c;成为了我们工作和学习中不可或缺的一部分。然而&#xff0c;当面对多个PDF文件需要合并成一个完整的文档时&#xff0c;许多人可能会感到头疼。今天&#xff0c;就让我们一起来探讨三种高效的PDF合…

OOXML入门学习

进入-飞入 <par> <!-- 这是一个并行动画序列的开始。"par"代表并行&#xff0c;意味着在这个标签内的所有动画将同时开始。 --><cTn id"5" presetID"2" presetClass"entr" presetSubtype"4" fill"hold&…

利用大模型技术,打造本地个人专属知识库

文章目录 利用大模型技术&#xff0c;打造本地个人专属知识库一 简介二 部署2.1 硬件要求2.2 部署信息2.3 通过docker部署、启动Ollama2.3 进入Ollama容器、拉取qwen2:7b模型2.4 测试Ollama2.5 通过docker部署、启动MaxKB2.6 登录MaxKB管理后台2.7 MaxKB系统配置2.8 创建知识库…

第56期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

一种自定义SPI通信协议

本文介绍一种自定义SPI通信协议。 项目开发过程中&#xff0c;有时候会涉及到主处理器或FPGA和MCU之间的SPI通信&#xff0c;涉及到通信就需要考虑通信协议&#xff0c;本文给出一种简单的通信协议。 1.协议格式 协议格式如下图。 其中&#xff0c;将40 bit划分为2大部分&am…

Spring Boot 过滤器和拦截器详解

目录 Spring Boot 过滤器1.什么是过滤器2.工作机制3.实现过滤器 Spring Boot 拦截器1. 什么是拦截器2. 工作原理3.实现4.拓展&#xff08;MethodInterceptor 拦截器&#xff09;实现 过滤器和拦截器区别过滤器和拦截器应用场景过滤器拦截器 Spring Boot 过滤器 1.什么是过滤器 …

OpenCV视觉--视频人脸微笑检测(超详细,附带检测资源)

目录 概述 具体实现 1.加载分类器 2.打开摄像头并识别人脸 3.处理人脸并检测是否微笑 效果 总结 概述 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习库&#xff0c;广泛应用于图像处理和视频分析等领…

精密机器中的交叉导轨负荷与容许负荷的差异!

交叉导轨的设计和制造过程中&#xff0c;负荷及容许负荷是至关重要的参数&#xff0c;只有准确计算出交叉导轨的载荷&#xff0c;才能保证交叉导轨的稳定性和使用寿命。 负荷和容许载荷是两个不同的参数&#xff0c;那这两者的有什么差异呢&#xff1f; 交叉导轨的负荷是指其承…

[深度学习] 前馈神经网络

前馈神经网络&#xff08;Feedforward Neural Network, FFNN&#xff09;是人工神经网络中最基本的类型&#xff0c;也是许多复杂神经网络的基础。它包括一个输入层、一个或多个隐藏层和一个输出层。以下是详细介绍&#xff1a; 1. 结构 1. 输入层&#xff08;Input Layer&am…

在微信小程序中使用svg图标

在项目中引入图标组件是很常见的一个问题&#xff0c;但是这里我在小程序中引入图标组件的时候报错了&#xff01; 这个主要原因是 微信小程序上不支持 SVG 字体图标&#xff01; <image src"./xx.svg"/>所以参考微信开放社区 我们想要在微信小程序中使用svg图…

java基于ssm+jsp 电子商城系统

1管理员功能模块 管理员登录&#xff0c;通过填写用户名、密码进行登录&#xff0c;如图1所示。 图1管理员登录界面图 管理员登录进入电子商城系统可以查看个人中心、用户管理、医生管理、药品信息管理、线上诊疗管理、医生信息管理、管理员管理、论坛管理、系统管理、订单管…

智慧数据中心可视化:高效管理与直观监控的未来

随着数据中心的规模和复杂性不断增加&#xff0c;传统管理方式难以满足需求。智慧数据中心通过图扑可视化实现实时数据监控和智能分析&#xff0c;将复杂的基础设施直观呈现&#xff0c;极大提升了运维效率、故障排查速度和资源优化能力&#xff0c;为企业提供现代化、智能化的…

卡尔曼滤波公式推导笔记

视频见B站上DR_CAN的卡尔曼滤波器 【卡尔曼滤波器】3_卡尔曼增益超详细数学推导 &#xff5e;全网最完整_哔哩哔哩_bilibili