在調(diào)試圖片限制寬高時 出現(xiàn)了很多的問題 一開始我直接百度google, 發(fā)現(xiàn)都沒有這個問題.感覺這應(yīng)該是很常見的需求, element內(nèi)部沒有實現(xiàn), 也許是很簡單?網(wǎng)上都沒有此類問題.
到GitHub的issue里看, 確實有類似的問題, 但沒有系統(tǒng)的解決方法.一開始,我的思路就是按照常規(guī)的校驗方法去校驗, 由于js是沒有讀取圖片權(quán)限的, 在這里我使用了URL對象的URL.createObjectURL(file)方法, 其中包含一個表示參數(shù)中給出的對象的URL, 這個URL的生命周期和創(chuàng)建它的窗口中的document 綁定, 可以用于在瀏覽器上預(yù)覽本地圖片或者視頻.
但是既然是通過url讀取寬高就牽扯到圖片是否加載完畢的問題, 雖然是在本地創(chuàng)建一個圖片對象, 但創(chuàng)建還是有延遲問題.
解決了文件讀取問題后我就能拿到圖片真實寬高了, 經(jīng)過反復(fù)的debug 我發(fā)現(xiàn)img.onload并沒有走, isSize也一直是false, 看來這種邯鄲學(xué)步的方法顯然行不通, 想到onload是異步的, 來不及走就return結(jié)束了這個方法, 其實最省事的辦法, 就是給圖片判斷加上1秒的延遲, 但這種做法顯然是在自掘墳?zāi)?所以還是需要拿到文件真實的加載完成狀態(tài), 所以想法異步操作一下, 讓onload之后再執(zhí)行isSize的判斷以及return, 于是我就增加回調(diào)函數(shù)使onload先執(zhí)行, 然后對isSize有賦值操作.代碼如下:
之后isSize確實被重新賦值, 也有了正確的提示, 但只是一閃而過, 并成功的上傳了???
一步步的開始debug了, 發(fā)現(xiàn)最后還是可以回到return的, 但是不知道原因, 接著又開始google了, 發(fā)現(xiàn)我的思路是錯的.我發(fā)現(xiàn)beforeAvatarUpload其實是返回一個Promise
我在查看了一篇文章后, 發(fā)現(xiàn)Element Ui的upload人家內(nèi)部確實是想要一個promise, 直接給isSize一個boolean值return出去其實是沒有任何作用的, 這就解釋了為什么可以彈出錯誤信息卻可以成功上傳了, 這個是開始的實現(xiàn)方法
再后來我通過查看源碼之后發(fā)現(xiàn)this.beforeUpload是一個真正的promise, 也就是說必須返回一個promise, 簡單的boolean值是沒用的, 因為Element組件內(nèi)部還有很多的對promise的實現(xiàn).
這下清楚了一點, 就有了最終的方法, 經(jīng)過多次測試終于可以了.
beforeAvatarUpload(file) {
this.filterType = []
if (this.pType) { // 判斷父組件傳過來的可上傳圖片類型
const typeArr = this.pType
for (const i in typeArr) {
this.filterType.push(this.imgType[typeArr[i]])
}
} else { // 如果沒有直接賦值為默認(rèn)
this.filterType = this.imgType
}
let typeFlag = false
for (const o in this.filterType) {
if (this.filterType[o] === file.type) {
typeFlag = true
}
}
const isLt1M = file.size / 1024 / 1024 < 1
if (!typeFlag) {
this.$message.error('上傳圖片只能是 ' + this.filterType + ' 格式!')
}
if (!isLt1M) {
this.$message.error('上傳圖片大小不超過 1MB')
}
const _width = 210
const _height = 100
const isSize = new Promise(function(resolve, reject) {
const _url = URL.createObjectURL(file)
const img = new Image()
if (1) { // 是否判斷寬高
img.onload = function() {
const valid = img.width === _width
valid ? resolve() : reject()
}
} else {
resolve()
}
img.src = _url
}).then(() => {
return true
}, () => {
this.$message.error('上傳的尺寸必須是寬:' + _width + 'px 高:' + _height + 'px')
return Promise.reject()
})
return typeFlag && isLt1M && isSize
}
當(dāng)然 我這里寬高為固定的寬高, 在實際代碼中可以是子組件傳過來的, 如果沒有傳值也可以不限制, 判斷那里我還沒有寫.這個功能看似很簡單很簡單, 但是其實牽扯到promise異步調(diào)用返回值, 由于以前異步基本都用在ajax請求, 并沒有在別的地方用過, 所以花些時間學(xué)習(xí)了一下.