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获取焦点和失去焦点事件代码
Apr 21 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
使用ngView配合AngularJS应用实现动画效果的方法
Jun 19 Javascript
Knockout自定义绑定创建方法
Dec 26 Javascript
JavaScript中获取时间的函数集
Aug 16 Javascript
bootstrap实现图片自动轮播
Dec 21 Javascript
jQuery中DOM节点的删除方法总结(超全面)
Jan 22 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
Sep 01 jQuery
JS中获取 DOM 元素的绝对位置实例详解
Apr 23 Javascript
JavaScript遍历数组和对象的元素简单操作示例
Jul 09 Javascript
微信提示 在浏览器打开 效果实现过程解析
Sep 10 Javascript
vue同个按钮控制展开和折叠同个事件操作
Jul 29 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
德生PL550的电路分析
2021/03/02 无线电
thinkPHP自定义类实现方法详解
2016/11/30 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
ExtJS4 Grid改变单元格背景颜色及Column render学习
2013/02/06 Javascript
JS保存和删除cookie操作 判断cookie是否存在
2013/11/13 Javascript
Nginx上传文件全部缓存解决方案
2015/08/17 Javascript
JavaScript关于提高网站性能的几点建议(一)
2016/07/24 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
Three.js利用顶点绘制立方体的方法详解
2017/09/27 Javascript
监听element-ui table滚动事件的方法
2019/03/26 Javascript
原生JS实现音乐播放器的示例代码
2021/02/25 Javascript
python实现猜数字游戏(无重复数字)示例分享
2014/03/29 Python
Python操作SQLite简明教程
2014/07/10 Python
Python三级目录展示的实现方法
2016/09/28 Python
200行自定义python异步非阻塞Web框架
2017/03/15 Python
Python使用getpass库读取密码的示例
2017/10/10 Python
分析python切片原理和方法
2017/12/19 Python
python切片及sys.argv[]用法详解
2018/05/25 Python
python人民币小写转大写辅助工具
2018/06/20 Python
python实现本地图片转存并重命名的示例代码
2018/10/27 Python
使用k8s部署Django项目的方法步骤
2019/01/14 Python
Python动态语言与鸭子类型详解
2019/07/01 Python
Python + selenium + crontab实现每日定时自动打卡功能
2020/03/31 Python
使用Python FastAPI构建Web服务的实现
2020/06/08 Python
html5 input属性使用示例
2013/06/28 HTML / CSS
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
英国领先的豪华时尚家居网上商店:Amara
2019/08/12 全球购物
材料化学应届生求职信
2013/10/09 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
2014年团委工作总结
2014/11/13 职场文书
工程技术负责人岗位职责
2015/04/13 职场文书
68句权威创业名言
2019/08/26 职场文书
创业计划书之淘宝网店
2019/10/08 职场文书
python opencv通过4坐标剪裁图片
2021/06/05 Python
html+css实现滚动到元素位置显示加载动画效果
2021/08/02 HTML / CSS
Tomcat弱口令复现及利用
2022/05/06 Servers