在我使用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了,發現個人思路是錯的。this
仔細看了下掘金上的這篇文章JS 應用場景(Promise => 圖片上傳),發現upload人家內部確實是想要一個promise,你直接給isSize一個boolean值,最後return出去實際上是沒有任何做用的,這就解釋了爲什麼能夠彈出錯誤信息卻能夠成功上傳了,這個是剛纔的實現方法。google
仍是去看下源碼吧,一看纔有點兒眉目spa
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; }
看了最終版的代碼發現確實也很簡單,咱們每每被固有的思惟帶入歧途,其實仍是本身的功力不深啊,之後仍是要多注重基礎,多挖掘細節,以小見大,修煉內功,共勉!