效果图:
思路:当上传的时候,才显示 进度条,上传完毕,不显示进度条。然后再显示 缩略图
上传
//是否显示缩略图。当原文存在有缩略图的时候,取值 true ,当不存在值的时候,取值 false。
let showThumbnail = ruleForm.topic.picurl ? ref(true) : ref(false);
//缩略图网址。因为数据储存为 相对路径,前端显示的时候,添加上网址,成为绝对路径
let showThumbnailUrl = ruleForm.topic.picurl ? ref(import.meta.env.VITE_BASE_URL + ruleForm.topic.picurl) : ref('');
//是否显示进度条。默认为不显示,当上传图片的时候,才开始显示。上传完毕后,再改为不显示。
let showProcess = ref(false);
//进度条初始数据,开始为0,最后为 100
let progressPercent = ref(0);
//自动上传处理。有 http-request 触发。
const handleThumbnailUpload = (option: UploadRequestOptions) => {
let oldThumbnail = ruleForm.topic.picurl;
let { file } = option;
let formData = new FormData();
formData.append('file', file);
uploadImage(formData) //自定义 axios 上传
.then((res) => {
if (res.data.picurl) {
ruleForm.topic.picurl = res.data.picurl; //把生成的缩略图赋值给表单数据,供给
handleThumbnailShow(res.data.picurl); //自定义函数,处理显示进度条、显示缩略图
if (oldThumbnail) {
removeImage(oldThumbnail); //从服务器上删除旧缩略图
}
} else {
if (res && res.data.msg) {
ElMessage.error(res.data.msg);
} else {
ElMessage.error('图片上传失败!');
}
resetProcess();
return false;
}
})
.catch(() => {
resetProcess();
});
};
// 有 on-change 触发,开始进度条计值
const handleThumbnailChange = (uploadFile: UploadFile) => {
if (uploadFile.status === 'ready') {
showProcess.value = true;//开始显示进度条
let ms = 0;
const interval = setInterval(() => {
if (progressPercent.value >= 100) { //当达到 100 ,停止计值
clearInterval(interval);
return;
} else if (ms >= 5000) {
clearInterval(interval); //由于意外而上传失败,超过 5 秒,停止 计值
return;
}
progressPercent.value += 1; //计算增加值,进度条
ms += 50;
}, 50);
}
};
//人为设置进度条。当上传完毕后,再显示 进度条达到 100
const handleThumbnailShow = (url: string) => {
setTimeout(() => {
progressPercent.value = 100;
}, 100);
setTimeout(() => {
showThumbnailUrl.value = import.meta.env.VITE_BASE_URL + url;
showThumbnail.value = true;
resetProcess();
}, 1000);
};
//复原进度条为不显示
const resetProcess = () => {
showProcess.value = false;
progressPercent.value = 0;
};
//自定义限制上传图片类型
const handleThumbnailBeforeUpload = (rawFile: UploadRawFile) => {
if (imageType.indexOf(rawFile.type) === -1) {
ElMessageBox({
type: 'error',
title: '',
message: '上传的文件必须是JPG、JPEG、PNG、GIF、BMP类型',
showCancelButton: false,
confirmButtonText: 'OK',
});
return false;
} else if (rawFile.size / 1024 / 1024 > 10) {
ElMessageBox({
type: 'error',
title: '',
message: '图片大小不能超过 10MB',
showCancelButton: false,
confirmButtonText: 'OK',
});
return false;
}
return true;
};
import request from '@/http/index';
import type { AxiosPromise, AxiosResponse, AxiosError } from 'axios';
export function uploadImage(formData: FormData): AxiosPromise {
return new Promise((resolve, reject) => {
request
.post('/thumbnail/upload/' + Math.random(), formData, {
headers: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
},
})
.then((res: AxiosResponse) => {
resolve(res);
})
.catch((error: AxiosError) => {
reject(error);
});
});
}
export function removeImage(picurl: string | undefined): AxiosPromise {
return new Promise((resolve, reject) => {
if (picurl) {
request({
url: '/thumbnail/remove/' + Math.random(),
method: 'delete',
data: { picurl: picurl },
})
.then((res: AxiosResponse) => {
resolve(res);
})
.catch((error: AxiosError) => {
reject(error);
});
} else {
reject();
}
});
}
const ruleForm: TopicPostForm = reactive({
topic: { tid: 0, cid: 0, dir: '', title: '', keywords: '', channel: '', description: '', summary: '', version: '', picurl: '', content: '', filterHtml: 0, yn: 1 } as TopicPost,
channelList: [] as TopicChannel[],
});
const setTopicContent = (topic: TopicPost, channelList: TopicChannel[]) => {
ruleForm.topic.tid = topic.tid;
ruleForm.topic.cid = topic.cid;
ruleForm.topic.dir = topic.dir;
ruleForm.topic.title = topic.title;
ruleForm.topic.keywords = topic.keywords;
ruleForm.topic.channel = topic.channel;
ruleForm.topic.description = topic.description;
ruleForm.topic.summary = topic.summary;
ruleForm.topic.version = topic.version;
ruleForm.topic.picurl = topic.picurl;
ruleForm.topic.content = topic.content;
ruleForm.topic.yn = topic.yn;
ruleForm.channelList = resetChannelList(channelList);
};
以上内容,根据自己的实际情况,可以自由定义。与上传相关的只有一个缩略图网址:ruleForm.topic.picurl
element plush 上传功能文档
注意:action:请求 UR。在上传组件中,当无后端处理网址的时候,on-success 也是无效的,不能触发,on-progress 也是无效的,不能触发。on-change 仅仅有个 ready 状态有效。