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="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="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中的图片获取与上传的更多相关文章

  1. vue+element ui中select组件选择失效问题原因与解决方法

    codejing 2020-07-10 09:13:31  652  收藏 分类专栏: Web Vue Element UI 版权 .当表单form赋完值后,如果后续又对form中某一属性值进行操作如 ...

  2. 使用element UI el-upload组件实现视频文件上传及上传进度显示方法总结

    实现效果: 上传中: 上传完成: 代码: <el-form-item label="视频上传" prop="Video"> <!-- acti ...

  3. asp.net 中 UEditor 图片和附件上传失败的处理方法

    1.0 找到 net 文件夹下面的 web.config 配置文件,注释掉如下的两句: 2.0 Uploader文件默认属性为编译,将其属性改为内容以后重新运行程序,图片上传成功. 3.0 删除 im ...

  4. vue给input file绑定函数获取当前上传的对象

    HTML <input type="file" @change="tirggerFile($event)"> JS(vue-methods) tir ...

  5. 基于element ui 实现七牛云自定义key上传文件,并监听更新上传进度

    借助上传Upload 上传组件的 http-request 覆盖默认的上传行为,可以自定义上传的实现 <el-upload multiple ref="sliderUpload&quo ...

  6. Vue+Element UI 实现视频上传

    一.前言 项目中需要提供一个视频介绍,使用户能够快速.方便的了解如何使用产品以及注意事项. 前台使用Vue+Element UI中的el-upload组件实现视频上传及进度条展示,后台提供视频上传AP ...

  7. vue + element ui 阻止表单输入框回车刷新页面

    问题 在 vue+element ui 中只有一个输入框(el-input)的情况下,回车会提交表单. 解决方案 在 el-form 上加上 @submit.native.prevent 这个则会阻止 ...

  8. 关于Element UI中页面样式小问题

    一,修改组件dialog窗口的大小 二,在我使用upload组件上传一张美女图片时,发现当预览图片时,图片是灰色的,点击一下才会变亮,这种效果使我很不舒服,于是我通过添加下面的一条样式,问题解决了(可 ...

  9. vue+element ui 的上传文件使用组件

    前言:工作中用到 vue+element ui 的前端框架,使用到上传文件,则想着封装为组件,达到复用,可扩展.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9 ...

随机推荐

  1. 跨域解决方案之HTML5 postMessage

    问题场景: web是嵌入到手机客户端中的静态页面,为了统计用户行为需要引入ga,但是ga必须是在www下才行,哪怕是localhost,这就是矛盾.解决方案是在页面中使用iframe,iframe是在 ...

  2. vue-cli脚手架项目实例

    看完了配置,接下来通过一个实例,更清晰地了解这些文件之间的联系,顺带练习练习vue相关知识. 1.安装 打开命令行控制器,系统自带cmd或者git bash等都可以,按照顺序输入如下指令,耐心等待每一 ...

  3. CSS浮动并清除浮动(造成的影响)

    一.浮动 CSS浮动    CSS float浮动的深入研究.详解及拓展(一)    CSS浮动属性Float详解 块级元素独占一行 块级元素,在页面中独占一行,自上而下排列,也就是传说中的流. 可以 ...

  4. 基于Vue的WebApp项目开发(二)

    利用webpack解析和打包.vue组件页面 相关知识: vue项目中的每个页面其实都是一个.vue的文件,这种文件,Vue称之为组件页面,必须借助于webpack的vue-loader才能运行,所以 ...

  5. ST Link 调试问题总结

    用过ST Link调试工具的同事都应该知道,ST Link是一个很不错的调试工具,它具有小并且功能齐全,价格便宜等特点,现在市场上普遍是下面这两种ST Link, 但如果用的比较多,会发现有时候会存在 ...

  6. geoserver 知识小计

    http://localhost:8888/geoserver/wms?service=WMS&request=GetCapabilities 这个地址用于获取发布的WMS服务的属性,用于获取 ...

  7. 体验SpringBoot

    体验SpringBoot 1.介绍 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开 ...

  8. linux下 signal信号机制的透彻分析与各种实例讲解

    转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/det ...

  9. 利用Kali进行WiFi钓鱼测试实战

    文中提及的部分技术可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用.请不要做一只咖啡馆里安静的猥琐大叔. 写在前面 从至少一年前我就一直想在自己跑kali的笔记本上架个钓鱼热点.然而由于网上的 ...

  10. make menuconfig 出错解决

    问题: hank@hank-virtual-machine:/opt/Emb/linux-2.6.30.4$ sudo make menuconfig *** Unable to find the n ...