上傳組件封裝需求分析
在基于elementUI庫做的商城后臺管理中,需求最大的是商品管理表單這塊,因為需要錄入各種各樣的商品圖片信息。加上后臺要求要傳遞小于2M的圖片,因此封裝了一個upload.vue組件作為上傳頁面的子組件,它用于管理圖片上傳邏輯。
upload.vue解析
upload主要用于實現表單上傳圖片的需求,主要由input +img 構成當沒有圖片的時候顯示默認圖片,有圖片則顯示上傳圖片,因為input樣式不太符合需求所以只是將起設置為不可見,不能將其設置為display:none。否則將將無法觸發input的change事件
upload.vue代碼如下:
<template> <div> <div class="upload-box" :style="imgStyle"> <!-- 用戶改變圖片按鈕的點擊 觸發上傳圖片事件 --> <input type="file" :ref="imgType$1" @change="upload(formVal$1,imgType$1)" class="upload-input" /> <!-- img 的 src 用于渲染一個 圖片路徑 傳入圖片路徑 渲染出圖片 --> <img :src="formVal$1[imgType$1]?formVal$1[imgType$1]:'static/img/upload.jpg'" /> </div> </div></template><script>/* 該組件因為要上傳多個屬性的圖片 主圖(mainImg) 詳細圖(detailImg) 規格圖 (plusImg) 該組件基于壓縮插件lrz,所以下方打入該組件 npm install lrz --save 即可*/import lrz from 'lrz';export default { name: 'uploadImg', //組件名字 props: { formVal: { type: Object, //props接受對象類型數據(表單對象也可以是純對象類型) required: true, default: {} }, imgType: { //表單對象中的圖片屬性 example:mainImg type: String, required: true, default: '' }, imgStyle: { type: Object, // 用于顯示的圖片的樣式 required: true //必須傳遞 } }, created: function() { //生命周期函數 }, data: function() { /* 因為該組件需要改變父組件傳遞過來的值, 所以將起拷貝一份 */ let formVal$1 = this.formVal; let imgType$1 = this.imgType; return { formVal$1, imgType$1, uploadUrl: url,//你的服務器url地址 }; }, methods: { upload: function(formVal, imgType) { var self = this; //圖片上傳加載我們在這里加入提示,下方需要主動關閉,防止頁面卡死 var loadingInstance = this.$loading({ text: '上傳中' }); var that = this.$refs[imgType].files[0]; //文件壓縮file //圖片上傳路徑 var testUrl = this.uploadUrl; //圖片上傳路徑 try { //lrz用法和上一個一樣也是一個壓縮插件來的 lrz(that) .then(function(message) { var formData = message.formData; //壓縮之后我們拿到相應的formData上傳 self.$axios .post(testUrl, formData) .then(function(res) { console.log(res); if (res && res.data.iRet == 0) { formVal[imgType] = res.data.objData.sUrl; //上傳成功之后清掉數據防止下次傳相同圖片的時候不觸發change事件 self.$refs[imgType].value = ''; /* 這里因為使用elementUI中的表單驗證, 當上傳圖片完成之后還會提示沒有上傳圖片 所以需要通知父組件清除該驗證標記 */ self.$emit('clearValidate', imgType); self.$nextTick(() => { // 以服務的方式調用的 Loading 需要異步關閉 loadingInstance.close(); }); } else { throw res.data.sMsg; } }) .catch(function(err) { self.$nextTick(() => { // 以服務的方式調用的 Loading 需要異步關閉 loadingInstance.close(); }); //接口報錯彈出提示 alert(err); }); }) .catch(function(err) { self.$nextTick(() => { loadingInstance.close(); }); }); } catch (e) { //關閉加載動畫實例 self.$nextTick(() => { loadingInstance.close(); }); } } }, mounted: function() {}, watch: { /* 這里需要注意當父組件上傳一個圖片然后通過重置按鈕重置的時候. 我們需要監聽一下,防止上傳同一張圖片上傳失敗 */ formVal: { handle: function(newVal, oldVal) { var imgType = this.imgType; if (newVal[imgType] == '') { //這里使用了原生js寫法當然也可以通過ref引用找到,后者更好 document.getElementsByClassName('upload-input')[0].value = ''; } } } }};</script><style scoped>/* 這里是默認的設置圖片的尺寸。可以通過父組件傳值將其覆蓋*/.upload-box { position: relative; height: 100px; width: 100px; overflow: hidden;}.upload-box img { width: 100%; height: 100%;}.upload-box .upload-input { position: absolute; left: 0; opacity: 0; width: 100%; height: 100%;}</style>
新聞熱點
疑難解答
圖片精選