使用axios可以实现文件上传功能,并且可以获取上传进度,实现带进度条的上传文件功能
<template>
<div>
<div>
<div> <input type="file" /></div>
<div class="prog_wrap">
<div class="text">0%</div> // 进度百分比
<div class="proing" ></div> // 进度条
</div>
</div>
</div>
</template>
<script>
export default{
name:'up_loadfile',
data(){
return { dataList:[] }
},
</script>
<style>
.prog_wrap{ width: 300px; height: 40px; border: 1px solid black; position: relative;}
.text{ position: absolute;top: 50%;left: 50%; transform:translate(-50%,-50%);}
.proing{ width: 0%; height: 100%; background-color: aquamarine;}
</style>
上传的逻辑
console.log(e.target.files[0])
在控制台打印 “上传第一个图片的信息 ”
console.log(e.target.files[0])
uploadfile(e){
console.log(e.target.files[0])
let file=e.target.files[0];
let formData=new FormData();
formData.append("headfile",file);//将文件file用接口参数headfile来承载
}
头像上传接口:方式:post 。参数:headfile=图片路径
Axios.post( ).then()上传后返回的响应信息
msbox是图片名称
<template>
<div>
<div>
<input type="file" @change="uploadfile" />
-------------------------------------
进度条盒子
<div class="prog_wrap">
<div class="text">{{progVal}}%</div> // 百分比
<div class="proing" :style="{width:progVal+'%'}"></div> //进度条
</div>
进度条盒子
-------------------------------------
</div>
<div>图片预览效果:<img :src="showImage" alt="" /></div>
</div>
</template>
<script>
import Axios from 'axios';//使用Axios
export default{
name:'up_loadfile',
data(){
return {
progVal:0,
showImage:""
}
},
methods:{
uploadfile(e){
console.log(e.target.files[0])
let file=e.target.files[0];
let formData=new FormData();
formData.append("headfile",file);//将文件添加到 FormData对象实例中
//--------------------------------------------------
//进度条
let config = {
onUploadProgress: (progressEvent)=>{
let percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total );
console.log(percentCompleted); //如果图片上传成功则控制台显示100%,percentCompleted是进度值
this.progVal=percentCompleted
}
};
//--------------------------------------------------
// Axios:
//第一参数接口文档,第二个参数是数据,第三个参数是进度条
Axios.post(this.$config.baseApi+"/user/myinfo/formdatahead?token="+this.$config.token,formData,config).then(res=>{console.log(res)
if(res.data.code==200){ //判断是否post成功
this.showImage="http://vueshop.glbuys.com/userfiles/head/"+res.data.data.msbox;
}
})
//----------------------------------------------------------
}
}
}
</script>
<style>
.prog_wrap{ width: 300px; height: 40px; border: 1px solid black; position: relative;}
.text{ position: absolute;top: 50%;left: 50%; transform:translate(-50%,-50%);}
.proing{ width: 0%; height: 100%; background-color: aquamarine;}
</style>
问题1:uploadfile(e)中e是事件对象作为参数,那请问,是只有change类型的事件才有e事件对象作为参数,还是其他类型的事件,也具有e事件对象作为参数
【Vue.js中事件处理函数的参数e(事件对象)的适用范围】
在Vue中,当我们在模板里使用事件监听,比如@click、@input、@change等,绑定的事件处理函数会被自动传入一个事件对象e。这个e是原生的JavaScript事件对象,它包含了事件相关的信息,比如触发事件的元素、事件类型、时间戳等等。在原生JavaScript中,事件处理函数默认都会接收到这个事件对象作为第一个参数,只要定义了参数就可以访问到。
所有的事件处理函数都会接收到事件对象e,只要在方法中声明这个参数。比如,@click、@input、@keyup等等,这些事件的处理函数都可以访问到e对象。而不仅仅是@change事件。
uploadfile方法接收了e参数,并在其中获取了e.target.files[0],这是处理文件上传时常用的方式。这里的e是change事件的事件对象,当文件选择后触发change事件,e.target指向input元素,从而获取文件信息。
Vue官方文档,事件处理部分提到,当使用内联语句的方式,比如@click=“handleClick”,如果没有参数,方法会默认接收事件对象作为第一个参数。如果提供了参数,
如@click=“handleClick(‘arg’, event)”,则需要显式传递event来获取事件对象。
所以,不管事件类型是什么,只要事件被触发,事件处理函数如果没有参数,就会接收到这个e对象。而像@change、@click等事件都是如此。因此,e对象是每个事件处理函数都有的,前提是没有被其他参数覆盖。
关键点解析:
1. 所有事件都有事件对象 e
只要触发的是原生 DOM 事件(如 click、change、input 等),对应的处理函数默认都会自动接收事件对象 e 。这个对象包含事件相关的信息(如触发元素、事件类型、坐标等)。
2. 显式声明参数才能访问 e
在 Vue 模板中,如果事件处理函数没有显式传递参数,e 会自动作为第一个参数传入。例如:
------------------
HYML
<button @click="handleClick">点击</button>
---------------------
JS
methods: {
handleClick(e) { // 自动接收 e 对象
console.log(e.target); // 输出触发事件的元素
}
}
3.如果自定义参数,需用 $event 手动传递 e
当处理函数需要其他参数时,需手动传递 $event 以保留事件对象:
-------------------------------
html
<button @click="handleClick('参数', $event)">点击</button>
-----------------------------------
js
methods: {
handleClick(arg, e) { // 通过 $event 获取 e
console.log(arg, e.target);
}
}
<input type=“file” @change=“uploadfile” />中,@change=“uploadfile” 没有传递参数,因此 uploadfile 方法默认接收 e 作为参数
问题2:e的内容
在 JavaScript 和 Vue 中,事件对象 e(或 event)是浏览器在事件触发时自动创建的一个对象,它记录了事件发生时的所有相关信息,并提供了控制事件行为的方法。它的存在是为了让开发者能更精细地处理事件
e 的具体内容取决于事件类型(如 click、change、keydown),以下是通用属性和方法:
问题3:FormData对象
1. FormData 是什么:
它是浏览器提供的一个 API,专门用于构造表单数据,适合通过 JavaScript 发送文件或表单数据到服务器。
可以自动处理文件、二进制数据、文本字段的编码,无需手动拼接数据。常用于通过 AJAX(如 Axios、Fetch)上传文件。
let formData = new FormData();
作用:创建一个空的 FormData 对象。
2. formData.append(“headfile”, file);
append的作用:向 FormData 对象中添加一个键值对,键名为 “headfile”,值为用户选择的文件(file)。
参数说明:
“headfile”:服务器接口要求的字段名(需与后端约定,例如后端通过 headfile 字段接收文件)。
file:用户通过 < input type=“file”> 选择的文件对象(即 e.target.files[0])。
总结:
FormData 是处理文件上传的标准工具。
append 方法将文件添加到表单数据中,键名需与后端匹配。
最终通过 HTTP 请求(如 Axios)将 FormData 发送到服务器。
问题3:Axios.post的语法结构
Axios.post的语法结构,即axios.post(url, data, config),其中data是请求体,config是配置选项。
接下来,要解释每个参数的意义。第一个参数是URL,包含基础地址、路径和token查询参数。第二个参数formData是发送的数据,对应请求体。第三个参数config是Axios的配置对象,比如设置请求头或上传进度回调。
如果不使用Axios.post的语法结构来发送请求,而是用我们封装好的Axios函数来做,来发送请求该如何做
封装好的Axios函数: request_name( )来发送post请求
import Axios from "axios";
import _config from "../conf/confg";
import qs from "qs"; //这里的post数据类型转换我们用拦截器来做
//导出名叫request_name的一个方法
export function request_name(config1 = {}, router) {
//创建实例
let service = Axios.create({ baseURL: _config.baseApi });
//-------------------------------------------------------------------------------
//请求拦截器来做post数据转换
service.interceptors.request.use(
(config) => {
console.log(config);
----------------------------------------------------------------------
if (config.method.toLocaleLowerCase() === "post") { //小写一致化
config.data = qs.stringify(config.data);
} else if (config.method.toLocaleLowerCase() === "file") {
config.method = "post";
let formData = new FormData();
if (config.data instanceof Object) { //(config.data是否为对象类型
for (let key in config.data) {
formData.append(key, config.data[key]);
}
config.data = formData;
}
-------------------------------------------------------------------
// config.method = "post";
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
//-------------------------------------------------------------------------------
//响应拦截器
service.interceptors.response.use(
(response) => {
console.log(response); //判断是否调用了会员安全认证接口了
if (response.config.url == "/home/user/safe?token=1ec949a15fb709370f") {
if (response.data.code != 200) {
localStorage.clear();
//没有调用了会员安全认证接口,即登录验证失败
router.replace("/login"); //跳到登录页面
}
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
//------------------------------------------------------------------------------
return service.request(config1).then((res) => res.data);
}
<template>
<div>
<div>
<input type="file" @change="uploadfile" />
<div class="prog_wrap">
<div class="text">{{progVal}}%</div>
<!-- 进度百分比 -->
<div class="proing" :style="{width:progVal+'%'}"></div>
<!--进度条 -->
</div>
</div>
<div>图片预览效果:<img :src="showImage" alt="" /></div>
</div>
</template>
<script>
export default{
name:'up_loadfile',
data(){
return {
progVal:0,
showImage:""
}
},
methods:{
uploadfile(e){
console.log(e.target.files[0])
let file=e.target.files[0];
---------------------------------------------------------------------------
this.$requestname({
url:"/user/myinfo/formdatahead?token="+this.$config.token,
data:{headfile:file},//由于是post请求,而requestname封装的Axios需要转换数据类型,但在这里的数据类型不需要转
method:"file",//所以这里的请求类型我们要自定义一个,来逃避Axios中post需要换数据类型这一行为
进度条 onUploadProgress: (progressEvent)=>{
let percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total );
console.log(percentCompleted);//如果图片上传成功则控制台显示100%
this.progVal=percentCompleted
}
}).then(res=>{
console.log(res)
if(res.code==200){
this.showImage="http://vueshop.glbuys.com/userfiles/head/"+res.data.msbox;
}
})
}
}
-------------------------------------------------
}
</script>
<style>
.prog_wrap{ width: 300px; height: 40px; border: 1px solid black; position: relative;}
.text{ position: absolute;top: 50%;left: 50%; transform:translate(-50%,-50%);}
.proing{ width: 0%; height: 100%; background-color: aquamarine;}
</style>
如果config.data是Object类型,我们进行for循环,因为,data里面可能还有其他的值呢,如 data:{headfile:file ,“book”:33 }等,很幸运我们这里就有一个值
FormData 对象的创建和将图片文件添加到 中FormData 对象,如下
【 FormData 对象的创建和将图片文件添加到 中FormData 对象,】这一步可以放到Axios的请求数据体里,使其更加方便