一、图片下标,判断,base64,获取img标签等问题
上传图片时用到的accept只会在用户点击上传时添加一个自定义文件类型,如添加了accept=".jpg,.png,",虽然会呈现出符合条件的文件,但用户仍可以通过点击所有文件类型来上传其他类型的文件,此时设置before-upload函数,
参考el-upload上传组件accept属性限制文件类型(案例详解)_辰兮要努力的博客-CSDN博客_el-upload accept 结果只有accept在生效,ElementUI el-upload上传图片限制, before-upload 不生效问题_老电影故事的博客-CSDN博客_beforeupload参考该文章发现自动把自动上传关闭导致这个问题,就只能绑定在on-change里;另外还有:on-exceed 加 limit执行上传限制长度的函数执行。
<el-form-item label="商品轮播图设置" label-width="160px">
<p>商品轮播图</p>
<p class="tips">
仅支持上传图片,最少上传一张 最多可上传十张, 已上传
<span>{{ canonicalImage.length }}</span>
/ 10
</p>
<div class="form_canonicalImage">
<el-upload
action="#"
list-type="picture-card"
:auto-upload="false"
:limit="10"
:multiple="true"
:file-list="canonicalImage"
:on-change="uploadChange"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:on-preview="handlePreview"
:before-remove="beforeRemove"
:before-upload="beforeImageUpload"
ref="mYupload"
accept=".jpg,.png,"
>
<i slot="default" class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</div>
</el-form-item>
methods中
//删除之前的钩子
beforeRemove(file, fileList) {
return this.$confirm('删除该图片, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
},
// 删除轮播图
handleRemove(file, fileList) {
this.canonicalImage = JSON.parse(JSON.stringify(fileList));
},
//触发上传限制
handleExceed() {
this.$message.warning("上传超出限制!");
},
//预览
handlePreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
// 添加轮播图
uploadChange(file, fileList) {
//截取出文件末尾的类型
let fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
const whiteList = ["jpg", "png"];
const isLt2M = file.size / 1024 / 1024 < 4;
if (whiteList.indexOf(fileSuffix) === -1) {
this.$message.error("上传文件只能是jpg/png格式");
fileList.pop();
return false;
}
else if (!isLt2M) {
this.$message.error("上传文件大小不能超过 4MB");
fileList.pop();
return false;
}else{
this.uploadImage_loading = true;
this.getBase64(file.raw).then((res) => {
productcopyAPI
.savefile({
imagesBase64: res,
filetype: "image",
fileName: file.name,
keyName: "keyName",
ticket: this.ticket,
})
.then(({ data }) => {
fileList.forEach((item) => {
item.uid == file.uid && (item.url = data.data[0].url);
});
this.canonicalImage = JSON.parse(JSON.stringify(fileList));
})
.catch((error) => {
this.uploadImage_loading = false;
this.$message.error(error);
});
});
}
},
// 图片转base64
getBase64(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
let imgResult = "";
reader.readAsDataURL(file);
reader.onload = function () {
imgResult = reader.result;
};
reader.onerror = function (error) {
reject(error);
};
reader.onloadend = function () {
resolve(imgResult);
};
});
},
以及网络图片转base64格式的参考:vue网络图片url转Base64「建议收藏」 - 全栈程序员必看
//初始化时调用
getimage() {
this.$refs.mYupload.clearFiles();
this.uploadImage_loading = true;
let data = [];
this.canonicalImage.forEach((item, i) => {
if (item.url.includes("baidu")) {
data.push({ url: item.url, index: i });
}else{
data = []
}
});
let num = 0;
if(data[num]){
this.imageUrlToBase64(data, num);
}
},
//网络图片url转换为base64
imageUrlToBase64(data_, num) {
//一定要置空!!!!
this.base64Datas = [];
let image = new Image();
//解决跨域问题
image.setAttribute("crossOrigin", "anonymous");
let imageUrl = data_[num].url;
image.src = imageUrl;
let that = this;
//image.onload为异步加载
image.onload = () => {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
var quality = 0.8;
//这里的dataurl就是base64类型
var dataURL = canvas.toDataURL("image/jpeg", quality); //使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
//数组存放图片base64
this.base64Datas = dataURL;
productcopyAPI
.savefile({
imagesBase64: this.base64Datas,
filetype: "image",
fileName: "file.name",
keyName: "keyName",
ticket: this.ticket,
})
.then(({ data }) => {
data_[num].url = data.data[0].url;
if(num <data_.length-1){
num++
this.imageUrlToBase64(data_, num);
}else{
data_.forEach((item,i)=> {
this.canonicalImage[item.index].url = item.url;
});
}
this.uploadImage_loading = false;
})
.catch((error) => {
this.uploadImage_loading = false;
this.$message.error(error);
});
};
},
转换格式的时候,一定要将中间的变量置空!另外为防止根据默认下标有的是网络图片有的不是,导致删除错误,还需要在对象中将该图片现在图片列表中的下标当做添加index属性以当做key值
破解循环中的异步操作,不能直接用for循环,在我看来有效的办法方法体内的num++,再回调此函数
以及在商品详情中仍需要借此转换成base64的格式,但需要先用正则表达式将所有img标签里的src获取到,其他的基本大同小异了。
//正则匹配详情里所有img标签
var regex0 = new RegExp(/(?<=(img src="))[^"]*?(?=")/gims); //eslint-disable-line
this.detailimgtag = this.outdetail.match(regex0);
let data= []
let num = 0
this.detailimgtag.forEach((item,i)=>{
if (item.includes("baidu")) {
data.push({url:item,index:i})
}
})
二、formdata的方式上传视频,原生axios上传,进度条等问题
视频(也是文件)用formdata的方式上传报错,参考:vue上传文件formData入参为空,接口请求500_静静心中的梦_66的博客-CSDN博客用到了原生axios上传,另外在接口中上传和返回时间过长,需要添加一个进度条展示,参考:element ui 图片自定义上传进度条消失问题_我是顾昀峰的博客-CSDN博客_vue和elementui视频上传成功后进度条消失但展示中只会有上传进度的展示,返回以及添加至页面还需要等待很久,进度条以及到100%了。
// 视频上传函数
uploadVideo(file,fileList) {
//截取出文件末尾的类型
let fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
const blackList = ["mp4"];
const isLt2M = file.size / 1024 / 1024 < 10;
if (blackList.indexOf(fileSuffix) === -1) {
this.$message.error("上传文件只能是mp4格式");
// this.canonicalVideo = fileList.slice(0,1)
return false;
}else if (!isLt2M) {
this.$message.error("上传文件大小不能超过 10MB");
// this.canonicalVideo = fileList.slice(0,1)
return false;
}else {
this.isShowUploadVideo = false;
this.videoFlag = true;
var formdata = new FormData();
formdata.append("file", file.raw);
formdata.append("filetype", "video");
formdata.append("ticket", this.ticket);
formdata.append("keyname", "keyName");
formdata.append("filenames", file.name);
this.$axios.post('https://aicaigoufuwuapi.yiwangtui.com/api/upload/UploadFile',formdata,{
onUploadProgress: progressEvent => {
if(progressEvent.lengthComputable)
var val = parseInt(progressEvent.loaded / progressEvent.total * 100 ).toFixed(0)
this.videoUploadPercent = Math.floor(val)-1;
}
}
)
.then(res=>{
this.canonicalVideo=[{
src:res.data.data.data[0].url,
video_id:''
}];
this.videoFlag = false;
this.videoUploadPercent = 100;
})
.catch((error)=>{
this.$message.error(error+',请重新上传!');
this.videoFlag = false;
this.videoUploadPercent = 0;
})
}
},