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 相关文章推荐
ASP.NET jQuery 实例1(在TextBox里面创建一个默认提示)
Jan 13 Javascript
php+js实现倒计时功能
Jun 02 Javascript
js调试工具Console命令详解
Oct 21 Javascript
jquery实现动态画圆
Dec 04 Javascript
javascript中substring()、substr()、slice()的区别
Aug 30 Javascript
AngularJS实现按钮提示与点击变色效果
Sep 07 Javascript
JS控制TreeView的结点选择
Nov 11 Javascript
jQuery删除当前节点元素
Dec 07 Javascript
如何用js判断dom是否有存在某class的值
Feb 13 Javascript
Vue-router 类似Vuex实现组件化开发的示例
Sep 15 Javascript
vue-cli构建项目使用 less的方法
Oct 04 Javascript
实例介绍JavaScript中多种组合继承
Jan 20 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简单装饰器模式实现与用法示例
2017/06/22 PHP
Laravel学习教程之request validation的编写
2017/10/25 PHP
PHP实现数组和对象的相互转换操作示例
2019/03/20 PHP
jquery的$(document).ready()和onload的加载顺序
2010/05/26 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
实用的JS正则表达式(手机号码/IP正则/邮编正则/电话等)
2013/01/11 Javascript
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
2013/01/16 Javascript
用客户端js实现带省略号的分页
2013/04/27 Javascript
node.js发送邮件email的方法详解
2017/01/06 Javascript
jQuery实现大图轮播
2017/02/13 Javascript
JS拉起或下载app的实现代码
2017/02/22 Javascript
jQuery插件FusionCharts绘制的2D双柱状图效果示例【附demo源码】
2017/05/13 jQuery
AngularJs实现聊天列表实时刷新功能
2017/06/15 Javascript
详谈构造函数加括号与不加括号的区别
2017/10/26 Javascript
javascript中new Array()和var arr=[]用法区别
2017/12/01 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
解决layer弹出层自适应页面大小的问题
2019/09/16 Javascript
js实现贪吃蛇游戏(简易版)
2020/09/29 Javascript
vue的$http的get请求要加上params操作
2020/11/12 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
[39:21]LGD vs OG 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.24
2019/09/10 DOTA
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
实例解析Python中的__new__特殊方法
2016/06/02 Python
详解python中递归函数
2019/04/16 Python
Python画图高斯分布的示例
2019/07/10 Python
用Python获取摄像头并实时控制人脸的实现示例
2019/07/11 Python
快速解决pymongo操作mongodb的时区问题
2020/12/05 Python
python 30行代码实现蚂蚁森林自动偷能量
2021/02/08 Python
html5如何在Canvas中实现自定义路径动画示例
2017/09/18 HTML / CSS
《孔繁森》教学反思
2014/04/17 职场文书
家庭困难证明
2014/10/12 职场文书
研究生毕业论文导师评语
2014/12/31 职场文书
青年文明号创建口号大全
2015/12/25 职场文书
2016先进集体事迹材料范文
2016/02/25 职场文书
Redisson实现Redis分布式锁的几种方式
2021/08/07 Redis
Unicode中的CJK(中日韩统一表意文字)字符小结
2021/12/06 HTML / CSS