摘要:网址功能单图多图上传图片上传预览上传进度条分组上传,分组查询新建分组,删除分组删除图片选择图片目录结构前端利用搭建,中引入子组件。实现分组的新增查询删除。利用模块实现删除文件功能。
公司要写一些为自身业务量身定制的的组件,要基于Vue,写完后扩展了一下功能,选择写图片上传是因为自己之前一直对这个功能比较迷糊,所以这次好好了解了一下。演示在网址打开后的show.gif中。
使用技术:Vue.js | node.js | express | MongoDB。
github网址:https://github.com/neroneroff...
单图多图上传
图片上传预览
上传进度条
分组上传,分组查询
新建分组,删除分组
删除图片
选择图片
目录结构前端利用Vue搭建,Entry.vue中引入子组件Upload.vue。在Upload.vue中,使用input标签,上传图片,form表单提交数据,但是from让人很头疼,提交后刷新页面,所以给它绑定了一个隐藏的iframe标签来实现无刷新提交表单。
Dom中:
调用上传函数提交完数据后:
upload(); document.forms[0].target="rfFrame";
图片预览
利用html5的fileReader对象
let count = 0;//上传函数外定义变量,记录文件的数量,即递归的次数 /*-----------------------此段代码在上传函数中-------------------------------*/ let fileReader = new FileReader(); //解析图片路径,实现预览 fileReader.readAsDataURL(file.files[count]); fileReader.onload=()=>{ previewData = { url:fileReader.result,//图片预览的img标签的src name:file.files[count].name, size:file.files[count].size, }; //这段代码在上传函数中,所以在外面定义了一个_this = this,fileList为vue的data中定义的状态 _this.fileList.push(previewData); };
进度条实现
在axios的配置中定义onUploadProgress函数,接收参数:progressEvent,利用它的两个属性:progressEvent.total和progressEvent.loaded(上传的文件总字节数和已上传的字节数)
node写接口,实现图片的接收、查询、删除。实现分组的新增、查询、删除。利用Formidable模块接收并处理前端传过来的表单数据。利用fs模块实现删除文件功能。
let progress = 0; let config = { headers: {"Content-Type": "multipart/form-data"}, onUploadProgress (progressEvent){ if(progressEvent.lengthComputable){ progress = progressEvent.total/progressEvent.loaded; _this.$refs.progress[_this.$refs.progress.length-1].style.width = Number(progress).toFixed(2)*100+"%"; } } };
向formData中插入文件
formData = new FormData(); if(file.files[count]){ formData.append("file",file.files[count],file.files[count].name);
对于上传方式,我这里统一采用依次上传,无论是单图多图,单图上传一次就好,多图则递归调用上传函数,直到递归次数等于图片数量,停止递归。
上传函数
let file=$event.target, formData = new FormData(); //递归调用自身,实现多文件依次上传 let _this = this; let count = 0; let previewData = {}; uploadImage($event){ let file=$event.target, formData = new FormData(); //递归调用自身,实现多文件依次上传 let _this = this; let count = 0; let previewData = {}; function upload(){ //开始上传时,滚到底部 _this.$refs.picWrapper.scrollTop = _this.$refs.picWrapper.scrollHeight; //定义axios配置信息 let progress = 0; let config = { headers: {"Content-Type": "multipart/form-data"}, onUploadProgress (progressEvent){ console.log(`进度条的数量${_this.$refs.progress.length -1}`); if(progressEvent.lengthComputable){ progress = progressEvent.total/progressEvent.loaded; //进度条 _this.$refs.progress[_this.$refs.progress.length-1].style.width = Number(progress).toFixed(2)*100+"%"; } } }; //向formData中插入文件 if(file.files[count]){ formData.append("file",file.files[count],file.files[count].name); let fileReader = new FileReader(); //解析图片路径,实现预览 fileReader.readAsDataURL(file.files[count]); fileReader.onload=()=>{ previewData = { url:fileReader.result, name:file.files[count].name, size:file.files[count].size, }; _this.fileList.push(previewData); _this.progressShow = true }; fileReader.onloadend=()=>{ //检测图片大小是否超出限制 if(formData.get("file").size>_this.maxSize){ formData.delete("file"); //当图片全部上传完毕,停止递归 count++; if(count > file.files.length-1){ return } upload() }else{ //发送数据 axios.post(`/upload?mark=${_this.group}`,formData,config).then((response)=>{ formData.delete("file"); let res = response.data; console.log(res); if(res.result){ //如果是新建上传 if(_this.group === "new"){ _this.fileList.push(res.data); _this.fileList.forEach((item,index)=>{ if(!item.newName){ _this.fileList.splice(index,1) } }) }else{ //如果是选择其他组上传,直接把返回数据赋值到文件数组 _this.fileList = res.data; } _this.newUpload = false }else{ alert("上传失败"); return; } _this.noPic = false; count++; if(count > file.files.length-1){ return } upload() }).catch((err)=>{ alert("上传失败123"); }); } }; } } //第一次调用 upload(); document.forms[0].target="rfFrame";
}
node.js写后端//引入表单处理模块 let Formidable = require("formidable");
一系列定义....
form.encoding = "utf-8"; form.uploadDir = "/project/vue/vue_uploader/my-server/public/images";//定义文件存放地址 form.keepExtensions = true; form.multiples = false;//以单文件依次上传的方式,实现多文件上传 form.maxFieldsSize = 1*1024; //解析图片,重命名图片名称,返回给前端。 let fileData = ""; let fileDir = "images";//定义文件的存放路径 let route = "upload_";//定义路由 let serverIp = "http://localhost:3002/";//定义服务器IP
对文件数据进行处理,存入本地并存入数据库(由于涉及到分组上传。。。所以比较复杂)
解析文件函数:
function handleFile (file){ let filename = file.name; let nameArray = filename.split("."); let type = nameArray[nameArray.length-1]; let name = ""; for (let i = 0;i{ if(err){ res.json({ result:false, msg:err.message }) }else{ if(doc){ doc.picList.push(fileData); doc.save((err,saveResult)=>{ if(err){ return res.json({ result:false, }); }else{ let length= doc.picList.length; console.log(doc.picList.length) if(groupMark === "all"){ UploadData.find({},(err,queryResult)=>{ if(err){ res.json({ result:false, mgs:"发生错误了" }) }else{ let allPic = []; queryResult.forEach((item)=>{ if(item.group !=="default"){ allPic = allPic.concat(item.picList) } }); res.json({ result:true, data:allPic.concat(queryResult[1].picList) }) } }) }else if(groupMark === "new"){ UploadData.findOne({group:"default"},(err,queryResult)=>{ if(err){ return res.json({ result:false, msg:err.message }); }else{ return res.json({ result:true, data:queryResult.picList[queryResult.picList.length-1] }) } }); }else{ UploadData.findOne({group:group},(err,queryResult)=>{ if(err){ return res.json({ result:false, msg:err.message }); }else{ return res.json({ result:true, data:queryResult.picList }) } }); } } }) } } }) }
最后,调用解析文件函数
form.parse(req,(err,fields,files)=>{ //传多个文件 if(files.file instanceof Array){ return }else{ //传单个文件 handleFile(files.file) } });
数据库结构:
剩下的还有文件删除,新增分组,删除分组,分组查询的功能,由于篇幅有限,这些功能可以去看源码
第一次用node和mongoDB写后台业务,还有很多地方需要完善,代码会继续更新~
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/19150.html
摘要:利用中间件实现异步请求,实现两个用户角色实时通信。目前还未深入了解的一些概念。往后会写更多的前后台联通的项目。删除分组会连同组内的所有图片一起删除。算是对自己上次用写后台的一个强化,项目文章在这里。后来一直没动,前些日子才把后续的完善。 欢迎访问我的个人网站:http://www.neroht.com/ 刚学vue和react时,利用业余时间写的关于这两个框架的训练,都相对简单,有的...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...
阅读 1626·2021-09-02 09:55
阅读 1090·2019-08-30 13:19
阅读 1391·2019-08-26 13:51
阅读 1445·2019-08-26 13:49
阅读 2372·2019-08-26 12:13
阅读 450·2019-08-26 11:52
阅读 1897·2019-08-26 10:58
阅读 3083·2019-08-26 10:19