0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

前端文件上传的几种交互造轮子

OSC开源社区 来源:OSCHINA 社区 2023-07-04 10:39 次阅读

来源| OSCHINA 社区

作者 | 京东云开发者-京东物流 刘海鼎

背景

前端文件上传本来是一个常规交互操作,没什么特殊性可言,但是最近在做文件上传,需要实现截图粘贴上传,去找了下有没有什么好用的组件,网上提供的方法有,但是没找完整的组件来支持 cv 上传,经过了解发现可以用剪贴板功能让自己的 cv 实现文件上传,于是自己就整合了目前几种文件上传的交互方式,码了一个支持 cv 的 vue3 文件上传组件(造个轮子)。

介绍

作为一个完整的组件内容还是挺多的,这里主要介绍下上传交互中一些主要功能,包括上传的几种交互方式, 上传进度的获取,上传类型的限制,默认上传请求和自定义上传请求。 以下代码都是非完整代码,大家用于参考实现过程,可以通过以下代码修改来完成自己想要的交互功能。

几种交互

1,点击选择上传

点击选择是最常见的上传交互,之前原生上传控件,样式修改比较麻烦,为了修改上传样式,我们可以把该控件设置隐藏,用其他元素通过从 click 交互,来触发该文件选择控件。在选择文件控件上绑定 onchange 事件,该控件在 change 后获取到文件,然后调用上传方法,实现如下:

2,拖动上传

拖拽文件上传,首先在页面上建立一个拖放区域,在拖放区域上绑定拖放事件,监听拖放事件 drop 内容中 datTransfer 中是包含 files, 如果存在 files,获取 files 然后调用上传附件方法。 拖放区域可以通过事件 dragover 来检查拖放文件是否进入拖放区域来设置拖放区域悬浮样式,通过 dragleave 来检查离开拖放区取消悬浮样式。 进行交互提示 实现如下:
+
3,复制上传(复制检测区域设置)

复制上传的交互步骤

・将文件保存到剪贴板:执行键盘快捷键或者使用鼠标复制

・将鼠标移动到可粘贴区: 判断是否移动到可粘贴区,来确定是否在执行粘贴后上传,否则整个页面都会作为粘贴区

・执行粘贴操作:执行键盘粘贴快捷键(ctrl+v) 粘贴区绑定 paste 事件,在触发 paste 事件前将鼠标移到粘贴区,复制会被检查不在粘贴区,阻止上传操作,实现如下:

上传模式

根据以上三种交互,大家可自由组合上传形式,比如点击和拖拽,拖拽和粘贴组合等等,我这边目前按点击,拖拽,粘贴叠加组合,设置为:

・点击上传,click

・拖拽上传 drag(包括点击上传和拖拽上传)

・粘贴上传 paste (包括点击,拖拽和复制上传)

通过传参 uploadeMode 设置 (click, drag, paste)

组件设置:

组件应用


    
点击上传

文件限制

文件限制包括是否多文件上传限制 multiple, 上传数量 limit 限制,上传类型 accept 限制,这些设置参考了 element-plus 上传组件,在其基础上做了简化。实现如下 multiple 和 accept 首先需要在点击控件上绑定,以便于在点击选择上传时就能够过滤对应文件,拖拽上传和粘贴上传,无法通过 input [type=file] 组件控制需要在上传方法中判断过滤,(以粘贴上传为例) 组件实现

上传进度设置

获取文件上传进度,使用 ajax 中的 progress 事件监听机制,回传数据 loaded 进度,和 ttotal 进行计算,获取到计算的百分比通过 process 插槽线上在界面上。 具体实现如下: 组件实现 文件限制后执行组件上传,默认情况下走内置的上传方法,如果做了自定义,上传进度也需要自己实现(自己实现过程可以参考内置方法中的实现)

// 上传方法调用
ajaxUpload({...props, file})
// 上传方法实现
ajaxUpload = (options) => {
const xhr = new XMLHttpRequest()
    const action = option.action
    console.log(xhr, xhr.upload)
    if (xhr.upload) {
    // 建立progress监听
      xhr.upload.addEventListener('progress', (evt:any) => {
        const progressEvt = evt
        progressEvt.percent = evt.total > 0 ? (evt.loaded / evt.total) * 100 : 0
        // 回传进度数据
        option.onProgress(progressEvt)
      })
    }
}

同样文件上传成功,异常等方法也可以通过监听 load 并且判断 xhr.status 来实现,

xhr.addEventListener('load', () => {
      if (xhr.status < 200 || xhr.status >= 300) {
        return option.onError(getError(action, option, xhr))
      }
      option.onSuccess(getBody(xhr))
})
组件使用 ・配置获取进度数据回调函数 onProgress ・配置接收回传的进度数据进行赋值 ・配置进度条插槽显示进度数据

   
点击上传
自定义上传请求

默认情况下,不需要自定义上传请求,组件内置了上传请求,如果个人有需求可以自定义上传请求,子定义上传请求,是在文件限制流程后,检查是否有自定义请求方法,如果存在就将文件传入自定义请求方法。 组件实现:
// 上传文件
const uploadFiles = (files) => {
    if (files.length === 0) return
    const { limit, multiple, accept, httpRequest } = props
    // 是否多文件限制,主要用于拖拽和粘贴上传中
    if (!multiple) {
       files = Array.from(files).slice(0, 1)
    }
    // 文件数量
    if (limit && files.length > limit) {
       /*具体大家需要的逻辑可自行定义*/
       return
    }
    // 文件类型限制
    if (accept) {
       files = filesFiltered(Array.from(files), accept)
    }
    //在文件符合条件后执行上传方法
    // 自定义上传方法调用
    if(httpRequest) {
       return httpRequest(files)
    }
 }
组件应用: 注意点: 通过自定义上传方法实现时,在原来组件上的属性 action 无效

    
点击上传

总结

通过以上可以实现一个支持多种交互方式的文件上传组件,同时也将 element-plus 中文件上传的流程做了一个学习,因为该组件的实现过程就是参考了 element-plus 的实现,在 element-plus 上传的基础上添加了粘贴上传交互,该组件的实现重在交互方式,各个样式风格通过插槽自定义。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 文件
    +关注

    关注

    1

    文章

    540

    浏览量

    24402
  • 组件
    +关注

    关注

    1

    文章

    338

    浏览量

    17584

原文标题:前端文件上传的几种交互造轮子

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    上传文件

    上传文件必须小于20M吗?怎样能上传大于20M的文件
    发表于 08-10 20:11

    【MYD-Y6ULX申请】语音交互前端信号处理板

    项目名称:语音交互前端信号处理板试用计划:申请理由本人在语音交互领域有十年多的学习和开发经验,是国内早期的wifi音箱/无线多通道语音/语音交互整机方案设计的主导者,对无线音频/多通道
    发表于 01-22 10:34

    SMT全贴只要50元【华秋智

    PCB和元器件物料快递至华秋智工厂6)生产&收货:物料、资料文件确认后即可安排生产,24h出货注:本活动免认证,无需上传个人信息[url=https://data.hqchip.com:4006/t/ucS]>>马上参与马上下
    发表于 08-20 16:53

    goahead文件上传原理与步骤

    goahead文件上传原理:使用html form即表单提交文件上传请求,web服务器核心处理接收客户端Post过来的文件数据(注意post
    发表于 12-16 08:26

    如何利用扫地机轮子制作ROS移动机器人地盘

    制作ROS移动机器人地盘摘要概述硬件需求车体设计电路设计程序设计摘要本教程讲述如何利用扫地机轮子制作ROS移动机器人地盘。概述原本不打算自己轮子的,但是网上的移动机器人地盘要么巨贵--对于学生党
    发表于 01-14 08:36

    基于PHP大文件上传的研究和设计

    基于PHP大文件上传的研究和设计,感兴趣的可以看看。
    发表于 02-22 18:15 6次下载

    基于Iframe内联框架的异步文件上传与删除

    在Weh应用程序开发过程中,文件上传功能是个很常用又非常重要的功能,它要处理的内容主要包括:如何将上传文件文件的形式保存到服务器,
    发表于 11-11 10:20 5次下载
    基于Iframe内联框架的异步<b class='flag-5'>文件</b><b class='flag-5'>上传</b>与删除

    springMVC后台接受前端上传文件及下载文件

    通过MultipartHttpServletRequest对象来接受前端上传文件
    发表于 11-28 13:33 3249次阅读

    如何在java上传和下载文件

    文件上传在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件
    发表于 11-13 08:00 11次下载

    java Web如何实现文件上传与下载

    文件上传概述,实现web开发中的文件上传功能,需完成如下二步操作: 在web页面中添加上传输入项在servlet 中读取
    发表于 03-06 11:03 7次下载
    java Web如何实现<b class='flag-5'>文件</b>的<b class='flag-5'>上传</b>与下载

    PHP教程之文件系统和服务器的交互资料说明

    本文档的主要内容详细介绍的是PHP教程之文件系统和服务器的交互资料说明包括了:1.文件上传,2.使用目录函数 ,3.与文件系统的
    发表于 04-18 17:04 4次下载
    PHP教程之<b class='flag-5'>文件</b>系统和服务器的<b class='flag-5'>交互</b>资料说明

    天翼云存储上传文件 天翼云存储操作攻略

    天翼云存储怎么上传文件?天翼云是一款能够提供文件同步、备份及分享等服务的网络云存储平台,通过天翼云储存,多终端上传和下载、管理、分享文件变得
    发表于 06-28 11:11 3819次阅读

    使用OkHttp上传和下载文件时显示进度库使用

    核心进展 该库有助于在使用 OkHttp 上传和下载文件时显示进度。 CoreProgress 包括: 使用 OkHttp 下载文件时的进度。 使用 OkHttp 上传
    发表于 03-24 11:17 5次下载

    SpringBoot超大文件上传,实现秒传

    当标志位true为上传已经完成,此时如果有相同文件上传,则进入秒传逻辑。如果标志位为false,则说明还没上传完成,此时需要在调用set的方法,保存块号
    的头像 发表于 11-17 10:30 723次阅读

    MarkDown文件插入图片并上传GitHub

    MarkDown文件插入图片并上传GitHub
    的头像 发表于 01-12 17:02 784次阅读