图片复制上传,拖拽输入框上传,el-upload自定义上传方法(上传和备注框强关联)

news2024/11/25 3:05:11

1. 效果图:

在这里插入图片描述

2. 复制图片使用的方法:

  • 1.通过监听paste方法,获取复制内容
  • 2.获取复制内容中的clipboardData
  • 3.获取file文件进行上传
<input  @paste.native="handlePaste"  />

handlePaste(value){
   let files = value.clipboardData.files
   if(files){
     files=files[0]
   }else{
     files=value.clipboardData.items[0].getAsFile()
   }
   console.log(files)
}

3. 拖拽使用的方法:

  • 1.通过监听dragoverdropdragleave事件,进行判断拖拽
  • 2.drop释放鼠标时,获取对应文件的file并上传
 const e=Dom //节点

 // 挂载监听拖拽
 e.removeEventListener('dragover',this.handletDragover,false)
 e.addEventListener('dragover',this.handlePaste,false)

 // 挂载监听释放
 e.removeEventListener('drop',this.handletDrop,false)
 e.addEventListener('drop',this.handletDrop,false)

// 挂载监听离开
 e.removeEventListener('dragleave',this.handletDragleave,false)
 e.addEventListener('dragleave',this.handletDragleave,false)
 
 
 const handletDragover(e)=>{
        e.preventDefault();
        // 当拖拽到对应元素是设置样式
 }
const handletDragleave(e)=>{
      // 离开对应元素是设置样式
}
 const handletDrop(e)=>{
      const files = e.dataTransfer.files;
      // 获取对应的files,并进行上传
      e.preventDefault();
      e.stopPropagation();
   }

4. el-upload封装对应方法,并实现限制种类、大小等

  • 1.组件(copy-upload.vue):

    <template>
      <el-upload
                :action="sendUrl"
                :accept="acceptArray.length>0?acceptArray.map(n=>this.acceptType[n]).join(',') :'*'"
                class="upload-demo"
                :http-request="handleFileUpload"
                :headers="headers"
                :data="data"
                :on-preview="handlePreview"
                :on-remove="handleRemove"
                :before-upload="beforeUpload"
                :before-remove="beforeRemove"
                :on-success="handleSuccess"
                :on-erroe="handleError"
                :multiple="multiple"
                :limit="limit"
                :on-exceed="handleExceed"
                :file-list="fileList">
                <el-button size="small" type="primary">点击上传</el-button>
                <div v-if="size>0" slot="tip" class="el-upload__tip">{{ acceptTitle!=''?acceptTitle :`只能上传${(acceptArray.map(n=>n=='image'?'图片':n).join('/'))}文件` }},且不超过{{ filterSize(size) }}</div>
              </el-upload>
    </template>
    
    <script>
      export default {
        model:{
          prop:'parentFileList',
          event:'change-fileList'
        },
        props: {
            // 请求头
           headers:{
            type:Object,
            default:()=>{}
          },
            //   大小限制:10 * 1024 * 1024 = 10MB
          size:{
            type:Number,
            default:-1
          },
          //   展示的文字
          acceptTitle:{
            type:String,
            default:''
          },
          //   限制类型,按照acceptType数组里面来
          acceptArray:{
            type:Array,
            default(){
              return ['doc', 'docx', 'pdf', 'xls', 'xlsx','png','jpg','jpeg','gif']
            }
          },
          //  数量
          limit:{
            type:Number,
            default:null
          },
         //   是否可以多选
          multiple:{
            type:Boolean,
            default:false
          },
        //   额外数据
          data:{
            type:Object,
            default() {
                return {
                  uploadType: 'common',
                  security:'public',
                  module:'common',
              }
            }
          },
          // 存在的数据(v-model关联的)
          parentFileList:{
            type:Array,
            default(){
              return []
            }
          },
         //   请求头
          sendUrl:{
            type:String,
            default:''
          }
        },
        data() {
          return {
            acceptType:{
              'doc':'application/msword',
              'docx':'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
              'ppt':"application/vnd.ms-powerpoint",
              'pptx':'application/vnd.openxmlformats-officedocument.presentationml.presentation',
              'xls':'application/vnd.ms-excel',
              'xlsx':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
              'pdf':'application/pdf',
              'csv':'.csv',
              'txt':'text/plain',
              'image':'image/*',
              'png':'image/png',
              'gif':'image/gif',
              'jpg':'image/jpg',
              'jpeg':'image/jpeg'
            },
            fileList:[],
            isClearTitle:true
          };
        },
        watch: {
          parentFileList:{
            handler(value){
              this.fileList=value
            },
            deep:true,
            immediate:true
          },
          fileList:{
            handler(value){
              this.$emit('change-fileList',value)
            },
            deep:true,
          }
        },
        created(){
          // 抛处监听请求
          this.$emit('inpuPaste',(e)=>{
            if(e){
              // 挂载监听复制
              e.removeEventListener('paste',this.handlePaste,false)
              e.addEventListener('paste',this.handlePaste,false)
            }
    
          })
    
          this.$emit('inpuDrag',(e)=>{
            if(e){
              // 挂载监听拖拽
              e.removeEventListener('dragover',this.handletDragover,false)
              e.addEventListener('dragover',this.handlePaste,false)
    
              // 挂载监听释放
              e.removeEventListener('drop',this.handletDrop,false)
              e.addEventListener('drop',this.handletDrop,false)
    
              // 挂载监听离开
              e.removeEventListener('dragleave',this.handletDragleave,false)
              e.addEventListener('dragleave',this.handletDragleave,false)
            }
    
          })
        },
        methods: {
          handletDragover(e){
            e.preventDefault();
          },
          handletDragleave(e){
          },
          handletDrop(e){
            const files = e.dataTransfer.files;
            this.copyUp(files)
            e.preventDefault();
            e.stopPropagation();
          },
          filterSize(size){
              const pow1024=(num)=>{
                  return Math.pow(1024, num)
              }
              if (!size) return ''
              if (size < pow1024(1)) return size + ' B'
              if (size < pow1024(2)) return (size / pow1024(1)).toFixed(0) + ' KB'
              if (size < pow1024(3)) return (size / pow1024(2)).toFixed(0) + ' MB'
              if (size < pow1024(4)) return (size / pow1024(3)).toFixed(0) + ' GB'
              return (size / pow1024(4)).toFixed(2) + ' TB'
          },
          // 判断
          judegFileSize(file){
            let retunBoolean=true
            let fileSize = file.size
            //判断文件类型
            const fileExtArray=file.name.split('.')
            const judegFn=()=>{
              if(this.acceptArray.indexOf(fileExtArray.at(-1))==-1){
                this.$message.error(`${file.name}上传失败,只能上传${this.acceptArray.join('、')}`)
                retunBoolean=false
              }
            }
            if(this.acceptArray.length>0){
              if(this.acceptArray.indexOf('image')!=-1){
                var pattern = /(\.jpg|\.jpeg|\.png|\.gif)$/i;
                // 判断文件名是否匹配图片格式的正则表达式
                if (!pattern.test(`.${fileExtArray.at(-1)}`)) {
                  judegFn()
                }
              }else{
                judegFn()
              }
    
            }
            if(retunBoolean){
              if (this.size>0 &&  fileSize > this.size) {
                this.$message.error(`最大上传${this.filterSize(this.size)}`)
                retunBoolean=false
              }
            }
            if(!retunBoolean){
              this.isClearTitle=false
            }
            return retunBoolean
          },
          postUpObject(file){
            return {
                action:this.sendUrl,
                data:this.data,
                file:file,
                headers:this.headers,
                onSuccess:this.handleSuccess,
                onError:this.handleError
              }
          },
          // 自定义上传
          handleFileUpload(data) {
            const formData = new FormData();
            formData.append("file", data.file);
            if(data.data){
              Object.keys(data.data).forEach(key => {
                formData.append(key, data.data[key]);
              })
            }
            fetch(data.action, {
                    method: "POST",
                    body: formData,
                    headers: data.headers,
                    'Content-type': 'multipart/form-data'
              })
              .then(respone => respone.json())
              .then(res=>{
                if (data.onSuccess) data.onSuccess(res, data.file, this.fileList)
              }).catch(error=>{
                if (data.onError) data.onError({message:'上传失败'}, data.file, this.fileList)
            })
          },
          // 上传之前,需要将数据追加到fileList,复制图片是存在复制
          beforeUpload(file){
            const isFile=this.judegFileSize(file)
            if(isFile){
              if(this.multiple){
                this.fileList.push(file)
              }else{
                this.fileList=[file]
              }
            }
            return isFile
          },
    
          // 点击(预览),需要在成功后将url放入file里面
          handlePreview(file) {
            if(file.status=="success" && file.url){
              const extArray=file.url.split('.')
              const extArrayAll=['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
              if(extArrayAll.indexOf(extArray.at(-1))!=-1){
                window.open(`https://view.officeapps.live.com/op/view.aspx?src=${file.url}`)
              }else{
                window.open('http://www.pfile.com.cn/api/profile/onlinePreview?url='+encodeURIComponent(file.url));
              }
            }
          },
          // 超过限制
          handleExceed(files, fileList) {
            this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
          },
           // 删除
          handleRemove(file, fileList) {
            const index=this.fileList.findIndex(n=>n.uid==file.uid)
            if(index!=-1){
              this.fileList.splice(index,1)
               this.isClearTitle=true
            }
          },
          // 删除之前
          beforeRemove(file, fileList) {
            if(this.isClearTitle){
              return this.$confirm(`确定移除 ${ file.name }`);
            }
    
          },
          // 成功&&插入对应的url
          handleSuccess(res,file,fileList){
            if(res.code && res.code==200){
              const resData=res.data
              const index=this.fileList.findIndex(n=>n.uid==file.uid)
              if(index!=-1){
                const fileData=this.fileList[index]
                this.fileList.splice(index,1,Object.assign(fileData,{url:resData.url}))
                // console.log(this.fileList,'---handleSuccess')
                console.log(res,'handleSuccess')
              }
            }else{
              this.handleError({message:'上传失败'},file,fileList)
            }
          },
          // 失败
          handleError(error,file,fileList){
            const index=this.fileList.findIndex(n=>n.uid==file.uid)
            if(index!=-1){
              this.fileList.splice(index,1)
              this.$message.error(`${file.name}上传失败`)
            }
            console.log(error,'handleError')
          },
          copyUp(files){
            if(files && files.length>0){
                if(!this.multiple){
                    const file=files[0]
                    if(this.judegFileSize(file)){
                        this.fileList=[file]
                        this.handleFileUpload(this.postUpObject(file))
                    }
                }else{
                    for(let x=0;x<files.length;x++){
                    const file=files[x]
                    if(this.fileList.length<this.limit || !this.limit){
                        if(this.judegFileSize(file)){
                            this.fileList.push(file)
                            this.handleFileUpload(this.postUpObject(file))
                        }
                    }else{
                        this.handleExceed(files,fileList)
                        break;
                    }
                    }
                }
              }
          },
          handlePaste(value){
            if(value.clipboardData){
              const fileList=[...this.fileList]
              let files = value.clipboardData.files
              if(!files){
                files=Array.from(value.clipboardData.items).map(n=>n.getAsFile()).filter(n=>n)
              }
              this.copyUp(files)
            }
    
          },
        },
      };
    </script>
    
    <style  scoped>
    ::v-deep .el-upload-list__item:first-child{
      margin-left: 0 !important;
    }
    </style>
    
    
  • 2.使用:

    • 1.引入copy-upload组件,并关联对应的v-model
    • 2.监听组件抛出的方法inpuDrag->拖拽相关方法,inpuPaste->复制相关方法
    • 3.对应的input定义ref,然后监听的方法使用,并传入对应的Dom节点, @inpuDrag="$event(input的Dom节点)",@inpuPaste="$event(input的Dom节点)"
    
    <div style='width:600px'>
          <el-input v-model='txt' ref="copyUploadRef" style='margin-bottom:10px' type="textarea" :rows="5"></el-input>
          <copy-upload v-model="fileList" :size="10 * 1024 * 1024" acceptTitle="pdf或word或Excel或常见图片格式" :multiple="true" :headers='{}'  @inpuDrag="$event($refs.copyUploadRef.$el)"  @inpuPaste="$event($refs.copyUploadRef.$el)" sendUrl="/api/posts/" :data="{}"></copy-upload>
    </div>
    
    

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

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

相关文章

win10 + vs2017 + cmake3.17编译tiff-4.0.9

前言&#xff1a; 需要先编译依赖库&#xff1a;zlib-1.2.11, jpeg-9b 我的安装根目录是&#xff1a;D:\Depend_3rd_party\tiffx64 1. 下载tiff-4.0.9.zip&#xff0c;并解压到根目录下 得到&#xff1a;D:\Depend_3rd_party\tiffx64\tiff-4.0.9 2. 创建build文件夹&#xff…

链栈的练习

链栈练习 相关内容&#xff1a;栈的链式存储结构&#xff08;链栈&#xff09; //链栈的初始化、判空、入栈、出栈、读取栈顶元素 //链栈的结点&#xff1a;数据域、指针域 #include<stdio.h> #include<stdlib.h> typedef int Status; #define OK 1 #define ERRO…

二维码智慧门牌管理系统升级:实现一标六实数据管理

文章目录 前言一、一标六实数据管理应用的关键特点二、一标六实数据管理应用的具体应用 前言 随着城市的发展&#xff0c;对基础数据的精确管理和快速查询需求日益增强。为满足这一需求&#xff0c;二维码智慧门牌管理系统进行了升级&#xff0c;提供一标六实数据管理应用&…

全自动洗衣机什么牌子好?内衣洗衣机品牌排行榜前四名

随着内衣洗衣机的流行&#xff0c;很多小伙伴在纠结该不该入手一款内衣洗衣机&#xff0c;专门来洗一些贴身衣物&#xff0c;答案是非常有必要的&#xff0c;因为我们现在市面上的大型洗衣机只能做清洁&#xff0c;无法对我们的贴身衣物进行一个高强度的清洁&#xff0c;而小小…

[自定义 Vue 组件] 小尾巴顶部导航栏(2.0) TailTopNav

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/oglrqteg8fzvvzn0 [自定义 Vue 组件] 响应式顶部导航栏(1.0) TopNav&#xff1a;https://www.yuque.com/u27599042/coding_star/hzltsltxgavwx8u2 组件效果示例 组件所依赖的子组件 [自定义 Vue 组件] 小尾巴…

node插件express(路由)的基本使用(一)

文章目录 一、express的了解1.定义2.作用3.使用express的前提条件&#xff08;1&#xff09;如果是新文件夹需要薪资package.json文件&#xff0c;如果有就忽略&#xff08;2&#xff09;安装第三方依赖包&#xff08;3&#xff09;在使用的地方导入express 二、express的基本使…

原地封神!一个只用套模板即可制作电子相册的网站

对于忙碌的年轻人来说&#xff0c;一键操作的模板意味着无需复杂的操作步骤&#xff0c;就能轻松制作出精美的电子相册。 但是一个好的工具也是事关重要&#xff0c;最近发现了一款非常适合年轻人的模板---FLBOOK在线制作电子杂志平台&#xff0c;只需要找到合适的模板即可制作…

【leetcode】26. 删除有序数组中的重复项(图解)

目录 1. 思路&#xff08;图解&#xff09;2. 代码 题目链接&#xff1a; leetcode 26. 删除有序数组中的重复项 题目描述&#xff1a; 注意返回的是去重后的数组长度&#xff0c;但是输出的是去重后的数组元素。 1. 思路&#xff08;图解&#xff09; 思路&#xff1a;快慢…

【数据结构】深入浅出理解快速排序背后的原理 以及 版本优化【万字详解】(C语言实现)

快速排序 快速排序递归实现前言一、Hoare版本&#xff08;一&#xff09;算法运行图例&#xff08;二&#xff09;算法核心思路&#xff08;三&#xff09;算法实现步骤&#xff08;1&#xff09;单趟&#xff08;2&#xff09;多趟 &#xff08;四&#xff09;码源详解 递归实…

Servlet对象生命周期

Servlet 生命周期包括加载与实例化、初始化、服务请求、销毁等阶段。 ervlet 的生命周期包括以下阶段&#xff1a; 加载与实例化&#xff1a;当容器启动或者第一次请求到达时&#xff0c;Servlet 容器加载 Servlet 类并创建 Servlet 实例。 初始化&#xff1a;在 Servlet 实例…

线性回归与线性拟合的原理、推导与算法实现

关于回归和拟合&#xff0c;从它们的求解过程以及结果来看&#xff0c;两者似乎没有太大差别&#xff0c;事实也的确如此。从本质上说&#xff0c;回归属于数理统计问题&#xff0c;研究解释变量与响应变量之间的关系以及相关性等问题。而拟合是把平面的一系列点&#xff0c;用…

UUNet训练自己写的网络

记录贴写的很乱仅供参考。 自己写的Unet网络不带深度监督&#xff0c;但是NNUNet默认的训练方法是深度监督训练的&#xff0c;对应的模型也是带有深度监督的。但是NNUNetV2也贴心的提供了非深度监督的训练方法在该目录下&#xff1a; 也或者说我们想要自己去定义一个nnUNWtTra…

pyusb环境搭建和无法发包问题

pyusb环境搭建和无法发包问题 项目需要对usb设备进行开发调试&#xff0c;选择搭建pyusb环境进行调试测试&#xff0c;这里记录下完整流程和中间解决的一些问题。 我使用的环境是window10 64bit, vscode 1.84.0 , Python 3.11.6 1 安装流程 参考github上的 https://github.…

实用篇-MQ消息队列

一、初识MQ 通讯分为同步通讯和异步通讯&#xff0c;同步通讯就比如我们日常生活中的打电话&#xff0c;看直播&#xff0c;能够得到及时的反馈。而异步通讯则类似于聊天软件聊天&#xff0c;不需要建立实时的连接&#xff0c;并且可以进行建立多个业务一起异步执行 1. 同步通…

关于SNAP的Biophysical Processor模块的计算准确率以及大厂10月种植情况

关于SNAP的Biophysical Processor模块的计算准确率 在处理河北省2022年的10月6日影像&#xff0c;使用SNAP的Biophysical Processor计算LAI时 发现很多农田地块出现了缺失值&#xff0c;但其实就是0值 SNAP的这个模块基于PROSAIL物理模型反演。不得不说&#xff0c;还是挺准…

AI:56-基于深度学习的微表情识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

聚观早报 |盒马参战双11;真我GT5 Pro将压轴登场

【聚观365】11月4日消息 盒马参战双11 真我GT5 Pro将压轴登场 奇瑞汽车10月销量创新高 iQOO 12系列将首发电竞芯片Q1 苹果CEO库克称正改善供需平衡 盒马参战双11 不少消费者反映&#xff0c;今年盒马的双11已悄然开始&#xff1a;10月20日起&#xff0c;盒马APP很多商品页…

COE文件之读写操作

在Xilinx的FIR、Block Memory等 IP核的配置中&#xff0c;需要使用COE&#xff08;Coefficient&#xff09;文件来进行初始化。 写COE文件 一般是通过Matlab设计好参数后&#xff0c;再生成COE文件。具体代码如下。 x 1:512; fid fopen(test.coe,w); fprintf(fid, memory_…

MachineLearning 14. 机器学习之集成分类器(AdaBoost)

这期介绍一下NB的最佳集成分类方法之一 AdaBoost&#xff0c;并实现在具体数据集上的应用&#xff0c;尤其是临床数据。 简 介 Adaboost是Adaptive Boosting的缩写&#xff0c;使用一组简单的弱分类器&#xff0c;通过强调被弱分类器错误分类的样本来实现改进的分类器。AdaBoo…

Java金字塔、空心金字塔、空心菱形

Java金字塔 public class TestDemo01 {public static void main(String[] args){//第一个for用于每行输出 从i1开始到i<5,总共5行for(int i1;i<5;i){//每行前缀空格&#xff0c;这个for用于表示每行输出*前面的空格//从上面规律可得,每行输出的空格数为总层数&#xff0c…