在平时项目开发中,我们经常会对文件做一些上传操作,不仅仅要实现基本需求,也要兼顾用户体验,根据自己在工作中遇到的问题谈谈对图片上传的预览以及上传进度的优化。
基于vue.js+axios搭建的项目,新建一个Index.Vue项目如下,基本结构可以先可以选择文件,预览文件。
<template>
<div class="wrapper">
<h2 class="text-center">上传图片</h2>
选择文件:<input type="file" multiple="true" accept="image/gif, image/jpeg" @change="handleFileChange($event)">
<p>图片预览:</p>
<img v-show="imgPreViewSrc" :src="imgPreViewSrc" alt="图片预览">
<button v-show="file" @click="uploadFile">上传文件到服务器</button>
</div>
</template>
<script>
...
data(){
return{
imgPreViewSrc:'', //文件预览地址
file:null, //上传文件
}
}
methods:{
}
...
</script>
<style lang="less" scoped>
.text-center{
text-align: center;
}
.wrapper{
font-size: 16px;
width: 60%;
height: 100%;
margin: 0 20%;
border: 1px solid #ddd;
img{
width: 200px;
}
button{
width:120px;
height: 30px;
margin-top: 30px;
line-height: 30px;
border: 1px solid #CCC;
text-align: center;
}
}
</style>
input的类型type设置为file,可以选择文件,multipe属性设置为true,一次可以选择多个文件。
选择一个图片文件(bg.jpg),之前有在input绑定文件改变监听方法,发现刚才选择的文件在Event>target>files下面:files是一个数组,刚才只选择了一张图片,所以长度为1,图片的名称(name),大小(size),类型(type)都有包含。
2.1.设置文件类型
在input标签accept属性设置文件类型,当用户打开文件资源管理器选择文件时,会过滤掉其他类型文件,能够从源头避免用户选择脏文件,也更加方便用户选择文件。
<input type="file" multiple="true" accept="image/gif, image/jpeg" @change="handleFileChange($event)">
2.2.图片预览
要将用户选择的文件显示到页面上,以方便用户下一步操作,因为用户可能会从选择的文件中再挑选几张图片操作,例如上传到服务器。
图片预览要用到URL对象的URL.createObjectURL(file)方法生成一个blob地址,直接赋值给img标签的src,页面就可以展示。(URL.createObjectURL() 静态方法会创建一个 domString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。)
在methods添加handleFileChange方法,预览图片
...
// 文件改变监听事件
handleFileChange(evt){
console.log(evt);
let file=evt.target.files[0];
this.file=file;
let src=URL.createObjectURL(file);
this.imgPreViewSrc=src;
},
...
选择好文件之后,文件要上传到服务器,有时候文件很大或者网速很慢的情况下,用户需要知道已经上传进度,如果没有上传进度,用户退出页面那么文件就上传失败了。
3.1.修改script文件
<script>
import axios from 'axios';
// 文件上传服务api
const baseURL='http://127.0.0.1/api';
function upload (params,cb=null) {
return new Promise((resolve, reject) => {
axios.create({
baseURL,
})({
url:'/upload/uploadFile/image',
method:'post',
data:params,
// 上传进度
onUploadProgress:function(progressEvent){
if(progressEvent.lengthComputable && cb){
cb(progressEvent);
}
},
}).then(res => {
console.log(res.data);
if(res.status===200){
resolve(res.data);
}else{
reject(res.data);
}
}).catch(err => {
reject(err);
});
});
}
...
// 上传文件到服务器
uploadFile(){
let file=this.file;
if(file){
let formData = new FormData();
formData.append('file', file);
upload(formData,(progressEvent)=>{
console.log(progressEvent);
});
}else{
alert('请选择文件')
}
...
</script>
3.2.上传进度
在axios入参新增onUploadProgress方法,在文件上传过程中该方法会调用,参数包含上传的一些信息。
有关ProgressEvent的一些介绍:
可以发现ProgressEvent中loaded属性值为图片文件上传的大小,total为文件的大小。
3.3.在页面添加进度条
为了组件通用化,新建一个Progress.vue组件,接受一个progressValue进度参数。
<template> <div> <div> <p v-if="progressValue<100">上传进度:{{progressValue}}%</p> <p v-else>上传成功!</p> <progress :value="progressValue" max="100"></progress> </div> </div> </template> <script> export default { props:['progressValue'], name: 'Progress', }; </script> <style lang="less" scoped> .progress-box{ position: fixed; top:0; left:0; bottom: 0; right:0; background: rgba(0,0,0,0.5); .progress-content{ position: absolute; top:50%; left:50%; width: 300px; height: 76px; padding: 8px 30px; transform: translate(-150px,-38px); background: #fff; border-radius: 8px; p{ margin-bottom: 5px; } progress{ width: 100%; height: 22px; } progress::-webkit-progress-bar{ background-color:#d7d7d7; } progress::-webkit-progress-value{ background-color:orange; } } } </style>
在div末尾添加Progress组件,再修改Index.vue文件methods的上传方法:
<template>
<div>
...
<Progress :progressValue="progressValue" v-if="isShowProgressBox"></Progress>
</div>
</template>
<script>
import Progress from '../components/Progress';
...
// 上传文件到服务器
uploadFile(){
let file=this.file;
if(file){
let formData = new FormData();
formData.append('file', file);
upload(formData,(progressEvent)=>{
this.isShowProgressBox=true;
this.progressValue=parseFloat((progressEvent.loaded/progressEvent.total*100).toFixed(2));
if(this.progressValue===100){
let timer=setTimeout(()=>{
this.isShowProgressBox=false;
clearTimeout(timer);
timer=null;
},500);
}
});
}else{
alert('请选择文件');
}
...
</script>
h5里提供了webkitdirectory 来实现上传文件夹的功能,但它仅支持Chrome。上传文件–限制类型 添加accept属性,使用*会导致谷歌浏览器响应延迟,对IE和火狐没有影响 。如需规定多个值,请使用逗号分隔。
平时开发时可能会遇到上传图片问题,但如果是上传图片,多数是先进行上传然后才能回显,今天给大家介绍一个简单的上传前先对图片进行回显的方式,仅用一小部分js代码即可实现
上传文件的类型;具体做法如下所示:注意:accept属性可以限制上传格式,其有兼容性如下
下行速率一般是从网络上的主机获取数据的速率,各种网络软件的运用,都必须从网路上获取数据。上传速率(度)是指单位时间内,网络数据的上行流量。
谷歌浏览器升级到chrome52.0.2743.80版本以上,会出现点击上传文件选择框会延迟几秒才会显示 反应很慢的情况。方案一:修改accept参数;方案二:浏览器修改设置
在使用file上传文件的时候,想到了图片预览的功能,然后查询了一些资料,一种是需要后端配合,将数据变成base64或者buff等数据传给后端然后调取接口进行显示,但是这种需要后端的配合和网络请求,感觉不如在纯前端操作方便的多
在做上传文件的时候,大家会引入input标签。但在实现的过程中,在上传一个文件后,第二次上传同一个文件时会无法触发上传的代码,问题其实这样解决。
通过设置nginx的client_max_body_size解决nginx+php上传大文件的问题: 用nginx来做webserver的时,上传大文件时需要特别注意client_max_body_size这个参数,否则会中断在nginx的请求中,在php中是无法记录到访问的.
将图片发给后端 ajax:1.前端获取图片信息 文件域;2.将文件信息 存到formdata;3.调用后端写的api接口发送数据;b.接受返回的数据;前端页面显示图片
最近项目开发中涉及到文件上传功能,使用的是七牛的服务。查看七牛文档发现文件上传格式为blob,而本地添加上传文件时获取到的是file格式,因此需要将file转换为blob,具体转换方法如下:
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!