日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Vue + Node.js + MongoDB圖片上傳組件實現圖片預覽和刪除功能詳解

瀏覽:173日期:2023-01-23 15:54:04

本文實例講述了Vue + Node.js + MongoDB圖片上傳組件實現圖片預覽和刪除功能。分享給大家供大家參考,具體如下:

公司要寫一些為自身業務量身定制的的組件,要基于Vue,寫完后擴展了一下功能,選擇寫圖片上傳是因為自己之前一直對這個功能比較迷糊,所以這次好好了解了一下。演示在網址打開后的show.gif中。

使用技術:Vue.js | node.js | express | MongoDB。

github網址:https://github.com/neroneroffy/private-project/tree/master/vue_uploader

Vue + Node.js + MongoDB圖片上傳組件實現圖片預覽和刪除功能詳解

功能 單圖多圖上傳 圖片上傳預覽 上傳進度條 分組上傳,分組查詢 新建分組,刪除分組 刪除圖片 選擇圖片目錄結構

Vue + Node.js + MongoDB圖片上傳組件實現圖片預覽和刪除功能詳解

前端利用Vue搭建,Entry.vue中引入子組件Upload.vue。在Upload.vue中,使用input標簽,上傳圖片,form表單提交數據,但是from讓人很頭疼,提交后刷新頁面,所以給它綁定了一個隱藏的iframe標簽來實現無刷新提交表單。

Dom中:

<form enctype='multipart/form-data' ref='formSubmit' > <label class='upload-content-right-top-btn'>上傳圖片</label> <input type='file' @change='uploadImage($event)' multiple='multiple' accept='image/gif, image/jpeg, image/png'></form><iframe name='rfFrame' src='about:blank' style='display:none;'></iframe>

調用上傳函數提交完數據后:

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<nameArray.length - 1;i++){ name = name + nameArray[i]; } let date = new Date(); let time = ’_’ + date.getFullYear() + '_' + date.getMonth() + '_' + date.getDay() + '_' + date.getHours() + '_' + date.getMinutes() +'_'+ date.getSeconds()+'_'+date.getMilliseconds(); let picName = name + time + ’.’ + type; let newPath = form.uploadDir + '/' + picName; let oldPath = form.uploadDir + '/'+ file.path.substring(file.path.indexOf(route)); fs.renameSync(oldPath, newPath); //重命名 fileData = { id:`${new Date().getTime()}`, url:serverIp + newPath.substring(newPath.indexOf(fileDir)), name:file.name, size:file.size, isSelected:false, newName:picName, }; UploadData.findOne({group:group},(err,doc)=>{ 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) }});

數據庫結構:

Vue + Node.js + MongoDB圖片上傳組件實現圖片預覽和刪除功能詳解

剩下的還有文件刪除,新增分組,刪除分組,分組查詢的功能,由于篇幅有限,這些功能可以去看源碼

第一次用node和mongoDB寫后臺業務,還有很多地方需要完善,代碼會繼續更新~

希望本文所述對大家vue.js程序設計有所幫助。

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99久久九九| 国产精品一级在线观看| 国产欧美另类| 久久精品天堂| 涩涩av在线| 国户精品久久久久久久久久久不卡| 久久久久久久久丰满| 在线午夜精品| 国产午夜精品一区在线观看| 精品视频黄色| 中文字幕色婷婷在线视频| 91成人网在线观看| 日本午夜精品| 婷婷综合六月| 蜜桃久久久久久| 欧美激情日韩| 亚洲一区二区免费看| 久久超碰99| 亚洲激情欧美| 卡一卡二国产精品| 国产精品毛片| 麻豆成全视频免费观看在线看| 亚洲一区二区成人| 国产成人精品一区二区免费看京| 国产精品视区| 国产激情久久| 亚洲一区二区三区无吗| 黑森林国产精品av| 欧美天堂一区| 三级在线观看一区二区| 久久只有精品| 亚洲人成亚洲精品| 神马午夜久久| 久久亚洲资源中文字| 蜜桃久久久久久| 亚洲最新无码中文字幕久久 | 在线一区欧美| 性欧美videohd高精| 日韩和欧美一区二区三区| 久久久9色精品国产一区二区三区| 欧美激情精品| 日韩不卡一区二区| 国产视频一区三区| 999精品一区| 久久久久.com| 久久精品影视| 成人午夜精品| 成人看片网站| 日韩中文在线电影| 都市激情国产精品| 国产91欧美| av免费不卡国产观看| 91一区二区三区四区| 日韩国产在线观看| 国产精品三上| 久久久国产精品网站| 蜜桃视频在线观看一区| 蜜桃tv一区二区三区| 精品国产麻豆| 久久一区二区三区喷水| 99国产精品一区二区| 久久久久国产精品一区三寸| 日本不卡免费高清视频在线| 亚洲精品88| 欧美成人久久| 亚洲人亚洲人色久| 亚洲精品乱码日韩| 国产精品一级| 久久精品国产福利| 亚洲91精品| 免费人成精品欧美精品| 日韩精品一区二区三区中文| 国产一级成人av| 欧美日韩视频网站| 夜夜嗨一区二区| 欧美欧美黄在线二区| 天堂av在线| 蜜桃久久久久久| 欧美成a人片免费观看久久五月天| 国产白浆在线免费观看| 国产字幕视频一区二区| 丝袜美腿亚洲一区| 国产一区二区三区日韩精品| 天堂а√在线最新版中文在线| 亚洲欧美日韩国产一区| 久久av综合| 午夜在线观看免费一区| 你懂的亚洲视频| 在线视频日韩| 波多野结衣久久精品| 亚洲精品大全| 日本不良网站在线观看| 日韩精品三区四区| 99精品美女| 国产精品s色| 国产手机视频一区二区| 国产成人1区| 日本成人中文字幕在线视频| 国产一区2区| 日本欧美韩国一区三区| 国产精品日韩| 天堂资源在线亚洲| 精品99久久| 国产色99精品9i| 综合一区在线| 亚洲在线网站| 亚洲调教视频在线观看| 国产91欧美| 久久亚洲资源中文字| 亚洲一区欧美| 夜夜嗨av一区二区三区网站四季av| 老色鬼精品视频在线观看播放| 中文字幕亚洲影视| 日韩精品免费一区二区在线观看| 精品一区二区三区的国产在线观看| 免费在线观看日韩欧美| 国产婷婷精品| 日韩精品一级二级 | 青青草伊人久久| 天海翼精品一区二区三区| 人人爽香蕉精品| 亚洲乱码一区| 久久亚洲国产精品一区二区| 国产亚洲在线观看| 视频一区二区中文字幕| 亚洲丝袜美腿一区| 免费精品视频最新在线| 欧美精品自拍| 亚洲日本免费电影| 国产日韩欧美中文在线| 国产精品最新自拍| 国产极品久久久久久久久波多结野| 精品国内亚洲2022精品成人| 91嫩草亚洲精品| 久久精品在线| 亚洲欧洲美洲国产香蕉| 综合色就爱涩涩涩综合婷婷| 久久狠狠亚洲综合| 国产精品毛片久久| 日韩电影二区| 免费在线视频一区| 国产精品成人自拍| 精品国产一区二区三区性色av| 欧美片第1页| 亚洲日产国产精品| 国语精品一区| 天堂va在线高清一区| 国产精品观看| 在线 亚洲欧美在线综合一区| 国产乱码精品一区二区三区四区 | 国产欧美日韩亚洲一区二区三区| 精品视频一区二区三区在线观看| av在线资源| 中文字幕一区二区精品区| 久久不见久久见中文字幕免费| 久久精品99久久无色码中文字幕| 蜜桃免费网站一区二区三区| 中国字幕a在线看韩国电影| 亚洲香蕉视频| 秋霞影视一区二区三区| 国产亚洲久久| 国产视频一区在线观看一区免费| 美女久久99| 亚洲精选久久| 久久久夜精品| 久久久免费人体| 亚洲精品影院在线观看| 亚洲二区精品| 捆绑调教日本一区二区三区| 亚洲精品成人一区| 精品国产成人| 国产日产一区| 日韩一区二区三区精品| 午夜在线播放视频欧美| 波多野结衣一区| 亚洲精品.com| 色一区二区三区| 毛片在线网站| 蜜臀久久精品| 久久女人天堂| 六月丁香综合在线视频| 国产精品美女在线观看直播| 日韩在线成人| 亚洲精品极品| 亚洲欧美日韩国产一区二区| 影视先锋久久| 好吊视频一区二区三区四区| 久久麻豆精品| 欧美特黄一区| 麻豆成人在线| 亚洲精品乱码日韩| 91精品国产一区二区在线观看| 日韩亚洲精品在线观看| 欧美日韩 国产精品| 国产精品毛片久久久| 免费在线播放第一区高清av| 久久亚洲人体| 日本精品不卡| 999在线观看精品免费不卡网站| 久久香蕉精品|