vue+element-ui中的图片获取与上传

摘要:
vue+element ui中的图像采集和上传与图像处理相关。图像格式为文件流,记录如下。HandleLoadError{consting=e.srcElement;this.imageUrl=this.errorLoadImg;//用未能加载的图像替换img.oneerror=null;//清除错误:如果加载过程中显示的图像在错误期间出错,它将继续循环,因此我们必须清除错误并限制操作一次}上载图像:使用元素uielupload自动上载,一次发送一张图像upload Pictures˂!“);}returnisImage&&isLt2M;},handleProgress{this.loading=true;//在上载}手动上载时执行加载事件。一次提交多个el上载图像。要求:每个图片区域只能提交一个图像,然后单击“确定”一起提交。{handleChange}”:onremove=“=˃{handleRemove}”“:自动上载=”false“:文件列表=”fileList[0]“ref=“file1”˃选择图片{handleChange}”:on-remove=“=˃{handleRemove}”;auto upload=“false”:fileList=“fileList[1]”ref=“file 2”˃选择图片{handeChange ge}“:on remove=”手柄移除}“:auto upload=”false“:file list=”fileList[2]“ref=”file3“˃选择图片确认˂!
vue+element-ui中的图片获取与上传

工作上接触了一下图片的处理,图片的格式是文件流, 记录如下。

请求图片

请求图片的时候,带上{ responseType: 'blob' }, 否则图片显示的可能是乱码。

axios
  .post(url, parmas, { responseType: 'blob' })
  .then(res => {
    return Promise.resolve(res);
  })
  .catch(e => {
    return Promise.reject(e);
  });

显示图片

图片返回的是文件流的形式, 控制台中显示的是乱码。
直接显示二进制图片会出错,所以我们要进行处理。

<!-- template中 -->
<img alt="logo" :src="http://t.zoukankan.com/imageUrl" @error="handleLoadError" />
/*------ script中------*/
let urlCreator = window.URL || window.webkitURL;
let imageUrl = urlCreator.createObjectURL(res);
this.imageUrl = imageUrl;

显示图片中,要对万一图片显示不出来的情况进行处理。使用onerror事件可以对加载图片失败的情况进行处理。

handleLoadError(e) {
  const img = e.srcElement;
  this.imageUrl = this.errorLoadImg;  //  用加载失败的图片替代之
  img.onerror = null; //  清除错误:如果错误时加载时显示的图片出错,将会一直循环,所以我们必须清除掉错误,限制运行一次
}

上传图片:使用 element-ui 的 el-upload

自动上传,一次传一张图片

<el-upload
  action="uploadUrl"
  :show-file-list="false"
  :accept="'image/*'"
  :headers="{token:$cookieStorage.token}"
  :on-success="handleSuccess"
  :on-error="handleError"
  :before-upload="handleBeforeUpload"
  :on-progress="handleProgress"
>
  <el-button type="primary" size="medium">上传图片</el-button>
</el-upload>
<!--
  action: 图片上传的地址
  show-file-list: 是否显示文件上传列表
  accept: 可接受的上传类型,image/*为图片
  headers: 头部信息
  on-success: 上传成功事件
  on-error: 上传失败事件
  before-upload: 上传前处理事件,返回一个值,值为false将阻止上传
  on-progress: 上传中事件
  -->
/*----- 以下为常用处理代码 ------*/
handleSuccess(response, file, fileList) {
  this.$success("上传成功");
},
handleError() {
  this.$error("上传失败,请重新上传图片!");
},
handleBeforeUpload(file) {
  const isImage = file.type.includes("image");
  if (!isImage) {
    this.$message.error("上传文件类型必须是图片!");
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    this.$message.error("上传图片大小不能超过 2MB!");
  }
  return isImage && isLt2M;
},
handleProgress(event, file, fileList) {
  this.loading = true;  //  上传时执行loading事件
}

手动上传,一次提交多个 el-upload 的图片

要求:每个 picture area 限制选择一张图片,点击确定后一起提交。

<el-upload
  action="myUrl"
  :on-change="(file,fileList)=>{handleChange(file,fileList,1)}"
  :on-remove="(file,fileList)=>{handleRemove(file,fileList,1)}"
  :auto-upload="false"
  :file-list="fileList[0]"
  ref="file1"
>
  <el-button size="small">选择图片</el-button>
</el-upload>
<el-upload
  action="myUrl"
  :on-change="(file,fileList)=>{handleChange(file,fileList,2)}"
  :on-remove="(file,fileList)=>{handleRemove(file,fileList,2)}"
  :auto-upload="false"
  :file-list="fileList[1]"
  ref="file2"
>
  <el-button size="small">选择图片</el-button>
</el-upload>
<el-upload
  action="myUrl"
  :on-change="(file,fileList)=>{handleChange(file,fileList,3)}"
  :on-remove="(file,fileList)=>{handleRemove(file,fileList,3)}"
  :auto-upload="false"
  :file-list="fileList[2]"
  ref="file3"
>
  <el-button size="small">选择图片</el-button>
</el-upload>
<el-button @click="submitData">确认</el-button>
<!--
  action:提交的地址,此处随便写一个,不写会报错
  on-change: 图片上传到缓存中将被触发
  on-remove: 从缓存中删除文件将被触发
  -->
data(){
  fileList: [0,0,0], //缓存区文件
  uploadFile:[[],[],[]] //  上传用文件
},
handleChange(file, fileList, type) {
  //  限制单张上传,超过限制即覆盖
  if (fileList.length > 1) {
    fileList.splice(0, 1);
  }

  //  校验
  const isLt2M = file.size / 1024 / 1024 < 5;
  if (!isLt2M) {
    this.$message.error("上传图片大小不能超过 5MB!");
    this.removeUploadedFile(type);  //  不符合要求删除文件
    return false;
  }

  const isImage = file.raw.type.includes("image");
  if (!isImage) {
    this.$message.error("上传的格式必须是图片!");
    this.removeUploadedFile(type);
    return false;
  }
  //  验证通过之后,将缓存区文件存入上传区文件中
  this.formData.files[type] = file.raw;
},
//  从缓存区移除文件
removeUploadedFile(type) {
  if (type === 0) {
    this.$refs.file1.clearFiles();
  }
  if (type === 1) {
    this.$refs.file2.clearFiles();
  }
  if (type === 2) {
    this.$refs.file3.clearFiles();
  }
}
//  删除文件
handleRemove(file, fileList, type) {
  //  删除文件时要移除缓存区文件和上传区文件
  this.fileList[type] = 0;
  this.uploadFile[type] = [];
},
//  上传文件
submitData() {
  //  校验是否选择文件
  let fileNum = this.flatten(this.uploadFile).length;
  if (fileNum === 0) {
    this.$error("未选择任何文件!");
    return false;
  }

  //  使用formdata格式
  let formData = new FormData();
  if (this.formData.files[0]) {
    formData.append("file1", this.formData.files[0]);
  }
  if (this.formData.files[1]) {
    formData.append("file2", this.formData.files[1]);
  }
  if (this.formData.files[2]) {
    formData.append("file2", this.formData.files[2]);
  }

  //  请求:在headers上务必加上content-Type,指定表单形式发送
  axios
  .post("uploadUrl", formData, {headers: { "Content-Type": "multipart/form-data" }})
  .then(res => {
    this.$success("上传图片成功!");
    this.fileList = [0,0,0];
    this.uploadFile =[[],[],[]];
  })
  .catch(e => {
    console.log(e);
  });
}
//  扁平化数组
flatten(arr) {
  let res = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      res = res.concat(this.flatten(arr[i]));
    } else {
      res.push(arr[i]);
    }
  }
  return res;
}

multipartform-data相关知识

图片加载技术:预加载和懒加载

  • 预加载:重点在"预",在用户需要看到该图片之前,就已经加载和请求到该图片。
  • 懒加载: 重点在"懒",尽可能少的加载图片,只加载必需的图片(用户屏幕可视范围内),目的是尽可能的减少请求数,减缓服务器的压力。
    在vue中懒加载的组件有很多,比如vue-lazy-laodvue-clazy-load

浏览器阻塞

同一时间对服务器的请求过多,将会造成浏览器阻塞。
浏览器默认对同一域下的资源,只保持一定的连接数,阻塞过多的连接,以提高访问速度和解决阻塞问题。

对于请求图片来说,有以下解决方法

  1. 使用雪碧图:把所有图片合成一张大图。
  2. 延迟加载:只去请求可视区的图片。
    最后使用了延迟加载,对非可视区领域的图片延迟加载,优先加载可视区图片,减少图片的请求数。
<img :src="http://t.zoukankan.com/imageUrl" ref="img">
//  方式一:延迟加载非可视区域
delayTime() {
  let windowHeight = window.innerHeight;
  let imgTop = this.$refs.img.getBoundingClientRect().top;
  const isDelay = imgTop > windowHeight;
  if (isDelay) {
    return Math.random() * 2000 + 3000;
  } else {
    return Math.random() * 2000 + 500;
  }
}
//  方法二:按顺序依次延迟加载
delayTime() {
  if (this.params.index) {
    return Math.random() * 2000 + this.params.index * this.params.type * 500;
  } else {
    return 0;
  }
}
setTimeout(() => {
  //  图片请求代码
}, this.delayTime);

使用延时加载前的请求
使用延时加载前的请求

使用延时加载后的请求
使用延时记载后的请求

参考

[1] XMLHttpRequest Standard.The responseType attribute
[2] XMLHttpRequest.responseType | MDN
[3] 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型 « 张鑫旭-鑫空间-鑫生活
[4] FormData 对象的使用 | MDN
[5] 前端|加载的图片太多或者太大怎么办(上) - u012496505的博客 - CSDN博客
[6] Lazy Loading Images and Video  |  Web Fundamentals  |  Google Developers
[7] An Introduction to Progressive Image Rendering
[8] 原生 JS 实现最简单的图片懒加载 - WEB前端 - 伯乐在线

2019/1/14 9:15:33

免责声明:文章转载自《vue+element-ui中的图片获取与上传》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇segv &amp;amp; mini coredump 调研JQuery实现简单的服务器轮询效果下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

在EasyUI项目中使用FileBox控件实现文件上传处理

我在较早之前的随笔《基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用》Web框架介绍中介绍了基于Uploadify的文件上传操作,免费版本用的是Jquery+Flash实现文件的上传处理,HTML5收费版本的没有试过。随着Flash逐渐退出整个环境,很多浏览器都可能不再支持Flash的了,因此在更新原有EasyUI...

webp图片实践之路

最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中。传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显。估计在不久的将来,webp会成为标配。 本文主要分享一下我们在webp图片使用上的实践之路。   我们会从三部分来聊聊webp这个话题。 什么是webp,它有什么用? 使用webp的常规方法以及...

ajax实现文件上传,多文件上传,追加参数

1.html部分实现代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>文件上传</title> </head> <body> <form id= "uploadForm">...

jmeter上传文件同时带有参数

在jmeter中上传文件时同时带有参数。主要问题有两个: 第一是jmeter中「参数」模块的字段值是什么, 第二是jmeter中「文件上传」模块的字段值是什么,以及上传文件的MIME类型是什么。 》如下图,在浏览器中上传文件,network中查看上传接口,有请求地址、authorization(一般是登录接口返回的token,这里作为参数用来身份识别)、F...

vue-router详解

路由(vue-router) 现在的应用都流行SPA应用(single page application) 传统的项目大多使用多页面结构,需要切换内容的时候我们往往会进行单个HTML文件的跳转,这个时候网络、性能影响,浏览器会出现不定时间的空白界面,用户体验不好 单页面应用就是用户通过某些操作地址栏url之后,动态的进行不同模板内容的无刷新切换,用户体...

文件上传的几种方式_django

一、form组件形式上传文件 缺点:页面会刷新 后台: 前端:   二、ajax形式上传 能够实现页面不刷新上传 1、原生ajax上传,使用XMLHttpRequest对象来进行上传   流程:     生成XMLHttpRequest对象     对象编写数据open()     开始发送send()     编写对象的回调函数xhr.onreadys...