在我使用vue+elementUI开发过程当中遇到一个问题:upload 对图片的宽高作校验vue
一开始我直接百度google,发现都没有这个问题,这应该是一个很常见的需求啊,element 为啥没有实现呢,也许是很简单吧,网上居然没有此类问题,我到GitHub的issue里看,确实有相似的问题,但没有系统的解决方法,凉凉。web
既然没有找到那就只能本身鼓捣了promise
想要作图片的宽高校验那就要先获取到图片宽高信息:image.onloadbash
onload 事件在图片加载完成后当即执行。函数
let image = new Image();
image.onload = function() {
let width = image.width;
let height = image.height;
};
image.src = "images/bg.jpg";
复制代码
获取到信息后那就能够进行比较了 好比我须要一张750*420尺寸的图片post
let width = 750; //图片宽度
let height = 420; //图片高度
let image = new Image();
image.onload = function() {
let isSize = image.width == width && image.height == height;
if (!isSize) {
that.$message.error("上传头像图片尺寸不符合,只能是750*420");
}
};
image.src = "images/bg.jpg";
复制代码
如今我想获取到上传的图片信息测试
beforeAvatarUpload(file) {
// 上传图片前处理函数
let width = 750; //图片宽度
let height = 420; //图片高度
let _URL = window.URL || window.webkitURL;
let image = new Image();
img.onload = function() {
let isSize = image.width == width && image.height == height;
if (!isSize) {
that.$message.error("上传头像图片尺寸不符合,只能是750*420");
}
return isSize;
};
img.src = _URL.createObjectURL(file);
}
复制代码
如今isSize确实被从新赋值了,有了正确的提示,但只是一闪而过,并成功的上传了,很郁闷,一步步的开始debugger了,发现最后仍是能够回到return的,可是不知道啥缘由,接着又开始google了,发现个人思路是错的。ui
仔细看了下掘金上的这篇文章JS 应用场景(Promise => 图片上传),发现upload人家内部确实是想要一个promise,你直接给isSize一个boolean值,最后return出去实际上是没有任何做用的,这就解释了为什么能够弹出错误信息却能够成功上传了,这个是刚才的实现方法。this
仍是去看下源码吧,一看才有点儿眉目google
upload(rawFile) {
this.$refs.input.value = null;
if (!this.beforeUpload) {
return this.post(rawFile);
}
const before = this.beforeUpload(rawFile);
if (before && before.then) {
before.then(processedFile => {
const fileType = Object.prototype.toString.call(processedFile);
if (fileType === '[object File]' || fileType === '[object Blob]') {
if (fileType === '[object Blob]') {
processedFile = new File([processedFile], rawFile.name, {
type: rawFile.type
});
}
for (const p in rawFile) {
if (rawFile.hasOwnProperty(p)) {
processedFile[p] = rawFile[p];
}
}
this.post(processedFile);
} else {
this.post(rawFile);
}
}, () => {
this.onRemove(null, rawFile);
});
} else if (before !== false) {
this.post(rawFile);
} else {
this.onRemove(null, rawFile);
}
},
复制代码
这才发现this.beforeUpload是一个真正的promise,你给人家必须返回一个promise,简单的boolean值是没用的,由于人家内部还有不少的对promise的实现,这下清楚了一点,就顺水推舟的有了最终的方法,通过多样测试,的确能够。
最终版代码
beforeAvatarUpload(file) {
// 上传图片前处理函数
const isJPG =
file.type === "image/jpeg" ||
file.type === "image/png" ||
file.type === "image/gif";
const isLt2M = file.size / 1024 / 1024 < 2;
let that = this;
let isAllow = false;
if (!isJPG) {
this.$message.error("上传头像图片只能是 jpg、png、gif 格式!");
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
const isSize = new Promise(function(resolve, reject) {
let width = 750;
let height = 420;
let _URL = window.URL || window.webkitURL;
let image = new Image();
image.onload = function() {
let valid = image.width == width && image.height == height;
valid ? resolve() : reject();
};
image.src = _URL.createObjectURL(file);
}).then(
() => {
return file;
},
() => {
this.$message.error("上传头像图片尺寸不符合,只能是750*420!");
return Promise.reject();
}
);
return isJPG && isLt2M && isSize;
}
复制代码
看了最终版的代码发现确实也很简单,咱们每每被固有的思惟带入歧途,其实仍是本身的功力不深啊,之后仍是要多注重基础,多挖掘细节,以小见大,修炼内功,共勉!