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的数组的扩展实例代码
Jul 09 Javascript
Javascript 构造函数,公有,私有特权和静态成员定义方法
Nov 30 Javascript
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 Javascript
使用jQuery validate 验证注册表单实例演示
Mar 25 Javascript
JS回调函数的应用简单实例
Sep 17 Javascript
jQuery简单实现日历的方法
May 04 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
Dec 12 Javascript
jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
Jan 19 Javascript
基于百度地图api清除指定覆盖物(Overlay)的方法
Jan 26 Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
Aug 26 Javascript
解决layer.msg 不居中 ifram中的问题
Sep 05 Javascript
jquery实现直播弹幕效果
Nov 28 jQuery
微信上传视频文件提示(推荐)
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
通过ODBC连接的SQL SERVER实例
2006/10/09 PHP
PHP初学者最感迷茫的问题小结
2010/03/27 PHP
PHP延迟静态绑定使用方法实例解析
2020/09/05 PHP
Jquery中&quot;$(document).ready(function(){ })&quot;函数的使用详解
2013/12/30 Javascript
JavaScript截取字符串的2个函数介绍
2014/08/27 Javascript
Jquery实现弹性滑块滑动选择数值插件
2015/08/08 Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
2016/02/25 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
Vue路由切换时的左滑和右滑效果示例
2018/05/29 Javascript
深入学习JavaScript中的bom
2019/05/27 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
python基于multiprocessing的多进程创建方法
2015/06/04 Python
python查看微信好友是否删除自己
2016/12/19 Python
Python 3中的yield from语法详解
2017/01/18 Python
Python 数据结构之堆栈实例代码
2017/01/22 Python
Python常见异常分类与处理方法
2017/06/04 Python
详解Python之unittest单元测试代码
2018/01/24 Python
python opencv实现切变换 不裁减图片
2018/07/26 Python
Pycharm之快速定位到某行快捷键的方法
2019/01/20 Python
Python理解递归的方法总结
2019/01/28 Python
python binascii 进制转换实例
2019/06/12 Python
Python爬虫抓取技术的一些经验
2019/07/12 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
如何基于python实现画不同品种的樱花树
2020/01/03 Python
基于Pycharm加载多个项目过程图解
2020/01/19 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
django中ImageField的使用详解
2020/12/21 Python
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
仓库管理制度
2014/01/21 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书
企业年度评优方案
2014/06/02 职场文书
大跃进口号
2014/06/16 职场文书
五一口号
2014/06/19 职场文书
消防安全培训工作总结
2015/10/23 职场文书
python 遍历磁盘目录的三种方法
2021/04/02 Python