当前位置: 首页 > news >正文

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

1. 效果图:

在这里插入图片描述

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

  • 1.通过监听paste方法,获取复制内容
  • 2.获取复制内容中的clipboardData
  • 3.获取file文件进行上传
<input  @paste.native="handlePaste"  />handlePaste(value){let files = value.clipboardData.filesif(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 = 10MBsize:{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=truelet 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 }`);}},// 成功&&插入对应的urlhandleSuccess(res,file,fileList){if(res.code && res.code==200){const resData=res.dataconst 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.filesif(!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>

相关文章:

  • Java 设计模式——命令模式
  • Linux shell编程学习笔记21:用select in循环语句打造菜单
  • AtCoder Beginner Contest 327 题解 A-D
  • Unity3D移动开发如何依据性能选择Shader
  • 01-单节点部署clickhouse及简单使用
  • 校验 ChatGPT 4.0 真实性的三个经典问题:快速区分 GPT3.5 与 GPT4,并提供免费测试网站
  • 台球厅桌球室计时计算软件计费方法,台球厅的电脑怎么计时
  • 由于flutter_app依赖于flutter_swiper>=0.0.2,不支持零安全,版本解决失败。
  • 短视频矩阵营销系统工具如何助力商家企业获客?
  • vscode 阅读 android以及kernel 源码
  • Python 中的 Gzip 解压
  • windows内存取证-中等难度-下篇
  • RIP路由配置
  • Adobe After Effects 2024(Ae2024)在新版本中的升级有哪些?
  • 分布式多主关系数据库的底线业务优势
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • co.js - 让异步代码同步化
  • co模块的前端实现
  • FastReport在线报表设计器工作原理
  • October CMS - 快速入门 9 Images And Galleries
  • python大佬养成计划----difflib模块
  • Redis字符串类型内部编码剖析
  • vue脚手架vue-cli
  • Web标准制定过程
  • 多线程 start 和 run 方法到底有什么区别?
  • 分布式任务队列Celery
  • 后端_MYSQL
  • 力扣(LeetCode)22
  • 聊聊hikari连接池的leakDetectionThreshold
  • 码农张的Bug人生 - 初来乍到
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • ( 10 )MySQL中的外键
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (九)信息融合方式简介
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (十六)串口UART
  • (四)鸿鹄云架构一服务注册中心
  • (已解决)什么是vue导航守卫
  • (译) 函数式 JS #1:简介
  • (转)Mysql的优化设置
  • (转)甲方乙方——赵民谈找工作
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET中 MVC 工厂模式浅析
  • .NET中的Exception处理(C#)
  • .NET中使用Protobuffer 实现序列化和反序列化
  • //解决validator验证插件多个name相同只验证第一的问题
  • :=