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

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

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

瀏覽:170日期: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性xxx老妇胖精品| 国产精品久久亚洲不卡| 国产精品麻豆成人av电影艾秋| 国产日本亚洲| 久久久精品国产**网站| 国内一区二区三区| 成人av三级| 日韩在线短视频| 日韩精品网站| 日韩视频在线一区二区三区 | a国产在线视频| 91看片一区| 亚洲一区中文| 亚洲精品乱码久久久久久蜜桃麻豆| 蜜臀久久久99精品久久久久久| 中文一区一区三区免费在线观 | 欧美日韩精品一区二区视频| 久久精品影视| 亚洲一区二区三区免费在线观看 | 日本aⅴ精品一区二区三区 | 爽好多水快深点欧美视频| 婷婷综合成人| 狂野欧美性猛交xxxx| 香蕉久久精品| 亚洲婷婷丁香| 日韩精品高清不卡| 国产精一区二区| 中文在线а√在线8| 日韩一级精品| 国产毛片精品| 日韩在线短视频| 亚洲三级av| 国内不卡的一区二区三区中文字幕| 视频二区不卡| 亚洲网址在线观看| 国产在视频一区二区三区吞精| 欧美粗暴jizz性欧美20| 亚洲精品国产精品粉嫩| 精品一区视频| 亚洲在线电影| 国产日韩在线观看视频| 精品伊人久久久| 亚洲欧美久久久| 日韩av在线播放中文字幕| 国产资源在线观看入口av| 亚洲精品网址| 国产精品日本一区二区三区在线 | 精品免费av| 亚洲欧美综合| 国产日本亚洲| 日韩在线短视频| 亚洲免费专区| 免费看av不卡| 无码日韩精品一区二区免费| 欧美黄色网页| 久久国产精品色av免费看| 久久精品国产68国产精品亚洲| 日韩美女精品| 久久中文亚洲字幕| 国产精品久av福利在线观看| 九一精品国产| 久久精品人人| 色婷婷成人网| 好吊日精品视频| 精品国产中文字幕第一页| 在线一区免费观看| 精品国产精品久久一区免费式| 免费精品视频| 日韩大片在线观看| 婷婷精品在线观看| 亚洲欧美网站在线观看| 欧美精品97| 国产精品老牛| 成人国产精品一区二区网站| 久久国产欧美| 国产精品一区二区av日韩在线| 日韩不卡在线| 欧美亚洲tv| 免费精品视频| 99热国内精品| 国产乱子精品一区二区在线观看| 欧美日韩国产高清| 国产h片在线观看| 国产欧美日韩在线观看视频| 爽好多水快深点欧美视频| 亚洲精品一区三区三区在线观看| 国产伦理久久久久久妇女| 亚洲最新av| 蜜臀91精品国产高清在线观看 | 欧美精品黄色| 亚洲最新无码中文字幕久久| 国产美女精品视频免费播放软件| 综合精品一区| 伊人久久成人| 日韩精品诱惑一区?区三区| 国产精品一区二区av交换| 免费黄网站欧美| 亚洲精品九九| 日韩中文字幕一区二区三区| 美女在线视频一区| 日韩精品欧美大片| 欧美日韩日本国产亚洲在线| 国产传媒在线观看| 国产极品模特精品一二| 日本伊人久久| 中国女人久久久| 99久久久久国产精品| a日韩av网址| 精品三级av在线导航| 亚洲va久久久噜噜噜久久| 日韩在线一区二区| 亚洲欧美成人综合| 日韩午夜av在线| 亚洲欧美日韩国产一区二区| 好看的亚洲午夜视频在线| 91久久久精品国产| 欧美一区二区三区高清视频| 日韩欧美一区二区三区在线观看| 福利在线一区| 国产一区二区精品福利地址| 国产精品久久亚洲不卡| 国产女人18毛片水真多18精品| 青青草91视频| 国产欧美另类| 国产午夜精品一区在线观看| 人人爱人人干婷婷丁香亚洲| 中文字幕日韩欧美精品高清在线| 久久成人国产| 午夜精品网站| 蜜桃av一区二区在线观看| 亚洲欧美日韩国产综合精品二区 | 亚洲www免费| 日本综合字幕| 欧美日韩水蜜桃| 在线视频免费在线观看一区二区| 中文亚洲欧美| 日韩在线卡一卡二| 亚洲乱码一区| 欧美久久香蕉| 精品国产不卡一区二区| 天堂中文av在线资源库| 久久精品国产68国产精品亚洲| 午夜欧美精品| 亚洲tv在线| 欧美黑人做爰爽爽爽| 国产精品99一区二区三区| 久久久精品网| 久久午夜精品一区二区| 91精品国产自产观看在线| 免费日韩一区二区三区| 桃色av一区二区| 国产精品日韩| 亚洲人妖在线| 精品黄色一级片| 亚洲调教视频在线观看| 日本欧美在线看| 国产日韩欧美在线播放不卡| 国产在线不卡一区二区三区| 99精品国产一区二区三区| 在线一区视频| 国产亚洲欧美日韩精品一区二区三区 | 精品中文字幕一区二区三区四区| 成人福利av| 99香蕉国产精品偷在线观看| 日韩精品亚洲专区| 国产精品黑丝在线播放| 狠狠爱成人网| 国产女人18毛片水真多18精品| 国产成人久久精品一区二区三区| 午夜久久中文| 蜜臀av亚洲一区中文字幕| 国产美女视频一区二区| 久久国产欧美| 69堂精品视频在线播放| 日韩久久一区二区三区| 中文视频一区| 精品国产免费人成网站| 亚洲一区二区三区无吗| 国产成人精品福利| 六月丁香综合| 精品一区二区三区四区五区| 欧美在线影院| 欧美交a欧美精品喷水| 一区久久精品| 日本成人一区二区| 婷婷综合六月| 欧美日本一区| 日韩网站在线| 成人在线视频免费| 香蕉精品999视频一区二区| 国产麻豆精品| 国产韩日影视精品| 日韩国产欧美三级| 国产视频一区免费看| 免费不卡中文字幕在线| 久久中文字幕二区| 亚洲一区二区av|