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 相关文章推荐
dojo 之基础篇(三)之向服务器发送数据
Mar 24 Javascript
最近项目写了一些js,水平有待提高
Jan 31 Javascript
jQuery中:disabled选择器用法实例
Jan 04 Javascript
javascript比较两个日期相差天数的方法
Jul 24 Javascript
AngularJS基础 ng-open 指令简单实例
Aug 02 Javascript
CSS3 media queries结合jQuery实现响应式导航
Sep 30 Javascript
jQuery实现手机版页面翻页效果的简单实例
Oct 05 Javascript
Node.js中文件操作模块File System的详细介绍
Jan 05 Javascript
原生js仿淘宝网商品放大镜效果
Feb 28 Javascript
通过示例彻底搞懂js闭包
Aug 10 Javascript
JS简单获取并修改input文本框内容的方法示例
Apr 08 Javascript
详解vue 中 scoped 样式作用域的规则
Sep 14 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删除数组中的特定元素的代码
2012/06/28 PHP
php统计时间和内存使用情况示例分享
2014/03/13 PHP
php防止网站被刷新的方法汇总
2014/12/01 PHP
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
js 代码集(学习js的朋友可以看下)
2009/07/22 Javascript
javascript操作cookie的文章(设置,删除cookies)
2010/04/01 Javascript
Javascript类定义语法,私有成员、受保护成员、静态成员等介绍
2011/12/08 Javascript
非jQuery实现照片散落桌子上,单击放大的LightBox效果
2014/11/28 Javascript
举例讲解如何判断JavaScript中对象的类型
2016/04/22 Javascript
JS组件Bootstrap按钮组与下拉按钮详解
2016/05/10 Javascript
详解webpack2+node+react+babel实现热加载(hmr)
2017/08/24 Javascript
对vue.js中this.$emit的深入理解
2018/02/23 Javascript
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
关于微信小程序map组件z-index的层级问题分析
2019/07/09 Javascript
echarts实现折线图的拖拽效果
2019/12/19 Javascript
详解Java中String JSONObject JSONArray List转换
2020/11/13 Javascript
详解Python中with语句的用法
2015/04/15 Python
Python基于Socket实现的简单聊天程序示例
2017/08/05 Python
python3 pandas 读取MySQL数据和插入的实例
2018/04/20 Python
python使用插值法画出平滑曲线
2018/12/15 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
python 错误处理 assert详解
2020/04/20 Python
学习python需要有编程基础吗
2020/06/02 Python
解释一下Windows的消息机制
2014/01/30 面试题
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
艺人经纪人岗位职责
2014/04/15 职场文书
2014年六一儿童节演讲稿
2014/05/23 职场文书
暑期教师培训方案
2014/06/07 职场文书
党员群众路线剖析材料
2014/10/08 职场文书
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP
MySQL开启事务的方式
2021/06/26 MySQL
分析Java中Map的遍历性能问题
2021/06/26 Java/Android
Python连接Postgres/Mysql/Mongo数据库基本操作大全
2021/06/29 Python
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技