使用vue3+ts+input封装上传组件,上传文件显示文件图标

news2025/6/9 17:24:06

效果图:
在这里插入图片描述
代码

<template>
  <div class="custom-file-upload">
    <div class="upload">
      <!-- 显示已选择的文件 -->
      <div class="file-list">
        <div v-for="(item, index) in state.filsList" :key="index" class="file-item">
          <div v-if="item.url.includes('.pdf')" @click="priviewPdf(item.url)" class="img filePdf">
            <div style="text-align: center;">
              <div class="overHiden" style="font-size: 14px;" :title="item.wjmc">{{ item.wjmc }}</div>
              <el-icon><Document /></el-icon>
            </div>
          </div>
          <el-image
            class="img"
            :src="state.baseUrl + '/file/file/preview?accessToken='+state.token+'&'+'filePath='+item.url"
            :preview-src-list="[state.baseUrl + '/file/file/preview?accessToken='+state.token+'&'+'filePath='+item.url]"
            show-progress
            fit="cover"
            v-else
          />
          <!-- <img @click="priviewImg(item.src)" v-else class="img" :src="state.baseUrl + '/file/file/preview?accessToken='+state.token+'&'+'filePath='+item.url" /> -->
          <el-icon @click="removeFile(index)" class="delete"><CloseBold /></el-icon>
        </div>
        <!-- 自定义样式的div -->
        <div class="upload-btn" @click="openFileSelector">
          <el-icon><Plus /></el-icon>
        </div>
      </div>
    </div>
    
    <!-- 隐藏的文件输入 -->
    <input 
      type="file" 
      ref="fileInput" 
      @change="handleFileChange" 
      multiple 
      accept=".jpg,.png,.pdf" 
      style="display: none;" 
    />
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus';
import { uploadFile } from '@/api/index'
import { getToken } from '@/utils/tools'
const fileInput = ref(null)
const emits = defineEmits(['successFile', 'handleRemove'])
const props = defineProps({
    filsList: Object
});
const state = reactive({
  filsList: [] as any,
  token: getToken()
})
onMounted(() => {
  state.filsList = props.filsList
})
watch(
  () => props.filsList,
    (newList, oldList) => {
      state.filsList = newList
  }
)
// 打开文件选择对话框
const openFileSelector = () => {
  fileInput.value.click()
}

// 处理文件选择
const handleFileChange = (e: any) => {
  const params = {
      files: e.target.files[0]
  }
  var filename = e.target.files[0].name
  // console.log(e.target.files[0])
  // 上传文件接口
  uploadFile(params).then((res: any) => {
      state.filsList.push({
        url: res[0],
        wjmc: filename
      })
      console.log(state.filsList)
      ElMessage.success('上传成功')
      // emits('successFile', res[0], filename)
      emits('successFile', state.filsList)
    }).catch((_) => {
      ElMessage.success('上传失败')
    })
}

// 查看pdf文件
const priviewPdf = (url: any) => {
  var pdfUrl = window.origin + `/file/file/preview?accessToken=${state.token}&filePath=${url}`
  window.open(pdfUrl, '_blank')
}

// 移除文件
const removeFile = (index:any) => {
  // state.filsList.splice(index, 1)
  emits('handleRemove', index)
}

// 格式化文件大小
const formatSize = (size:any) => {
  if (size < 1024) return size + ' B'
  if (size < 1048576) return (size / 1024).toFixed(1) + ' KB'
  return (size / 1048576).toFixed(1) + ' MB'
}
// 重置filelist
const resetFil = () => {
  state.filsList = []
}
// 导出对象
defineExpose({ resetFil });
</script>

<style scoped>
.custom-file-upload {
  align-items: center;
  display: flex;
  /* max-width: 400px; */
}
.upload{
  align-items: center;
  display: flex;
}
.upload-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  border-radius: 4px;
  border: 1px solid #cdd0d6;
  background-color: #fafafa;
  width: 148px;
  height: 148px;
  font-size: 28px;
  transition: background-color 0.3s;
  color: #909399;
  cursor: pointer;
}

.upload-btn:hover {
  border: 1px dashed #66b1ff;
}

.upload-btn i {
  margin-right: 8px;
}

.file-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 8px;
  cursor: pointer;
}

.file-item {
  display: flex;
  align-items: center;
  height: 148px;
  width: 148px;
  border-radius: 4px;
  margin-right: 4px;
  position: relative;
}
.delete{
  position: absolute;
  right: 4px;
  top: 4px;
}
.img{
  height: 148px;
  width: 148px;
  border-radius: 4px;
}
.filePdf{
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  border-radius: 4px;
  border: 1px solid #cdd0d6;
  
}

.file-item button {
  background: none;
  border: none;
  color: #909399;
  cursor: pointer;
  font-size: 16px;
}

.file-item button:hover {
  color: #f56c6c;
}
.overHiden{
  white-space: nowrap;       /* 禁止换行 */
  overflow: hidden;          /* 溢出内容隐藏 */
  text-overflow: ellipsis;   /* 溢出时显示省略号 */
}
</style>

使用

// 引入
import uploadFile from '@/components/uploadFile/index.vue'
const uploadFileRef = ref<any>(null);

dom结构
<uploadFile
    @successFile="onSuccess"
    @handleRemove="handleRemove"
    :filsList="state.ruleForm.files"
    ref="uploadFileRef"
/>
事件
// 上传成功--返回图片地址
const onSuccess = (list:any) => {
    state.ruleForm.files = list
}

// 删除上传图片--返回下表删除
const handleRemove = (index: any) => {
    state.ruleForm.files.splice(index, 1)
}

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

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

相关文章

【Linux】Ubuntu 创建应用图标的方式汇总,deb/appimage/通用方法

Ubuntu 创建应用图标的方式汇总&#xff0c;deb/appimage/通用方法 对于标准的 Ubuntu&#xff08;使用 GNOME 桌面&#xff09;&#xff0c;desktop 后缀的桌面图标文件主要保存在以下三个路径&#xff1a; 当前用户的桌面目录&#xff08;这是最常见的位置&#xff09;。所…

LangGraph--Agent工作流

Agent的工作流 下面展示了如何创建一个“计划并执行”风格的代理。 这在很大程度上借鉴了 计划和解决 论文以及Baby-AGI项目。 核心思想是先制定一个多步骤计划&#xff0c;然后逐项执行。完成一项特定任务后&#xff0c;您可以重新审视计划并根据需要进行修改。 般的计算图如…

Spring Boot 常用注解面试题深度解析

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot 常用注解面试题深度解析一、核心…

Linux系统的CentOS7发行版安装MySQL80

文章目录 前言Linux命令行内的”应用商店”安装CentOS的安装软件的yum命令安装MySQL1. 配置yum仓库2. 使用yum安装MySQL3. 安装完成后&#xff0c;启动MySQL并配置开机自启动4. 检查MySQL的运行状态 MySQL的配置1. 获取MySQL的初始密码2. 登录MySQL数据库系统3. 修改root密码4.…

408第一季 - 数据结构 - 栈与队列

栈 闲聊 栈是一个线性表 栈的特点是后进先出 然后是一个公式 比如123要入栈&#xff0c;一共有5种排列组合的出栈 栈的数组实现 这里有两种情况&#xff0c;&#xff0c;一个是有下标为-1的&#xff0c;一个没有 代码不用看&#xff0c;真题不会考 栈的链式存储结构 L ->…

【RTP】Intra-Refresh模式下的 H.264 输出,RTP打包的方式和普通 H.264 流并没有本质区别

对于 Intra-Refresh 模式下的 H.264 输出,RTP 打包 的方式和普通 H.264 流并没有本质区别:你依然是在对一帧一帧的 NAL 单元进行 RTP 分包,只不过这些 NAL 单元内部有部分宏块是 “帧内编码” 而已。下面分步骤说明: 1. 原理回顾:RFC 6184 H.264 over RTP 按照 RFC 6184 …

Redis实战-消息队列篇

前言&#xff1a; 讲讲做消息队列遇到的问题。 今日所学&#xff1a; 异步优化消息队列基于stream实现异步下单 1. 异步优化 1.1 需求分析 1.1.1 现有下单流程&#xff1a; 1.查询优惠劵 2.判断是否是秒杀时间&#xff0c;库存是否充足 3.实现一人一单 在这个功能中&…

(三)Linux性能优化-CPU-CPU 使用率

CPU使用率 user&#xff08;通常缩写为 us&#xff09;&#xff0c;代表用户态 CPU 时间。注意&#xff0c;它不包括下面的 nice 时间&#xff0c;但包括了 guest 时间。nice&#xff08;通常缩写为 ni&#xff09;&#xff0c;代表低优先级用户态 CPU 时间&#xff0c;也就是进…

佰力博科技与您探讨材料介电性能测试的影响因素

1、频率依赖性 材料的介电性能通常具有显著的频率依赖性。在低频下&#xff0c;偶极子的取向极化占主导&#xff0c;介电常数较高&#xff1b;而在高频下&#xff0c;偶极子的取向极化滞后&#xff0c;导致介电常数下降&#xff0c;同时介电损耗增加。例如&#xff0c;VHB4910…

K8S认证|CKS题库+答案| 4. RBAC - RoleBinding

目录 4. RBAC - RoleBinding 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、查看SA和role 3&#xff09;、编辑 role-1 权限 4&#xff09;、检查role 5&#xff09;、创建 role和 rolebinding 6&#xff0…

React 新项目

使用git bash 创建一个新项目 建议一开始就创建TS项目 原因在Webpack中改配置麻烦 编译方法:ts compiler 另一种 bable 最好都配置 $ create-react-app cloundmusic --template typescript 早期react项目 yarn 居多 目前npm包管理居多 目前pnpm不通用 icon 在public文件夹中…

AI编程在BOSS项目的实践经验分享

前言 在人工智能技术革新浪潮的推动下&#xff0c;智能编程助手正以前所未有的速度重塑开发领域。这些基于AI的代码辅助工具通过智能提示生成、实时错误检测和自动化重构等功能&#xff0c;显著提升了软件工程的全流程效率。无论是初入行业的开发者还是资深程序员&#xff0c;…

数学:”度量空间”了解一下?

度量空间是现代数学中一种基本且重要的抽象空间。以下是对它的详细介绍&#xff1a; 定义 相关概念 常见的度量空间举例 度量空间的类型 度量空间的作用 度量空间是拓扑空间的一种特殊情况&#xff0c;它为拓扑空间的研究提供了具体的模型和实例。同时&#xff0c;度量空间在…

jenkins脚本查看及备份

位置与备份 要完整备份 Jenkins 的所有脚本和相关配置&#xff0c;包括 Jenkinsfile、构建脚本&#xff08;如 .sh / .bat&#xff09;、Job 配置、插件、凭据等&#xff0c;你可以从两个层面入手&#xff1a; ✅ 一、完整备份 Jenkins 主目录&#xff08;最全面&#xff09; …

用电脑通过网口控制keysight示波器

KEYSIGHT示波器HD304MSO性能 亮点: 体验 200 MHz 至 1 GHz 的带宽和 4 个模拟通道。与 12 位 ADC 相比,使用 14 位模数转换器 (ADC) 将垂直分辨率提高四倍。使用 10.1 英寸电容式触摸屏轻松查看和分析您的信号。捕获 50 μVRMS 本底噪声的较小信号。使用独有区域触摸在几秒…

《如何使用MinGW-w64编译OpenCV和opencv_contrib》

《如何使用MinGW-w64编译OpenCV和opencv_contrib》 在Windows环境下使用MinGW编译OpenCV和opencv_contrib是一个常见需求,尤其是对于那些希望使用GCC工具链而非Visual Studio的开发者。下面我将详细介绍这个过程。 准备工作 首先需要安装和准备以下工具和库: MinGW(建议使…

模拟搭建私网访问外网、外网访问服务器服务的实践操作

目录 实验环境 实践要求 一、准备工作 1、准备四台虚拟机&#xff0c;分别标号 2、 防火墙额外添加两块网卡&#xff0c;自定义网络连接模式 3、 关闭虚拟机的图形管理工具 4、关闭防火墙 5、分别配置四台虚拟机的IP地址&#xff0c;此处举一个例子&#xff08;使用的临…

vue中Echarts的使用

文章目录 Echarts概述什么是EchartsEcharts的好处 Vue中Echarts的使用Echarts的安装Echarts的引入 Echarts概述 什么是Echarts Apache ECharts&#xff1a;一个基于 JavaScript 的开源可视化图表库。 其官网如下&#xff1a;https://echarts.apache.org/zh/index.html Echar…

【C++项目】负载均衡在线OJ系统-1

文章目录 前言项目结果演示技术栈&#xff1a;结构与总体思路compiler编译功能-common/util.hpp 拼接编译临时文件-common/log.hpp 开放式日志-common/util.hpp 获取时间戳方法-秒级-common/util.hpp 文件是否存在-compile_server/compiler.hpp 编译功能编写&#xff08;重要&a…

Spring Boot微服务架构(十一):独立部署是否抛弃了架构优势?

Spring Boot 的独立部署&#xff08;即打包为可执行 JAR/WAR 文件&#xff09;本身并不会直接丧失架构优势&#xff0c;但其是否体现架构价值取决于具体应用场景和设计选择。以下是关键分析&#xff1a; 一、独立部署与架构优势的关系 内嵌容器的优势保留 Spring Boot 独立部署…