vue+mongoose+node.js项目总结第一篇_图片文件上传
一、前言
项目演示:每个新用户登录之后会有个默认的头像,用户可以根据自己选择自己的头像图片进行更改。
二、主要内容
1、需求实现的思路分析。
第一步:用户点击按钮选择图片其实是间接触发input图片选择
第二步:input表单被监听change事件
第三步:选择图片,然后将图片用canvas画在预览框处
第四步:点击“确定按钮”,请求后端接口配合云存储,将图片上传到云存储上
第五步:利用云存储器中生成的图片url地址替换掉原来的地址
2、具体实现
2.1总体思路
2.2前台实现部分
(2)chooseImg(): 如上面所示这里用了一个小技巧点击下面的“选择图片”按钮,间接点击input输入框
//间接点击input框 chooseImg(){ var avater = this.$refs.avater //input框 avater.click() //input框点击 avater.click() //这里要设置两次才有用 },
(3)changeImg($event)这个函数监听到了input的图片发生了改变 , 注意:如果changeImg(e) 这样写获取不到事件e对象,改为changeImg($event)这样获取试试
//changeImg()函数将选中的图片绘制到页面中 changeImg(event){ console.log(111) var files = event.target.files if(files.length===0){//没有选中 return; } var imgPreview//新建一个缓冲区象允许Web应用程序异步读取存储在用户计算机上的文件。 var length = files.length for(let i=0; i<length; i++){ this.file = files[i] imgPreview = new FileReader() if(this.file.size > this.maxSize){//规定了一个图片大小的最大上限 Toast('图片太大,不允许上传') return; } } //加载选中的图片 imgPreview.onload=(event)=>{ let newimg = new Image() newimg.onload = ()=>{//图片预览 //创建画布 let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') let width = newimg.width let height = newimg.height //设置画布的大小 canvas.width = width; canvas.height = height ctx.drawImage(newimg, 0, 0, width, height) let newimgUrl = canvas.toDataURL('image/png')//方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。 this.avater = newimgUrl console.log(this.avater) } newimg.src = event.target.result; } imgPreview.readAsDataURL(this.file)//readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE },
(4)点击“确定”上传图片
//确定更新 upDateOk(){ if(!this.file){ Toast('请选择新的头像') return } // Indicator.open('头像更新中...') let self = this let param = new FormData()//FormData对象用以将数据编译成键值对 param.append('username',this.userInfo._id) param.append('avater',this.file) console.log(param) if(this.userInfo.avater!== 'http://localhost:4000/public/images/ava.jpg'){//如果用户的头像不是默认的那一张头像也需要将当前的这一张头像的地址传过去 param.append('oldVal', this.userInfo.avater) } let headers = { headers:{ "Content-Type": "application/x-www-form-urlencoded" } } //请求更新头像的方法 self.$axios.post('/api/upload/uploadAvater',param, headers).then(function(result){ self.$router.push({path: '/home'}); Indicator.close(); Toast(result.data.msg) }) } }
2.3后端node.js实现部分
(1)第一步:需要去云存储器上去申请账号和密码,创建存储桶,会生成需要用到的密匙(百度步骤很多)
(2)参考阿里云辅助文档:https://help.aliyun.com/document_detail/111265.html?spm=a2c4g.11186623.6.1239.45af2778FtkZdG
阿里云上借助的put方法实现上传功能,方法如下:
(3)multer标签实现的图片上传,所以需要安装multer
var fileName var filePath let Storage = multer.diskStorage({//diskStorage()方法指定文件存储的文件路径或者文件名 destination: function (req, file, callback) {//计算图片存放地址 callback(null, './public/images'); }, filename: function (req, file, callback) {//图片文件名 fileName = Date.now() + '_' + parseInt(Math.random() * 1000000) + '.png'; filePath = './public/images/' + fileName; callback(null, fileName) } }); let upload = multer({storage: Storage}).any()//接受一切上传的文件。文件数组将保存在 req.files。 let avater = multer({storage: Storage}).single('avater')//接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。
(4)前端请求对应的后端接口,实现图片上传
router.post('/uploadAvater', function (req, res, next) { avater(req, res, function (err) { let username = req.body.username;//获取到当前用户的id console.log(username) let imgs; let oldVal = req.body.oldVal || ''; if (oldVal) { oldVal = oldVal.replace('http://pfr020xzs.bkt.clouddn.com/', ''); client.delete(oldVal, function (err) { if (err) { console.log(err) } }) } if (err) { return res.end(err); } let i = 0; let imgItem = req.file; let filePath = `./public/images/${imgItem.filename}`; //调用上面的put方法实现图片上传 put(fileName,filePath,(result)=>{ imgs = result.url; console.log(imgs) User.update({ _id: username }, { avater: imgs }).then(() => { res.json({ code: '0', msg: '上传成功' }); }) }); }); });