一、前言
项目演示:用户可以向发布朋友圈一样发布动态,并且一张图片,四张图片,九张图片的排列方式不太相同
二、主要内容
1、分析
第一步:用户点击“+”号选择图片,input的change方法监听到图片的改变
第二步:将用户选择的图片用canvas画布画在预览区域
第三步:点击发送按钮,请求后端,将图片上传
2、前台实现
2.1图片发布部分
(1)
data(){ return{ contents:'', //发表的文字内容 maxSize: 10240000/2, //允许上传的最大图片大小 maxCount: 9,//允许的最大张数 images:[],//存放上传的图片数组 filesArr:[]//存放上传的文件 } },
(2)点击加号,选择要上传的图片
//点击加号选择图片 changeImg(e){ let files = e.target.files console.log(files) //如果没有选中 if(files.length===0){ return } //已经选中的图片数 + 当前的图片数 if(this.images.length + files.length >= this.maxCount){ Toast('最多只能传'+this.maxCount+'张图片') //并且将当前的加号隐藏 } //接下来将选中的图片加载到缓冲区 let reader; let file let images = this.images //存放当前加到页面上的图片数组 for(let i = 0, length=files.length; i< length; i++){ file = files[i]//遍历当前选中的图片 this.filesArr.push(file) //将当前选中的图片存到一个数组 reader = new FileReader()//对象允许Web应用程序异步读取存储在用户计算机上的文件 if(file.size > this.maxSize){ Toast('图片太大了,换一张试试') continue;//下面不执行了,进行下一个循环 } reader.onload = (e)=>{ let img = new Image() img.onload = function(){ let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') let width = img.width let height = img.height //设置canvas的宽度和高度 canvas.width = width canvas.height = height ctx.drawImage(img, 0, 0, width, height) let newImg = canvas.toDataURL('image/png') images.push(newImg) } console.log(e) img.src= e.target.result } reader.readAsDataURL(file) } },
(3)点击发送按钮,请求后端接口
recordMood(){ console.log(this.contents) if(!this.contents && this.filesArr.length===0){ Toast('内容不能为空!') return } Indicator.open('心情正在发布哦...') let self = this let content = this.contents console.log(content) let params = new FormData() params.append('content', content)//将请求的内容和当前用户的id传过去给后端 params.append('username',this.userInfo._id) // console.log(params) // console.log(params.getAll('content')); this.filesArr.forEach((file)=>{ params.append('file',file) }) for (var value of params.values()) { console.log(value);//查看formData中,发现都append进去了 } self.$axios.post('/api/upload/uploadFile', params, { headers: { /*'Content-Type': 'multipart/form-data'*/ "Content-Type": "application/x-www-form-urlencoded" } /*"Content-Type":"application/x-www-form-urlencoded"*/ }).then(function (result) { //console.log(result.data); self.$router.push('/found'); Indicator.close(); Toast(result.data.msg) }) } } }
3、后台实现部分
(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('/uploadFile',function(req, res, next){ upload(req, res, function(err){ console.log(111) let content = req.body.content || ''; let username = req.body.username //用户的_id console.log(content) //传来的图片 let imgs = [] if(err){ return res.send({code:1, data:err}) } console.log(req.files) if(req.files.length === 0){//用户没有上传图片 //就新建一个没有图片的PdMood对象 new PdMood({ writer: username, //发表用户的当前_id content: content }) .save() .then((result)=>{ res.json({ code: 0, result: result, msg:'上传成功' }) }) } //图片不为0,发送了含有图片的动态 let i = 0; req.files.forEach((imgItem, index) => { //图片上传到的路径 let filePath = './public/images/'+imgItem.filename //上传图片 put(imgItem.filename, filePath, (result)=>{ imgs.push(result.url) i++ if(i === req.files.length){ //新建一个含有图片的动态 new PdMood({ content: content, writer: username, //用户_id moodImg: imgs }).save().then(()=>{ res.json({ code:0, msg:'发布成功' }) }) } }) }) }) })