封装一个vue3的文件上传组件(拖拽或点击选择文件)

1. 效果

在这里插入图片描述

选择文件后:
在这里插入图片描述

2. 代码

<template><divclass="drop-zone c-normal":class="{borderOutline: outline,}"@dragover.prevent@drop.prevent="handleDrop"@click="chooseFiles"><div v-if="files.length < 1" class="flex items-center justify-center"><slot name="blank"><div class="f-6"><svg-icon icon-class="upload-fill"></svg-icon></div></slot></div><div v-if="files.length < 1"><slot name="title" :is-dragging="isDragging"><div v-if="!isDragging" class="upload-instructions f6">点击或将文件拖到这里上传</div><div v-else class="dragging-feedback">释放以上传文件</div></slot></div><div class="flex items-center"><div v-for="(file, index) in files" :key="index" class="flex file-item pa2 flex-column"><div class="f2 pa2"><svg-icon icon-class="file" /></div><div class="f6 truncate">{{ file.name }}</div><div class="delete-icon" @click.stop="removeFile(index)"><svg-icon icon-class="delete" /></div></div></div><input ref="fileInput" type="file" multiple style="display: none" @change="inputChange" /></div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import SvgIcon from '@/components/SvgIcon/SvgIcon.vue';type Prop = {outline?: boolean;maxFiles?: number;data: any;fileChange?: (data: any) => boolean | Promise<boolean>;
};const props = withDefaults(defineProps<Prop>(), {outline: true,maxFiles: -1,data: [],fileChange: () => true,
});const emits = defineEmits(['update:data']);const isDragging = ref(false);
const files = computed({get() {return props.data;},set: async (val) => {const flag = await props.fileChange(val);if (val.length > props.maxFiles){//:TODO 这里需要自定义一哈console.log('最多只能上传'+props.maxFiles+'个文件');return}if (flag === false) {return;}emits('update:data', val);},
});
const fileInput = ref<HTMLInputElement>();const handleDrop = (e: DragEvent) => {isDragging.value = false;const newFiles: File[] | any = e.dataTransfer?.files || [];files.value = [...files.value, ...newFiles];
};const chooseFiles = () => {if (fileInput.value) {fileInput.value.click();}
};const inputChange = (e: Event) => {const target = e.target as HTMLInputElement;const newFiles = target.files || [];files.value = [...files.value, ...newFiles];
};const removeFile = (index: number) => {files.value.splice(index, 1);
};
</script><style lang="scss" scoped>
/*这里的我用的是外部的公共样式, 实际并没有在组件内, 这里将用到的样式复制在下面了*/
:root{--c-normal: #a6a5ad;
}
.flex {display: flex;
}
.items-center {align-items: center;
}
.justify-center {justify-content: center;
}
.c{&-normal{color: var(--c-normal);}
}
.f2 {font-size: 2.25rem;
}
.pa2 {padding: 0.5rem;
}
.f-6,
.f-headline {font-size: 6rem;
}
.truncate {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;
}
/* ↑↑↑ 上面都是引用的公共样式  */
.drop-zone {box-sizing: border-box;width: 100%;height: 100%;padding: 20px;text-align: center;min-height: 150px;overflow-y: auto;&.borderOutline {border: 2px dashed #aaa;}.dragging-feedback {background-color: var(--c-normal);}.upload-instructions {margin-bottom: 10px;}.file-item {position: relative;width: 6rem;.delete-icon {position: absolute;top: 5px;right: 5px;cursor: pointer;color: var(--c-normal);&:hover {color: #1a1a1a;}}}
}
</style>

这个组件引入了 <svg-icon/>这个组件(这里可以替换为自己需要的组件), svg-icon 这个组件的封装可以参考这篇文章: vue3 + vite +ts 封住昂svg-icon组件

这篇文章距离现在时间比较长了, 可能会有一些版本问题, 若遇问题可参考其他相似的文章

如果有什么问题或建议欢迎评论或留言

3. 组件说明

prop参数

name说明默认值
outline外边框true
maxFiles最大文件数(大于-1时生效)-1
data文件数据(双向绑定的)[]
fileChange当文件变化时生效需返回一个boolen或Promise<boolean>类型()=>true

slot

name说明参数
blank文件时显示的图标-
title显示的文字isDragging是否正在拖拽

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

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

相关文章

并查集 (Union-Find) :从基础到优化

并查集 (Union-Find) 并查集是一种树形数据结构&#xff0c;主要用于处理不相交集合&#xff08;Disjoint Set&#xff09;的合并和查询问题。它特别适用于解决有关连通性的问题&#xff0c;比如在图论中判断两点是否在同一个连通分量中。并查集可以高效地支持以下两种操作&am…

2024年数字化转型与管理国际学术会议(DTM 2024)

目录 重要信息 大会简介 大会组委 征稿主题 论文出版 会议议程 参会方式 重要信息 大会官网&#xff1a;www.icemme.org&#xff08;点击了解大会&#xff0c;投稿等详细信息&#xff09; 大会时间&#xff1a;2024年11月22-24日 大会地点&#xff1a;中国-大连 大会…

Cloudflare为网站添加AI审计 可检查AI爬虫何时抓取和抓取频次以及直接屏蔽爬虫

网络服务提供商 Cloudflare 宣布即日起为所有网站 (包括免费托管的网站) 带来 AI 审计功能&#xff0c;该功能目前处于测试阶段&#xff0c;可以分析 AI 公司的爬虫和抓爬数据。新的 AI 审计工具 (Cloudflare AI Audit) 主要提供 AI 公司的爬虫何时到网站来抓取数据、抓取的数据…

【Rust练习】16.模式

文章题目来自&#xff1a;https://practice-zh.course.rs/pattern-match/patterns.html 1 &#x1f31f;&#x1f31f; 使用 | 可以匹配多个值, 而使用 … 可以匹配一个闭区间的数值序列 fn main() {} fn match_number(n: i32) {match n {// 匹配一个单独的值1 > println!(…

16. C++ TinyWebServer项目总结(16. 服务器调制、调试和测试)

主要包括&#xff1a; 使用 tcpdump 抓包&#xff1b;使用 gdb 调试器&#xff1b;使用压力测试工具&#xff0c;模拟现实世界中的高并发请求&#xff0c;测试服务器在高压状态下的稳定性。 最大文件描述符数 Linux 对应用进程能打开的最大文件描述符数量有两个层次的限制&a…

4. 数据结构: 对象和数组

数字、布尔值和字符串是构建数据结构的原子。不过&#xff0c;许多类型的信息需要不止一个原子。对象允许我们对值&#xff08;包括其他对象&#xff09;进行分组&#xff0c;从而构建更复杂的结构。到目前为止&#xff0c;我们所构建的程序都受到限制&#xff0c;因为它们只能…

软件设计模式——工厂模式

软件设计模式——工厂模式 文章目录 软件设计模式——工厂模式一、设计模式的认知1.1 什么是软件设计模式&#xff1a;1.2 为什么要学习设计模式&#xff1a;1.3 设计模式的分类&#xff1a; 二、工厂模式2.1 工厂模式实例&#xff1a; 一、设计模式的认知 1.1 什么是软件设计…

WordPress LearnPress插件 SQL注入复现(CVE-2024-8522)

0x01 产品描述&#xff1a; LearnPress 是一款功能强大的 WordPress LMS&#xff08;学习管理系统&#xff09;插件&#xff0c;适用于创建和销售在线课程。凭借其直观的界面和丰富的功能&#xff0c;无论您是否具备编程背景&#xff0c;都能轻松搭建起在线教育网站。学会如何使…

Java之路--瓦解逻辑控制与方法使用已是瓮中捉鳖

嗨嗨大家&#xff01;今天我们来学习逻辑运算和方法的使用~ 目录 一 逻辑控制 1 分支结构 1.1 if语句 1.2 switch 语句 2 循环结构 2.1 while 循环 2.2 for 循环 2.3 do while 循环 2.4 break 2.5 continue 3. 输出输入 二、方法的使用 1 方法定义语法 2 实参和…

网络通信——DHCP

目录 一.DHCP应用场景 二.通信过程 三.DHCP报文 四.DHCP通信原理 &#xff08;1&#xff09;租借过程 &#xff08;2&#xff09;DHCP 租期更新 &#xff08;3&#xff09;DHCP重绑定 五.一般路由器的DHCP支持两种地址池 &#xff08;1&#xff09;接口地址池 &…

进制转换,原码反码补码

正数的三码合一 1个byte8位&#xff0c;-128符号位溢出了&#xff0c;所以是1000 0000

基于Python大数据的B站热门视频的数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

全连接神经网络

这里写目录标题 全连接神经网络vs前馈神经网络基于全连接神经网络的手写数字识别使用Pytorch实现纯Python实现 全连接神经网络的局限 端到端学习 深度学习有时也称为端到端机器学习&#xff08;end-to-end machine learning&#xff09;。这里所说的端到端是指从一端到另一端的…

David律所代理Jose Martin幽默水果版权首发维权,尚未TRO

案件基本情况&#xff1a;起诉时间&#xff1a;2024/9/18案件号&#xff1a;2024-cv-08484原告&#xff1a;Jose Martin原告律所&#xff1a;David起诉地&#xff1a;伊利诺伊州北部法院涉案商标/版权&#xff1a;原告品牌简介&#xff1a;西班牙的卓越艺术家Jose Martin以他非…

网络原理之IP协议(网络层)

目录 前言 什么是IP协议&#xff1f; IP协议的协议头格式 16位总长度&#xff08;字节数&#xff09; 16位标识、3位标志位和13位片偏移 8位生存时间 IP地址管理 1.动态分配IP 2.NAT机制&#xff08;网络地址转换&#xff09; NAT机制是如何工作的 NAT机制的优缺点…

Nginx反向代理配置支持websocket

一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket&#xff0c;使用了HTTP/1.1中可用的协议切换机制&#xff08;RFC 2616: Hypertext Transfer Protocol – HTTP/1.1&#xff09;。 然而&#xff0c;这里有一个微妙之处:由于“升级”…

论文阅读:A Generalization of Transformer Networks to Graphs

论文阅读&#xff1a;A Generalization of Transformer Networks to Graphs 论文地址1 摘要2 贡献Graph TransformerOn Graph Sparsity&#xff08;图稀疏&#xff09;On Positional Encodings&#xff08;位置编码&#xff09;3 Graph Transformer Architecture&#xff08;架…

C++:日期类的实现

目录 一、前言 二、头文件 三、各个函数的实现 打印、检查日期及获取日期 、、-、-、 、<、<、>、>、 &#xff01; 日期-日期 >>、<< 一、前言 前面几篇讲了关于类和对象的一些知识&#xff0c;本篇就来实现一下前面用到的日期类。 二、头文…

市面第一款 C++ 版本的U盘装机软件(即将上线)

市面大部分U盘装机软件&#xff0c;都是采用Au3脚本开发&#xff0c;而且有各种捆绑&#xff0c;闲来无聊&#xff0c;采用Qt C制作一款CU盘装机软件&#xff0c;从此告别Au3脚本&#xff0c;各种炫酷界面随便换&#xff0c;敬请期待 另外两个界面暂时不公布&#xff0c;防止Au…

uni-app页面调用接口和路由(四)

文章目录 一、路由二、页面调用接口二、路由跳转1.uni.navigateTo(OBJECT)2.uni.redirectTo(OBJECT)3.uni.reLaunch(OBJECT)4.uni.switchTab(OBJECT)5.uni.navigateBack(OBJECT) 总结 一、路由 路由配置 uni-app页面路由为框架统一管理&#xff0c;开发者需要在pages.json里配…