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 相关文章推荐
jQuery使用append在html元素后同时添加多项内容的方法
Mar 26 Javascript
SWFObject基本用法实例分析
Jul 20 Javascript
纯JS实现本地图片预览的方法
Jul 31 Javascript
理解AngularJs指令
Dec 10 Javascript
JQuery中解决重复动画的方法
Oct 17 Javascript
vue2.0与bootstrap3实现列表分页效果
Nov 28 Javascript
解决Mac安装thrift因bison报错的问题
May 17 Javascript
详解小程序原生使用ES7 async/await语法
Aug 06 Javascript
JQuery获取元素尺寸、位置及页面滚动事件应用示例
May 14 jQuery
ES6 Object方法扩展的应用实例分析
Jun 25 Javascript
Vue路由守卫及页面登录权限控制的设置方法(两种)
Mar 31 Javascript
微信小程序实现滑动操作代码
Apr 23 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
php 随机排序广告的实现代码
2011/05/09 PHP
php 字符串替换的方法
2012/01/10 PHP
PHP 的异常处理、错误的抛出及回调函数等面向对象的错误处理方法
2012/12/07 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
PHP实现简单汉字验证码
2015/07/28 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
PHP实现找出链表中环的入口节点
2018/01/16 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
从Ajax到JQuery Ajax学习
2007/02/14 Javascript
JavaScript中去掉数组中的重复值的实现方法
2011/08/03 Javascript
面向对象的Javascript之二(接口实现介绍)
2012/01/27 Javascript
Jquery颜色选择器ColorPicker实现代码
2012/11/14 Javascript
js控制的遮罩层实例介绍
2013/05/29 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
easyui validatebox验证
2016/04/29 Javascript
EsLint入门学习教程
2017/02/17 Javascript
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
微信小程序自定义轮播图
2018/11/04 Javascript
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
2019/04/28 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
vue 实现cli3.0中使用proxy进行代理转发
2019/10/30 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
Python实现类继承实例
2014/07/04 Python
python发送邮件实例分享
2017/07/28 Python
python基于twisted框架编写简单聊天室
2018/01/02 Python
对numpy中shape的深入理解
2018/06/15 Python
python PIL和CV对 图片的读取,显示,裁剪,保存实现方法
2019/08/07 Python
浅析python内置模块collections
2019/11/15 Python
Django ModelForm组件原理及用法详解
2020/10/12 Python
Europcar葡萄牙:葡萄牙汽车和货车租赁
2017/10/13 全球购物
Booking.com西班牙:全球酒店预订
2018/03/30 全球购物
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
员工辞职信范文
2015/03/02 职场文书
2015年清明节演讲稿范文
2015/03/17 职场文书
2015年爱国卫生月活动总结
2015/03/26 职场文书
Python基础知识之变量的详解
2021/04/14 Python