<template><div><Buttontype="primary"style="margin-right: 14px;"@click="uploadFile">上传</Button><inputtype="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; // 转换为MBif (fileSize > 50) { // 判断文件大小是否超过50this.$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>