工做上接觸了一下圖片的處理,圖片的格式是文件流, 記錄以下。html
請求圖片的時候,帶上{ responseType: 'blob' }
, 不然圖片顯示的多是亂碼。前端
axios .post(url, parmas, { responseType: 'blob' }) .then(res => { return Promise.resolve(res); }) .catch(e => { return Promise.reject(e); });
圖片返回的是文件流的形式, 控制檯中顯示的是亂碼。
直接顯示二進制圖片會出錯,因此咱們要進行處理。vue
<!-- template中 --> <img alt="logo" :src="imageUrl" @error="handleLoadError" />
/*------ script中------*/ let urlCreator = window.URL || window.webkitURL; let imageUrl = urlCreator.createObjectURL(res); this.imageUrl = imageUrl;
顯示圖片中,要對萬一圖片顯示不出來的狀況進行處理。使用onerror
事件能夠對加載圖片失敗的狀況進行處理。ios
handleLoadError(e) { const img = e.srcElement; this.imageUrl = this.errorLoadImg; // 用加載失敗的圖片替代之 img.onerror = null; // 清除錯誤:若是錯誤時加載時顯示的圖片出錯,將會一直循環,因此咱們必須清除掉錯誤,限制運行一次 }
<el-upload action="uploadUrl" :show-file-list="false" :accept="'image/*'" :headers="{token:$cookieStorage.token}" :on-success="handleSuccess" :on-error="handleError" :before-upload="handleBeforeUpload" :on-progress="handleProgress" > <el-button type="primary" size="medium">上傳圖片</el-button> </el-upload> <!-- action: 圖片上傳的地址 show-file-list: 是否顯示文件上傳列表 accept: 可接受的上傳類型,image/*爲圖片 headers: 頭部信息 on-success: 上傳成功事件 on-error: 上傳失敗事件 before-upload: 上傳前處理事件,返回一個值,值爲false將阻止上傳 on-progress: 上傳中事件 -->
/*----- 如下爲經常使用處理代碼 ------*/ handleSuccess(response, file, fileList) { this.$success("上傳成功"); }, handleError() { this.$error("上傳失敗,請從新上傳圖片!"); }, handleBeforeUpload(file) { const isImage = file.type.includes("image"); if (!isImage) { this.$message.error("上傳文件類型必須是圖片!"); } const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error("上傳圖片大小不能超過 2MB!"); } return isImage && isLt2M; }, handleProgress(event, file, fileList) { this.loading = true; // 上傳時執行loading事件 }
要求:每一個 picture area 限制選擇一張圖片,點擊肯定後一塊兒提交。web
<el-upload action="myUrl" :on-change="(file,fileList)=>{handleChange(file,fileList,1)}" :on-remove="(file,fileList)=>{handleRemove(file,fileList,1)}" :auto-upload="false" :file-list="fileList[0]" ref="file1" > <el-button size="small">選擇圖片</el-button> </el-upload> <el-upload action="myUrl" :on-change="(file,fileList)=>{handleChange(file,fileList,2)}" :on-remove="(file,fileList)=>{handleRemove(file,fileList,2)}" :auto-upload="false" :file-list="fileList[1]" ref="file2" > <el-button size="small">選擇圖片</el-button> </el-upload> <el-upload action="myUrl" :on-change="(file,fileList)=>{handleChange(file,fileList,3)}" :on-remove="(file,fileList)=>{handleRemove(file,fileList,3)}" :auto-upload="false" :file-list="fileList[2]" ref="file3" > <el-button size="small">選擇圖片</el-button> </el-upload> <el-button @click="submitData">確認</el-button> <!-- action:提交的地址,此處隨便寫一個,不寫會報錯 on-change: 圖片上傳到緩存中將被觸發 on-remove: 從緩存中刪除文件將被觸發 -->
data(){ fileList: [0,0,0], //緩存區文件 uploadFile:[[],[],[]] // 上傳用文件 }, handleChange(file, fileList, type) { // 限制單張上傳,超過限制即覆蓋 if (fileList.length > 1) { fileList.splice(0, 1); } // 校驗 const isLt2M = file.size / 1024 / 1024 < 5; if (!isLt2M) { this.$message.error("上傳圖片大小不能超過 5MB!"); this.removeUploadedFile(type); // 不符合要求刪除文件 return false; } const isImage = file.raw.type.includes("image"); if (!isImage) { this.$message.error("上傳的格式必須是圖片!"); this.removeUploadedFile(type); return false; } // 驗證經過以後,將緩存區文件存入上傳區文件中 this.formData.files[type] = file.raw; }, // 從緩存區移除文件 removeUploadedFile(type) { if (type === 0) { this.$refs.file1.clearFiles(); } if (type === 1) { this.$refs.file2.clearFiles(); } if (type === 2) { this.$refs.file3.clearFiles(); } } // 刪除文件 handleRemove(file, fileList, type) { // 刪除文件時要移除緩存區文件和上傳區文件 this.fileList[type] = 0; this.uploadFile[type] = []; }, // 上傳文件 submitData() { // 校驗是否選擇文件 let fileNum = this.flatten(this.uploadFile).length; if (fileNum === 0) { this.$error("未選擇任何文件!"); return false; } // 使用formdata格式 let formData = new FormData(); if (this.formData.files[0]) { formData.append("file1", this.formData.files[0]); } if (this.formData.files[1]) { formData.append("file2", this.formData.files[1]); } if (this.formData.files[2]) { formData.append("file2", this.formData.files[2]); } // 請求:在headers上務必加上content-Type,指定表單形式發送 axios .post("uploadUrl", formData, {headers: { "Content-Type": "multipart/form-data" }}) .then(res => { this.$success("上傳圖片成功!"); this.fileList = [0,0,0]; this.uploadFile =[[],[],[]]; }) .catch(e => { console.log(e); }); } // 扁平化數組 flatten(arr) { let res = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { res = res.concat(this.flatten(arr[i])); } else { res.push(arr[i]); } } return res; }
multipartform-data相關知識element-ui
vue-lazy-laod
和vue-clazy-load
同一時間對服務器的請求過多,將會形成瀏覽器阻塞。
瀏覽器默認對同一域下的資源,只保持必定的鏈接數,阻塞過多的鏈接,以提升訪問速度和解決阻塞問題。axios
對於請求圖片來講,有如下解決方法數組
<img :src="imageUrl" ref="img">
// 方式一:延遲加載非可視區域 delayTime() { let windowHeight = window.innerHeight; let imgTop = this.$refs.img.getBoundingClientRect().top; const isDelay = imgTop > windowHeight; if (isDelay) { return Math.random() * 2000 + 3000; } else { return Math.random() * 2000 + 500; } } // 方法二:按順序依次延遲加載 delayTime() { if (this.params.index) { return Math.random() * 2000 + this.params.index * this.params.type * 500; } else { return 0; } } setTimeout(() => { // 圖片請求代碼 }, this.delayTime);
使用延時加載前的請求
瀏覽器
使用延時加載後的請求
緩存
[1] XMLHttpRequest Standard.The responseType attribute
[2] XMLHttpRequest.responseType | MDN
[3] 理解DOMString、Document、FormData、Blob、File、ArrayBuffer數據類型 « 張鑫旭-鑫空間-鑫生活
[4] FormData 對象的使用 | MDN
[5] 前端|加載的圖片太多或者太大怎麼辦(上) - u012496505的博客 - CSDN博客
[6] Lazy Loading Images and Video | Web Fundamentals | Google Developers
[7] An Introduction to Progressive Image Rendering
[8] 原生 JS 實現最簡單的圖片懶加載 - WEB前端 - 伯樂在線
2019/1/14 9:15:33