vue+node实现图片上传及预览的示例方法


Posted in Javascript onNovember 22, 2018

本文介绍了vue+node实现图片上传及预览的示例方法,分享给大家,具体如下:

先上效果图

vue+node实现图片上传及预览的示例方法

上代码

html部分主要是借助了weui的样式

<template>
 <div>
  <myheader :title="'发布动态'">
   <i class="iconfont icon-fanhui1 left" slot="left" @click="goback"></i>
  </myheader>
  <div class="upload">
   <div v-if="userInfo._id">
    <!--图片上传-->
    <div class="weui-gallery" id="gallery">
     <span class="weui-gallery__img" id="galleryImg"></span>
     <div class="weui-gallery__opr">
      <a href="javascript:" rel="external nofollow" class="weui-gallery__del">
       <i class="weui-icon-delete weui-icon_gallery-delete"></i>
      </a>
     </div>
    </div>
    <div class="weui-cells weui-cells_form">
     <div class="weui-cell">
      <div class="weui-cell__bd">
       <textarea class="weui-textarea" v-model="content" placeholder="你想说啥" rows="3"></textarea>
      </div>
     </div>
     <div class="weui-cell">
      <div class="weui-cell__bd">
       <div class="weui-uploader">
        <div class="weui-uploader__bd">
         <ul class="weui-uploader__files" id="uploaderFiles">
          <li ref="files" class="weui-uploader__file" v-for="(image,index) in images" :key="index"
            :style="'backgroundImage:url(' + image +' )'"><span @click="deleteimg(index)" class="x">×</span></li>
         </ul>
         <div v-show="images.length < maxCount" class="weui-uploader__input-box">
          <input @change="change" id="uploaderInput" class="weui-uploader__input " type="file"
             multiple accept="image/*">
         </div>
        </div>
       </div>
      </div>
     </div>
    </div>
    <a class="weui-btn weui-btn_primary btn-put" style="margin: 20px " @click.prevent.once="put">发送</a>
   </div>
   <unlogin v-else> </unlogin>
  </div>
 </div>
</template>

重点部分在于

<ul class="weui-uploader__files" id="uploaderFiles">
 <li ref="files" class="weui-uploader__file" v-for="(image,index) in images" :key="index"
   :style="'backgroundImage:url(' + image +' )'"><span @click="deleteimg(index)" class="x">×</span></li>
</ul>
<div v-show="!this.$refs.files||this.$refs.files.length < maxCount" class="weui-uploader__input-box">
 <input @change="change" id="uploaderInput" class="weui-uploader__input" type="file"
     multiple accept="image/*">
</div>

通过@change="change"监听图片的上传,把图片转成base64后(后面会讲怎么转base64)将base64的地址加入到images数组,通过v-for="(image,index) in images"把要上传的图片在页面中显示出来,即达到了预览的效果

js部分

data部分

data() {
   return {
    content: '',//分享动态的文字内容
    maxSize: 10240000 / 2,//图片的最大大小
    maxCount: 8,//最大数量
    filesArr: [],//保存要上传图片的数组
    images: []//转成base64后的图片的数组
   }
  }

delete方法

deleteimg(index) {
    this.filesArr.splice(index, 1);
    this.images.splice(index, 1);
   }

change方法

change(e) {
    let files = e.target.files;
    // 如果没有选中文件,直接返回
    if (files.length === 0) {
     return;
    }
    if (this.images.length + files.length > this.maxCount) {
     Toast('最多只能上传' + this.maxCount + '张图片!');
     return;
    }
    let reader;
    let file;
    let images = this.images;
    for (let i = 0; i < files.length; i++) {
     file = files[i];
     this.filesArr.push(file);
     reader = new FileReader();
     if (file.size > self.maxSize) {
      Toast('图片太大,不允许上传!');
      continue;
     }
     reader.onload = (e) => {
      let img = new Image();
      img.onload = function () {
       let canvas = document.createElement('canvas');
       let ctx = canvas.getContext('2d');
       let w = img.width;
       let h = img.height;
       // 设置 canvas 的宽度和高度
       canvas.width = w;
       canvas.height = h;
       ctx.drawImage(img, 0, 0, w, h);
       let base64 = canvas.toDataURL('image/png');
       images.push(base64);
      };
      img.src = e.target.result;
     };
     reader.readAsDataURL(file);
    }
   }

put方法把filesArr中保存的图片通过axios发送到后端,注意要设置headers信息

put() {
    Indicator.open('发布中...');
    let self = this;
    let content = this.content;
    let param = new FormData();
    param.append('content', content);
    param.append('username', this.userInfo._id);
    this.filesArr.forEach((file) => {
     param.append('file2', file);
    });
    self.axios.post('/upload/uploadFile', param, {
     headers: {
      "Content-Type": "application/x-www-form-urlencoded"
     }
    }).then(function (result) {
     console.log(result.data);
     self.$router.push({path: '/home'});
     Indicator.close();
     Toast(result.data.msg)
    })
   }

后端通过multer模块保存传输的图片,再把保存下来的图片发送到阿里云oss(这个可以根据自己的使用情况变化)

let filePath;
let fileName;

let Storage = multer.diskStorage({
  destination: function (req, file, cb) {//计算图片存放地址
    cb(null, './public/img');
  },
  filename: function (req, file, cb) {//图片文件名
    fileName = Date.now() + '_' + parseInt(Math.random() * 1000000) + '.png';
    filePath = './public/img/' + fileName;
    cb(null, fileName)
  }
});
let upload = multer({storage: Storage}).any();//file2表示图片上传文件的key

router.post('/uploadFile', function (req, res, next) {
  upload(req, res, function (err) {
    let content = req.body.content || '';
    let username = req.body.username;
    let imgs = [];//要保存到数据库的图片地址数组
    if (err) {
      return res.end(err);
    }
    if (req.files.length === 0) {
      new Pyq({
        writer: username,
        content: content
      }).save().then((result) => {
        res.json({
          result: result,
          code: '0',
          msg: '上传成功'
        });
      })
    }
    /*client.delete('public/img/1.png', function (err) {
      console.log(err)
    });*/
    let i = 0;
    req.files.forEach((item, index) => {
      let filePath = `./public/img/${item.filename}`;
      put(item.filename,filePath,(result)=>{
        imgs.push(result.url);
        i++;
        if (i === req.files.length) {
        //forEach循环是同步的,但上传图片是异步的,所以用一个i去标记图片是否全部上传成功
        //这时才把数据保存到数据库
          new Pyq({
            content: content,
            writer: username,
            pimg: imgs
          }).save().then(() => {
            res.json({
              code: '0',
              msg: '发布成功'
            });
          })
        }
      })
    })
  })
});

github地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS删除数组元素的函数介绍
Mar 27 Javascript
javascript中不等于的代码是什么怎么写
Dec 29 Javascript
用JavaScript实现一个代码简洁、逻辑不复杂的多级树
May 23 Javascript
JS实现自适应高度表单文本框的方法
Feb 25 Javascript
浅述Javascript的外部对象
Dec 07 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
Dec 13 Javascript
浅谈React之状态(State)
Sep 19 Javascript
js 将线性数据转为树形的示例代码
May 28 Javascript
JS为什么说async/await是generator的语法糖详解
Jul 11 Javascript
ES6使用 Array.includes 处理多重条件用法实例分析
Mar 02 Javascript
Canvas三种动态画圆实现方法说明(小结)
Apr 16 Javascript
ES6 解构赋值的原理及运用
May 25 Javascript
微信上传视频文件提示(推荐)
Nov 22 #Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
Nov 22 #Javascript
详解三种方式解决vue中v-html元素中标签样式
Nov 22 #Javascript
详解Vue组件之作用域插槽
Nov 22 #Javascript
详解vue中localStorage的使用方法
Nov 22 #Javascript
微信小程序功能之全屏滚动效果的实现代码
Nov 22 #Javascript
layer弹出子iframe层父子页面传值的实现方法
Nov 22 #Javascript
You might like
详解:――如何将图片储存在数据库里
2006/12/05 PHP
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
PHP+Mysql+jQuery实现动态展示信息
2011/10/08 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
PHP使用数组实现矩阵数学运算的方法示例
2017/05/29 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
jQuery模拟点击A标记示例参考
2014/04/17 Javascript
jQuery实现带滚动线条导航效果的方法
2015/01/30 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
jQuery实现的fixedMenu下拉菜单效果代码
2015/08/24 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
微信支付 JS API支付接口详解
2016/07/11 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
2017/07/31 Javascript
解决使用vue.js路由后失效的问题
2018/03/17 Javascript
jQuery简单实现根据日期计算星期几的方法
2019/01/09 jQuery
vue的列表交错过渡实现代码示例
2019/05/05 Javascript
对layui中的onevent 和event的使用详解
2019/09/06 Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
2020/03/06 Javascript
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
mac 安装python网络请求包requests方法
2018/06/13 Python
Python迭代器与生成器用法实例分析
2018/07/09 Python
如何利用python制作时间戳转换工具详解
2018/09/12 Python
python用fsolve、leastsq对非线性方程组求解
2018/12/15 Python
解决python中导入win32com.client出错的问题
2019/07/26 Python
python 实现图像快速替换某种颜色
2020/06/04 Python
Nike瑞典官方网站:Nike.com (SE)
2018/11/26 全球购物
给客户的道歉信
2014/01/13 职场文书
企业元宵节主持词
2014/03/25 职场文书
软件研发工程师岗位职责
2014/09/30 职场文书
考试没考好检讨书(精选篇)
2014/11/16 职场文书
2014年仓库管理工作总结
2014/12/17 职场文书