vue+mongoose+node.js项目总结第二篇_模拟动态发布功能

一、前言                                                                              

项目演示:用户可以向发布朋友圈一样发布动态,并且一张图片,四张图片,九张图片的排列方式不太相同

 

二、主要内容                                                                    

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:'发布成功'
                        })
                    })
                }
            })
        })
    })
})

 

posted @ 2019-09-03 14:35  mysunshine_SZZ  阅读(369)  评论(0编辑  收藏  举报