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

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>
    
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络基础扫盲-初识网络

博客内容&#xff1a;初识网络 文章目录 一、OSI七层网络模型二、TCP/IP四层模型1、MAC地址与IP地址 前言 在以前网络不够发之前&#xff0c;各个实验室进行一些研究时需要进行数据的交流&#xff0c;但是那时车马很慢&#xff0c;一生只够跑几次&#xff0c;所以就有人研究了网…

Java医院HIS系统源码

Java医院HIS系统源码 项目描述 该项目是用springbootlayuishiro写的医院管理系统&#xff0c;该系统的业务比较复杂&#xff0c;数据库一共有36张表。项目的视频业务参考文档&#xff0c;都在百度云盘中。可以先看看视频和参考文档。 运行环境 jdk8mysqlIntelliJ IDEAmaven…

IntelliJ IDEA 2023 最新版如何试用?IntelliJ IDEA 2023最新版试用方法及验证ja-netfilter配置成功提示

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

SOEM源码解析——ec_init(初始化单网卡主站)

0 工具准备 1.SOEM-master-1.4.0源码1 ec_init总览 /** Initialise lib in single NIC mode:初始化库在单网卡模式* param[in] ifname Dev name, f.e. "eth0" 设备名* return >0 if OK* see ecx_init*/ int ec_init(const char * ifname) {return ecx_init(&…

要讨个公道,要分辨真假

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【redis面试题】数据持久化

文章目录 前言一、RDB 的概述RDB 的执行原理 二、AOF 的概述AOF 的特点 三、RDB 与 AOF 的区别 前言 跟着B站的黑马程序员学习面试题&#xff0c;目前是redis的第五个内容——数据持久化 课程传送门&#xff1a;redis——数据持久化 在 Redis 中&#xff0c;提供了两种数据持久…

windows mysql安装

1、首先去官网下载mysql安装包&#xff0c;官网地址&#xff1a;MySQL :: Download MySQL Community Server 2&#xff1a;把安装包放到你安装mysql的地方&#xff0c;然后进行解压缩&#xff0c;注意&#xff0c;解压后的mysql没有配置文件&#xff0c;我们需要创建配置文件 配…

C++17中std::any的使用

类sdk:any提供类型安全的容器来存储任何类型的单个值。通俗地说&#xff0c;std::any是一个容器&#xff0c;可以在其中存储任何值(或用户数据)&#xff0c;而无需担心类型安全。void*的功能有限&#xff0c;仅存储指针类型&#xff0c;被视为不安全模式。std::any可以被视为vo…

计算机组成与结构-计算机体系结构

计算机体系结构 指令系统 Flynn分类法 SISD&#xff08;单指令流单数据流&#xff09; 结构 控制部分&#xff1a;一个处理器&#xff1a;一个主存模块&#xff1a;一个 代表 单处理器系统 SIMD&#xff08;单指令流多数据流&#xff09; 结构 控制部分&#xff1a;一个处理…

【LeetCode刷题-链表】--876.链表的中间结点

876.链表的中间结点 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*…

linux笔记总结-基本命令

参考&#xff1a; 1.Linux 和Windows比 比较 &#xff08;了解&#xff09; 1. 记住一句经典的话&#xff1a;在 Linux 世界里&#xff0c;一切皆文件 2. Linux目录结构 /lib • 系统开机所需要最基本的动态连接共享库&#xff0c;其作用类似于Windows里的DLL文件。几 乎所有…

项目实战:通过axios加载水果库存系统的首页数据

1、创建静态页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"style/index.css"><script src"script/axios.mi…

手把手创建Android应用程序·案例程序分析

目录 1. Activity 组件 MainActivity 类 2.布局文件activity_main. xml 3.应用程序配置文件 AndroidManifest.xml 4. Android的应用程序组件 4.1 Activity——活动 4.2 Service——服务 4.3 Broadcast receiver——广播接收器 4.4 Content provider——内容提供者…

React 项目结构小结

React 项目结构小结 简单的记录一下目前 React 项目用的依赖和实现 摸索了大半年了大概构建一套用起来还算轻松的体系……&#xff1f;基本上应该是说可以应对大部分的项目了 使用的依赖 目前项目还在 refactoring 的阶段&#xff0c;所以乱得很&#xff0c;这里是新建一个…

【使用Python编写游戏辅助工具】第一篇:概述

引言 欢迎阅读本系列文章&#xff0c;本系列将带领读者朋友们使用Python来实现一个简单而有趣的游戏辅助工具。 写这个系列的缘由源自笔者玩了一款游戏。正巧&#xff0c;笔者对Python编程算是有一定的熟悉&#xff0c;且Python语言具备实现各种有趣功能的能力&#xff0c;因…

基于单片机的可穿戴个人健康监测仪-智能手环

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、方案的设计与论证2.1设计任务及要求2.2 模块技术和方法综述2.3 设计可能遇到的困难 二、 系统总体框架3.1 硬件设计 三 软件部分4.1 主程序流程框 四、 结论五、 文章目录 概要 近几年智能化的不断发展&#…

3000 台 Apache ActiveMQ 服务器易受 RCE 攻击

超过三千个暴露在互联网上的 Apache ActiveMQ 服务器容易受到最近披露的关键远程代码执行 (RCE) 漏洞的影响。 Apache ActiveMQ 是一个可扩展的开源消息代理&#xff0c;可促进客户端和服务器之间的通信&#xff0c;支持 Java 和各种跨语言客户端以及许多协议&#xff0c;包括…

HiveSQL中last_value函数的应用

一、背景 在以下数据中如何实现对每一个列按照更新时间取最新的非null值&#xff1f; 1 a a null 202301 202301 1 b b null null 202302 1 null c null null 202303 1 d null null null 202304如何实现…

Nginx的location优先级和重定向

Nginx的location有优先级级和匹配方式&#xff1a; 在http模块有server,在server模块才有location,location匹配的是uri /test /image 在一个server当中有多个location,如何来确定匹配哪个location。 Nginx的正则表达式&#xff1a; ^:字符串的起始位置 $:字符串的结束位…

Spring Boot 常见面试题

目录 1.Spring Boot 快速入门什么是 Spring Boot&#xff1f;有什么优点&#xff1f;Spring Boot 与 Spring MVC 有什么区别&#xff1f;Spring 与 Spring Boot 有什么关系&#xff1f;✨什么是 Spring Boot Starters?Spring Boot 支持哪些内嵌 Servlet 容器&#xff1f;如何设…