<template>
<div>
<Button
type="primary"
style="margin-right: 14px;"
@click="uploadFile"
>上传</Button
>
<input
type="file"
id="importFile"
@change="checkedFile"
style="display: none"
accept="*"
multiple
/>
</div>
<div v-for="(item, index) in postImgList" :key="index">
{{ item.name }}
</div>
<div class="class_percent">
<Progress :percent="percent" :stroke-color="['#108ee9', '#87d068']" />
</div>
</template>
export default {
data() {
return {
postImgList: [],
percent: 0
};
},
methods: {
uploadFile() {
const loader = document.getElementById("importFile");
loader.click();
},
checkedFile({ target }) {
this.postImgList = Array.from(target.files);
if (this.postImgList.length === 0) { //如果没文件点击取消不需要调用接口
return
};
this.postImgList.forEach(item => {
item.percent = 0; // 每一条进度
const fileSize = item.size / 1024 / 1024; // 转换为MB
if (fileSize > 50) { // 判断文件大小是否超过50
this.$Message.warning(`${item.name}文件大小超过50M啦,请重新选择`);
return false;
};
});
this.upload();
},
// 上传按钮
upload() {
const formData = new FormData();
formData.append("key", "需要传的参数");
this.postImgList.forEach((item) => {
formData.append("file", item);
});
const msg = this.$Message.loading({
content: "正在上传...",
duration: 0,
closable: true,
});
this.$api.接口(formData, {
onUploadProgress: e => {
// lengthComputable:布尔值,表示加载的总量是否可以计算,默认是false。
// loaded:整数,表示已经加载的量,默认是0。
// total:整数,表示需要加载的总量,默认是0。
if (e.lengthComputable) {
this.percent = Math.round((e.loaded * 100) / e.total) == 100 ? 99 : Math.round((e.loaded * 100) / e.total);
if (this.percent === 100) {
setTimeout(msg, 5);
}
};
}
}).then((res) => {
setTimeout(msg, 5);
if (res.error !== "error") {
this.$Message.success("上传成功");
this.percent = 100;
this.getUavRefPage();
}
}).catch(() => {
setTimeout(msg, 5);
});
},
// 更新上传进度 没用到
updateFileProgress(file, progress) {
file.progress = progress;
if (progress === 100) {
setTimeout(() => {
this.fileList.splice(this.fileList.indexOf(file), 1);
}, 1000);
}
},
}
}
// e.loaded和e.total属性属于 JavaScript 中的 ProgressEvent 对象,在文件上传期间会被浏览器不断地更新,以确保上传进度得到及时的反馈。在 Axios 中,需要在上传请求中通过onUploadProgress属性传入该对象,比如:
axios.post('/upload', formData, {
onUploadProgress: e => {
console.log('已上传字节数:' + e.loaded);
console.log('总字节数:' + e.total);
}
});
// 在这里,onUploadProgress 是一个回调函数,该函数会在文件上传过程中被反复调用。而e 则是个ProgressEvent 对象,包含了与上传进度相关的一些属性。其中,e.loaded 表示上传的已完成的字节数,e.total 表示总字节数。需要注意的是,不同的浏览器和操作系统可能会返回不同的属性值。如果你使用的是 Vuejs,也可以使用axios.create 方法在组件内部创建一个自定义的Axios实例,并设置默认的onUploadProgress 回调:
export default {
// 其他代码
methods: {
upload() {
// 创建自定义 Axios 实例
const instance = axios.create({
onUploadProgress: e => {
console.log('已上传字节数:' + e.loaded);
console.log('总字节数:' + e.total);
}
});
// 发出请求
instance.post('/upload', formData);
}
}
}
这样,该组件内部所有的请求都会默认使用 instance 实例,且会默认携带 onuploadProgress回调函数。
以下是chat GPT给的
<template>
<div>
<input type="file" ref="fileInput" multiple @change="uploadFiles">
<ul>
<li v-for="(file, index) in fileList" :key="index">
{{ file.name }}
<Progress :percent="file.progress" v-if="file.progress !== 100"/>
<Icon name="ios-close" class="delete-icon" @click.prevent="removeFile(index)" />
</li>
</ul>
</div>
</template>
<script>
import { Upload, Progress, Icon } from 'view-design';
import axios from 'axios';
export default {
components: { Upload, Progress, Icon },
data() {
return {
fileList: []
};
},
methods: {
// 上传文件
uploadFiles() {
// 获取选择的文件
const files = this.$refs.fileInput.files;
// 遍历每个文件进行上传
for (let i = 0; i < files.length; i++) {
const file = files[i];
// 创建新的文件对象
const newFile = {
name: file.name,
progress: 0,
file: file,
cancelToken: null
};
// 添加到文件列表
this.fileList.push(newFile);
// 创建FormData对象实现上传
const formData = new FormData();
formData.append('file', file);
// 执行上传操作
const cancelTokenSource = axios.CancelToken.source();
axios.post('/upload', formData, {
cancelToken: cancelTokenSource.token,
onUploadProgress: e => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded * 100) / e.total);
this.updateFileProgress(newFile, percent);
}
}
})
.then(response => {
this.updateFileProgress(newFile, 100);
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('上传已取消:', file.name);
}
});
newFile.cancelToken = cancelTokenSource;
}
// 清空选择的文件
this.$refs.fileInput.value = null;
},
// 更新上传进度
updateFileProgress(file, progress) {
file.progress = progress;
if (progress === 100) {
setTimeout(() => {
this.fileList.splice(this.fileList.indexOf(file), 1);
}, 1000);
}
},
// 删除文件
removeFile(index) {
const file = this.fileList[index];
if (file) {
if (file.cancelToken) {
file.cancelToken.cancel(`用户取消上传:${file.name}`);
}
this.fileList.splice(index, 1);
}
}
}
};
</script>
<style>
.delete-icon {
margin-left: 10px;
font-size: 14px;
color: #f00;
cursor: pointer;
}
</style>