From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 28 五月 2025 16:48:52 +0800 Subject: [PATCH] 初始化项目 --- uview-ui/components/u-upload/u-upload.vue | 660 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 660 insertions(+), 0 deletions(-) diff --git a/uview-ui/components/u-upload/u-upload.vue b/uview-ui/components/u-upload/u-upload.vue new file mode 100644 index 0000000..e58bb65 --- /dev/null +++ b/uview-ui/components/u-upload/u-upload.vue @@ -0,0 +1,660 @@ +<template> + <view class="u-upload" v-if="!disabled"> + <view + v-if="showUploadList" + class="u-list-item u-preview-wrap" + v-for="(item, index) in lists" + :key="index" + :style="{ + width: $u.addUnit(width), + height: $u.addUnit(height) + }" + > + <view + v-if="deletable" + class="u-delete-icon" + @tap.stop="deleteItem(index)" + :style="{ + background: delBgColor + }" + > + <u-icon class="u-icon" :name="delIcon" size="20" :color="delColor"></u-icon> + </view> + <u-line-progress + v-if="showProgress && item.progress > 0 && !item.error" + :show-percent="false" + height="16" + class="u-progress" + :percent="item.progress" + ></u-line-progress> + <view @tap.stop="retry(index)" v-if="item.error" class="u-error-btn">鐐瑰嚮閲嶈瘯</view> + <image @tap.stop="doPreviewImage(item.url || item.path, index)" class="u-preview-image" v-if="!item.isImage" :src="item.url || item.path" :mode="imageMode"></image> + </view> + <slot name="file" :file="lists"></slot> + <view style="display: inline-block;" @tap="selectFile" v-if="maxCount > lists.length"> + <slot name="addBtn"></slot> + <view + v-if="!customBtn" + class="u-list-item u-add-wrap" + hover-class="u-add-wrap__hover" + hover-stay-time="150" + :style="{ + width: $u.addUnit(width), + height: $u.addUnit(height) + }" + > + <u-icon name="plus" class="u-add-btn" size="40"></u-icon> + <view class="u-add-tips">{{ uploadText }}</view> + </view> + </view> + </view> +</template> + +<script> +/** + * upload 鍥剧墖涓婁紶 + * @description 璇ョ粍浠剁敤浜庝笂浼犲浘鐗囧満鏅� + * @tutorial https://www.uviewui.com/components/upload.html + * @property {String} action 鏈嶅姟鍣ㄤ笂浼犲湴鍧� + * @property {String Number} max-count 鏈�澶ч�夋嫨鍥剧墖鐨勬暟閲忥紙榛樿99锛� + * @property {Boolean} custom-btn 濡傛灉闇�瑕佽嚜瀹氫箟閫夋嫨鍥剧墖鐨勬寜閽紝璁剧疆涓簍rue锛堥粯璁alse锛� + * @property {Boolean} show-progress 鏄惁鏄剧ず杩涘害鏉★紙榛樿true锛� + * @property {Boolean} disabled 鏄惁鍚敤(鏄剧ず/绉讳粨)缁勪欢锛堥粯璁alse锛� + * @property {String} image-mode 棰勮鍥剧墖绛夋樉绀烘ā寮忥紝鍙�夊�间负uni鐨刬mage鐨刴ode灞炴�у�硷紙榛樿aspectFill锛� + * @property {String} del-icon 鍙充笂瑙掑垹闄ゅ浘鏍囧悕绉帮紝鍙兘涓簎View鍐呯疆鍥炬爣 + * @property {String} del-bg-color 鍙充笂瑙掑叧闂寜閽殑鑳屾櫙棰滆壊 + * @property {String | Number} index 鍦ㄥ悇涓洖璋冧簨浠朵腑鐨勬渶鍚庝竴涓弬鏁拌繑鍥烇紝鐢ㄤ簬鍖哄埆鏄摢涓�涓粍浠剁殑浜嬩欢 + * @property {String} del-color 鍙充笂瑙掑叧闂寜閽浘鏍囩殑棰滆壊 + * @property {Object} header 涓婁紶鎼哄甫鐨勫ご淇℃伅锛屽璞″舰寮� + * @property {Object} form-data 涓婁紶棰濆鎼哄甫鐨勫弬鏁� + * @property {String} name 涓婁紶鏂囦欢鐨勫瓧娈靛悕锛屼緵鍚庣鑾峰彇浣跨敤锛堥粯璁ile锛� + * @property {Array<String>} size-type original 鍘熷浘锛宑ompressed 鍘嬬缉鍥撅紝榛樿浜岃�呴兘鏈夛紙榛樿['original', 'compressed']锛� + * @property {Array<String>} source-type 閫夋嫨鍥剧墖鐨勬潵婧愶紝album-浠庣浉鍐岄�夊浘锛宑amera-浣跨敤鐩告満锛岄粯璁や簩鑰呴兘鏈夛紙榛樿['album', 'camera']锛� + * @property {Boolean} preview-full-image 鏄惁鍙互閫氳繃uni.previewImage棰勮宸查�夋嫨鐨勫浘鐗囷紙榛樿true锛� + * @property {Boolean} multiple 鏄惁寮�鍚浘鐗囧閫夛紝閮ㄥ垎瀹夊崜鏈哄瀷涓嶆敮鎸侊紙榛樿true锛� + * @property {Boolean} deletable 鏄惁鏄剧ず鍒犻櫎鍥剧墖鐨勬寜閽紙榛樿true锛� + * @property {String Number} max-size 閫夋嫨鍗曚釜鏂囦欢鐨勬渶澶уぇ灏忥紝鍗曚綅B(byte)锛岄粯璁や笉闄愬埗锛堥粯璁umber.MAX_VALUE锛� + * @property {Array<Object>} file-list 榛樿鏄剧ず鐨勫浘鐗囧垪琛紝鏁扮粍鍏冪礌涓哄璞★紝蹇呴』鎻愪緵url灞炴�� + * @property {Boolean} upload-text 閫夋嫨鍥剧墖鎸夐挳鐨勬彁绀烘枃瀛楋紙榛樿鈥滈�夋嫨鍥剧墖鈥濓級 + * @property {Boolean} auto-upload 閫夋嫨瀹屽浘鐗囨槸鍚﹁嚜鍔ㄤ笂浼狅紝瑙佷笂鏂硅鏄庯紙榛樿true锛� + * @property {Boolean} show-tips 鐗规畩鎯呭喌涓嬫槸鍚﹁嚜鍔ㄦ彁绀簍oast锛岃涓婃柟璇存槑锛堥粯璁rue锛� + * @property {Boolean} show-upload-list 鏄惁鏄剧ず缁勪欢鍐呴儴鐨勫浘鐗囬瑙堬紙榛樿true锛� + * @event {Function} on-oversize 鍥剧墖澶у皬瓒呭嚭鏈�澶у厑璁稿ぇ灏� + * @event {Function} on-preview 鍏ㄥ睆棰勮鍥剧墖鏃惰Е鍙� + * @event {Function} on-remove 绉婚櫎鍥剧墖鏃惰Е鍙� + * @event {Function} on-success 鍥剧墖涓婁紶鎴愬姛鏃惰Е鍙� + * @event {Function} on-change 鍥剧墖涓婁紶鍚庯紝鏃犺鎴愬姛鎴栬�呭け璐ラ兘浼氳Е鍙� + * @event {Function} on-error 鍥剧墖涓婁紶澶辫触鏃惰Е鍙� + * @event {Function} on-progress 鍥剧墖涓婁紶杩囩▼涓殑杩涘害鍙樺寲杩囩▼瑙﹀彂 + * @event {Function} on-uploaded 鎵�鏈夊浘鐗囦笂浼犲畬姣曡Е鍙� + * @event {Function} on-choose-complete 姣忔閫夋嫨鍥剧墖鍚庤Е鍙戯紝鍙槸璁╁閮ㄥ彲浠ュ緱鐭ユ瘡娆¢�夋嫨鍚庯紝鍐呴儴鐨勬枃浠跺垪琛� + * @example <u-upload :action="action" :file-list="fileList" ></u-upload> + */ +export default { + name: 'u-upload', + props: { + //鏄惁鏄剧ず缁勪欢鑷甫鐨勫浘鐗囬瑙堝姛鑳� + showUploadList: { + type: Boolean, + default: true + }, + // 鍚庣鍦板潃 + action: { + type: String, + default: '' + }, + // 鏈�澶т笂浼犳暟閲� + maxCount: { + type: [String, Number], + default: 52 + }, + // 鏄惁鏄剧ず杩涘害鏉� + showProgress: { + type: Boolean, + default: true + }, + // 鏄惁鍚敤 + disabled: { + type: Boolean, + default: false + }, + // 棰勮涓婁紶鐨勫浘鐗囨椂鐨勮鍓ā寮忥紝鍜宨mage缁勪欢mode灞炴�т竴鑷� + imageMode: { + type: String, + default: 'aspectFill' + }, + // 澶撮儴淇℃伅 + header: { + type: Object, + default() { + return {}; + } + }, + // 棰濆鎼哄甫鐨勫弬鏁� + formData: { + type: Object, + default() { + return {}; + } + }, + // 涓婁紶鐨勬枃浠跺瓧娈靛悕 + name: { + type: String, + default: 'file' + }, + // 鎵�閫夌殑鍥剧墖鐨勫昂瀵�, 鍙�夊�间负original compressed + sizeType: { + type: Array, + default() { + return ['original', 'compressed']; + } + }, + sourceType: { + type: Array, + default() { + return ['album', 'camera']; + } + }, + // 鏄惁鍦ㄧ偣鍑婚瑙堝浘鍚庡睍绀哄叏灞忓浘鐗囬瑙� + previewFullImage: { + type: Boolean, + default: true + }, + // 鏄惁寮�鍚浘鐗囧閫夛紝閮ㄥ垎瀹夊崜鏈哄瀷涓嶆敮鎸� + multiple: { + type: Boolean, + default: true + }, + // 鏄惁灞曠ず鍒犻櫎鎸夐挳 + deletable: { + type: Boolean, + default: true + }, + // 鏂囦欢澶у皬闄愬埗锛屽崟浣嶄负byte + maxSize: { + type: [String, Number], + default: Number.MAX_VALUE + }, + // 鏄剧ず宸蹭笂浼犵殑鏂囦欢鍒楄〃 + fileList: { + type: Array, + default() { + return []; + } + }, + // 涓婁紶鍖哄煙鐨勬彁绀烘枃瀛� + uploadText: { + type: String, + default: '閫夋嫨鍥剧墖' + }, + // 鏄惁鑷姩涓婁紶 + autoUpload: { + type: Boolean, + default: true + }, + // 鏄惁鏄剧ずtoast娑堟伅鎻愮ず + showTips: { + type: Boolean, + default: true + }, + // 鏄惁閫氳繃slot鑷畾涔変紶鍏ラ�夋嫨鍥炬爣鐨勬寜閽� + customBtn: { + type: Boolean, + default: false + }, + // 鍐呴儴棰勮鍥剧墖鍖哄煙鍜岄�夋嫨鍥剧墖鎸夐挳鐨勫尯鍩熷搴� + width: { + type: [String, Number], + default: 200 + }, + // 鍐呴儴棰勮鍥剧墖鍖哄煙鍜岄�夋嫨鍥剧墖鎸夐挳鐨勫尯鍩熼珮搴� + height: { + type: [String, Number], + default: 200 + }, + // 鍙充笂瑙掑叧闂寜閽殑鑳屾櫙棰滆壊 + delBgColor: { + type: String, + default: '#fa3534' + }, + // 鍙充笂瑙掑叧闂寜閽殑鍙夊彿鍥炬爣鐨勯鑹� + delColor: { + type: String, + default: '#ffffff' + }, + // 鍙充笂瑙掑垹闄ゅ浘鏍囧悕绉帮紝鍙兘涓簎View鍐呯疆鍥炬爣 + delIcon: { + type: String, + default: 'close' + }, + // 濡傛灉涓婁紶鍚庣殑杩斿洖鍊间负json瀛楃涓诧紝鏄惁鑷姩杞琷son + toJson: { + type: Boolean, + default: true + }, + // 涓婁紶鍓嶇殑閽╁瓙锛屾瘡涓枃浠朵笂浼犲墠閮戒細鎵ц + beforeUpload: { + type: Function, + default: null + }, + // 绉婚櫎鏂囦欢鍓嶇殑閽╁瓙 + beforeRemove: { + type: Function, + default: null + }, + // 鍏佽涓婁紶鐨勫浘鐗囧悗缂� + limitType:{ + type: Array, + default() { + // 鏀粯瀹濆皬绋嬪簭鐪熸満閫夋嫨鍥剧墖鐨勫悗缂�涓�"image" + // https://opendocs.alipay.com/mini/api/media-image + return ['png', 'jpg', 'jpeg', 'webp', 'gif', 'image']; + } + }, + // 鍦ㄥ悇涓洖璋冧簨浠朵腑鐨勬渶鍚庝竴涓弬鏁拌繑鍥烇紝鐢ㄤ簬鍖哄埆鏄摢涓�涓粍浠剁殑浜嬩欢 + index: { + type: [Number, String], + default: '' + } + }, + mounted() {}, + data() { + return { + lists: [], + isInCount: true, + uploading: false + }; + }, + watch: { + fileList: { + immediate: true, + handler(val) { + val.map(value => { + // 棣栧厛妫�鏌ュ唴閮ㄦ槸鍚﹀凡缁忔坊鍔犺繃杩欏紶鍥剧墖锛屽洜涓哄閮ㄧ粦瀹氫簡涓�涓璞$粰fileList鐨勮瘽(瀵硅薄寮曠敤)锛岃繘琛屼慨鏀瑰閮╢ileList + // 鏃讹紝浼氳Е鍙憌atch锛屽鑷撮噸鏂版妸鍘熸潵鐨勫浘鐗囧啀娆℃坊鍔犲埌this.lists + // 鏁扮粍鐨剆ome鏂规硶鎰忔�濇槸锛屽彧瑕佹暟缁勫厓绱犳湁浠绘剰涓�涓厓绱犳潯浠剁鍚堬紝灏辫繑鍥瀟rue锛岃�屽彟涓�涓暟缁勭殑every鏂规硶鐨勬剰鎬濇槸鏁扮粍鎵�鏈夊厓绱犻兘绗﹀悎鏉′欢鎵嶈繑鍥瀟rue + let tmp = this.lists.some(val => { + return val.url == value.url; + }) + // 濡傛灉鍐呴儴娌℃湁杩欎釜鍥剧墖(tmp涓篺alse)锛屽垯娣诲姞鍒板唴閮� + !tmp && this.lists.push({ url: value.url, error: false, progress: 100 }); + }); + } + }, + // 鐩戝惉lists鐨勫彉鍖栵紝鍙戝嚭浜嬩欢 + lists(n) { + this.$emit('on-list-change', n, this.index); + } + }, + methods: { + // 娓呴櫎鍒楄〃 + clear() { + this.lists = []; + }, + // 閲嶆柊涓婁紶闃熷垪涓笂浼犲け璐ョ殑鎵�鏈夋枃浠� + reUpload() { + this.uploadFile(); + }, + // 閫夋嫨鍥剧墖 + selectFile() { + if (this.disabled) return; + const { name = '', maxCount, multiple, maxSize, sizeType, lists, camera, compressed, maxDuration, sourceType } = this; + let chooseFile = null; + const newMaxCount = maxCount - lists.length; + // 璁剧疆涓哄彧閫夋嫨鍥剧墖鐨勬椂鍊欎娇鐢� chooseImage 鏉ュ疄鐜� + chooseFile = new Promise((resolve, reject) => { + uni.chooseImage({ + count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1, + sourceType: sourceType, + sizeType, + success: resolve, + fail: reject + }); + }); + chooseFile + .then(res => { + let file = null; + let listOldLength = this.lists.length; + res.tempFiles.map((val, index) => { + // 妫�鏌ユ枃浠跺悗缂�鏄惁鍏佽锛屽鏋滀笉鍦╰his.limitType鍐咃紝灏变細杩斿洖false + if(!this.checkFileExt(val)) return ; + + // 濡傛灉鏄潪澶氶�夛紝index澶т簬绛変簬1鎴栬�呰秴鍑烘渶澶ч檺鍒舵暟閲忔椂锛屼笉澶勭悊 + if (!multiple && index >= 1) return; + if (val.size > maxSize) { + this.$emit('on-oversize', val, this.lists, this.index); + this.showToast('瓒呭嚭鍏佽鐨勬枃浠跺ぇ灏�'); + } else { + if (maxCount <= lists.length) { + this.$emit('on-exceed', val, this.lists, this.index); + this.showToast('瓒呭嚭鏈�澶у厑璁哥殑鏂囦欢涓暟'); + return; + } + lists.push({ + url: val.path, + progress: 0, + error: false, + file: val + }); + } + }); + // 姣忔鍥剧墖閫夋嫨瀹岋紝鎶涘嚭涓�涓簨浠讹紝骞跺皢褰撳墠鍐呴儴閫夋嫨鐨勫浘鐗囨暟缁勬姏鍑哄幓 + this.$emit('on-choose-complete', this.lists, this.index); + if (this.autoUpload) this.uploadFile(listOldLength); + }) + .catch(error => { + this.$emit('on-choose-fail', error); + }); + }, + // 鎻愮ず鐢ㄦ埛娑堟伅 + showToast(message, force = false) { + if (this.showTips || force) { + uni.showToast({ + title: message, + icon: 'none' + }); + } + }, + // 璇ユ柟娉曚緵鐢ㄦ埛閫氳繃ref璋冪敤锛屾墜鍔ㄤ笂浼� + upload() { + this.uploadFile(); + }, + // 瀵瑰け璐ョ殑鍥剧墖閲嶆柊涓婁紶 + retry(index) { + this.lists[index].progress = 0; + this.lists[index].error = false; + this.lists[index].response = null; + uni.showLoading({ + title: '閲嶆柊涓婁紶' + }); + this.uploadFile(index); + }, + // 涓婁紶鍥剧墖 + async uploadFile(index = 0) { + if (this.disabled) return; + if (this.uploading) return; + // 鍏ㄩ儴涓婁紶瀹屾垚 + if (index >= this.lists.length) { + this.$emit('on-uploaded', this.lists, this.index); + return; + } + // 妫�鏌ユ槸鍚︽槸宸蹭笂浼犳垨鑰呮鍦ㄤ笂浼犱腑 + if (this.lists[index].progress == 100) { + if (this.autoUpload == false) this.uploadFile(index + 1); + return; + } + // 鎵цbefore-upload閽╁瓙 + if(this.beforeUpload && typeof(this.beforeUpload) === 'function') { + // 鎵ц鍥炶皟锛屽悓鏃朵紶鍏ョ储寮曞拰鏂囦欢鍒楄〃褰撲綔鍙傛暟 + // 鍦ㄥ井淇★紝鏀粯瀹濈瓑鐜(H5姝e父)锛屼細瀵艰嚧鐖剁粍浠跺畾涔夌殑customBack()鍑芥暟浣撲腑鐨則his鍙樻垚瀛愮粍浠剁殑this + // 閫氳繃bind()鏂规硶锛岀粦瀹氱埗缁勪欢鐨則his锛岃this.customBack()鐨則his涓虹埗缁勪欢鐨勪笂涓嬫枃 + // 鍥犱负upload缁勪欢鍙兘浼氳宓屽鍦ㄥ叾浠栫粍浠跺唴锛屾瘮濡倁-form锛岃繖鏃秚his.$parent鍏跺疄涓簎-form鐨則his锛� + // 闈為〉闈㈢殑this锛屾墍浠ヨ繖閲岄渶瑕佸線涓婂巻閬嶏紝涓�鐩村鎵惧埌鏈�椤剁鐨�$parent锛岃繖閲岀敤浜唗his.$u.$parent.call(this) + // 鏄庣櫧鎰忔�濆嵆鍙紝鏃犻渶绾犵粨this.$u.$parent.call(this)鐨勭粏鑺� + let beforeResponse = this.beforeUpload.bind(this.$u.$parent.call(this))(index, this.lists); + // 鍒ゆ柇鏄惁杩斿洖浜唒romise + if (!!beforeResponse && typeof beforeResponse.then === 'function') { + let error = false; + await beforeResponse.then(res => { + // promise杩斿洖鎴愬姛锛屼笉杩涜鍔ㄤ綔锛岀户缁笂浼� + }).catch(err => { + // 杩涘叆catch鍥炶皟鐨勮瘽锛岀户缁笅涓�寮� + // return this.uploadFile(index + 1); + // 鍦� cache 涓� return 鍙槸杩斿洖鏈柟娉曪紝骞朵笉鏄繑鍥� uploadFile 鏂规硶锛岄渶瑕佸湪澶栧眰杩涜杩斿洖 ThinkGem + error = true; + }) + if (error){ + return this.uploadFile(index + 1); + } + } else if(beforeResponse === false) { + // 濡傛灉杩斿洖false锛岀户缁笅涓�寮犲浘鐗囩殑涓婁紶 + return this.uploadFile(index + 1); + } else { + // 姝ゅ涓鸿繑鍥�"true"鐨勬儏褰紝杩欓噷涓嶅啓浠g爜锛屽氨璺宠繃姝ゅ锛岀户缁墽琛屽綋鍓嶇殑涓婁紶閫昏緫 + } + } + // 妫�鏌ヤ笂浼犲湴鍧� + if (!this.action) { + this.showToast('璇烽厤缃笂浼犲湴鍧�', true); + return; + } + this.lists[index].error = false; + this.uploading = true; + // 鍒涘缓涓婁紶瀵硅薄 + const task = uni.uploadFile({ + url: this.action, + filePath: this.lists[index].url, + name: this.name, + formData: this.formData, + header: this.header, + success: res => { + // 鍒ゆ柇鏄惁json瀛楃涓诧紝灏嗗叾杞负json鏍煎紡 + let data = this.toJson && this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data; + if (![200, 201, 204].includes(res.statusCode)) { + this.uploadError(index, data); + } else { + // 涓婁紶鎴愬姛 + this.lists[index].response = data; + this.lists[index].progress = 100; + this.lists[index].error = false; + this.$emit('on-success', data, index, this.lists, this.index); + } + }, + fail: e => { + this.uploadError(index, e); + }, + complete: res => { + uni.hideLoading(); + this.uploading = false; + this.uploadFile(index + 1); + this.$emit('on-change', res, index, this.lists, this.index); + } + }); + task.onProgressUpdate(res => { + if (res.progress > 0) { + this.lists[index].progress = res.progress; + this.$emit('on-progress', res, index, this.lists, this.index); + } + }); + }, + // 涓婁紶澶辫触 + uploadError(index, err) { + this.lists[index].progress = 0; + this.lists[index].error = true; + this.lists[index].response = null; + this.$emit('on-error', err, index, this.lists, this.index); + this.showToast('涓婁紶澶辫触锛岃閲嶈瘯'); + }, + // 鍒犻櫎涓�涓浘鐗� + deleteItem(index) { + uni.showModal({ + title: '鎻愮ず', + content: '鎮ㄧ‘瀹氳鍒犻櫎姝ら」鍚楋紵', + success: async (res) => { + if (res.confirm) { + // 鍏堟鏌ユ槸鍚︽湁瀹氫箟before-remove绉婚櫎鍓嶉挬瀛� + // 鎵цbefore-remove閽╁瓙 + if(this.beforeRemove && typeof(this.beforeRemove) === 'function') { + // 姝ゅ閽╁瓙鎵ц 鍘熺悊鍚宐efore-remove鍙傛暟锛岃涓婃柟娉ㄩ噴 + let beforeResponse = this.beforeRemove.bind(this.$u.$parent.call(this))(index, this.lists); + // 鍒ゆ柇鏄惁杩斿洖浜唒romise + if (!!beforeResponse && typeof beforeResponse.then === 'function') { + await beforeResponse.then(res => { + // promise杩斿洖鎴愬姛锛屼笉杩涜鍔ㄤ綔锛岀户缁笂浼� + this.handlerDeleteItem(index); + }).catch(err => { + // 濡傛灉杩涘叆promise鐨剅eject锛岀粓姝㈠垹闄ゆ搷浣� + this.showToast('宸茬粓姝㈢Щ闄�'); + }) + } else if(beforeResponse === false) { + // 杩斿洖false锛岀粓姝㈠垹闄� + this.showToast('宸茬粓姝㈢Щ闄�'); + } else { + // 濡傛灉杩斿洖true锛屾墽琛屽垹闄ゆ搷浣� + this.handlerDeleteItem(index); + } + } else { + // 濡傛灉涓嶅瓨鍦╞efore-remove閽╁瓙锛� + this.handlerDeleteItem(index); + } + } + } + }); + }, + // 鎵ц绉婚櫎鍥剧墖鐨勫姩浣滐紝涓婃柟浠g爜鍙槸鍒ゆ柇鏄惁鍙互绉婚櫎 + handlerDeleteItem(index) { + // 濡傛灉鏂囦欢姝e湪涓婁紶涓紝缁堟涓婁紶浠诲姟锛岃繘搴﹀湪0 < progress < 100鍒欐剰鍛崇潃姝e湪涓婁紶 + if (this.lists[index].process < 100 && this.lists[index].process > 0) { + typeof this.lists[index].uploadTask != 'undefined' && this.lists[index].uploadTask.abort(); + } + this.lists.splice(index, 1); + this.$forceUpdate(); + this.$emit('on-remove', index, this.lists, this.index); + this.showToast('绉婚櫎鎴愬姛'); + }, + // 鐢ㄦ埛閫氳繃ref鎵嬪姩鐨勫舰寮忥紝绉婚櫎涓�寮犲浘鐗� + remove(index) { + // 鍒ゆ柇绱㈠紩鐨勫悎娉曡寖鍥� + if (index >= 0 && index < this.lists.length) { + this.lists.splice(index, 1); + this.$emit('on-list-change', this.lists, this.index); + } + }, + // 棰勮鍥剧墖 + doPreviewImage(url, index) { + if (!this.previewFullImage) return; + const images = this.lists.map(item => item.url || item.path); + uni.previewImage({ + urls: images, + current: url, + success: () => { + this.$emit('on-preview', url, this.lists, this.index); + }, + fail: () => { + uni.showToast({ + title: '棰勮鍥剧墖澶辫触', + icon: 'none' + }); + } + }); + }, + // 鍒ゆ柇鏂囦欢鍚庣紑鏄惁鍏佽 + checkFileExt(file) { + // 妫�鏌ユ槸鍚﹀湪鍏佽鐨勫悗缂�涓� + let noArrowExt = false; + // 鑾峰彇鍚庣紑鍚� + let fileExt = ''; + const reg = /.+\./; + // 濡傛灉鏄疕5锛岄渶瑕佷粠name涓垽鏂� + // #ifdef H5 + fileExt = file.name.replace(reg, "").toLowerCase(); + // #endif + // 闈濰5锛岄渶瑕佷粠path涓鍙栧悗缂� + // #ifndef H5 + fileExt = file.path.replace(reg, "").toLowerCase(); + // #endif + // 浣跨敤鏁扮粍鐨剆ome鏂规硶锛屽彧瑕佺鍚坙imitType涓殑涓�涓紝灏辫繑鍥瀟rue + noArrowExt = this.limitType.some(ext => { + // 杞负灏忓啓 + return ext.toLowerCase() === fileExt; + }) + if(!noArrowExt) this.showToast(`涓嶅厑璁搁�夋嫨${fileExt}鏍煎紡鐨勬枃浠禶); + return noArrowExt; + } + } +}; +</script> + +<style lang="scss" scoped> +@import '../../libs/css/style.components.scss'; + +.u-upload { + @include vue-flex; + flex-wrap: wrap; + align-items: center; +} + +.u-list-item { + width: 200rpx; + height: 200rpx; + overflow: hidden; + margin: 10rpx; + background: rgb(244, 245, 246); + position: relative; + border-radius: 10rpx; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + align-items: center; + justify-content: center; +} + +.u-preview-wrap { + border: 1px solid rgb(235, 236, 238); +} + +.u-add-wrap { + flex-direction: column; + color: $u-content-color; + font-size: 26rpx; +} + +.u-add-tips { + margin-top: 20rpx; + line-height: 40rpx; +} + +.u-add-wrap__hover { + background-color: rgb(235, 236, 238); +} + +.u-preview-image { + display: block; + width: 100%; + height: 100%; + border-radius: 10rpx; +} + +.u-delete-icon { + position: absolute; + top: 10rpx; + right: 10rpx; + z-index: 10; + background-color: $u-type-error; + border-radius: 100rpx; + width: 44rpx; + height: 44rpx; + @include vue-flex; + align-items: center; + justify-content: center; +} + +.u-icon { + @include vue-flex; + align-items: center; + justify-content: center; +} + +.u-progress { + position: absolute; + bottom: 10rpx; + left: 8rpx; + right: 8rpx; + z-index: 9; + width: auto; +} + +.u-error-btn { + color: #ffffff; + background-color: $u-type-error; + font-size: 20rpx; + padding: 4px 0; + text-align: center; + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 9; + line-height: 1; +} +</style> -- Gitblit v1.9.3