You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							306 lines
						
					
					
						
							7.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							306 lines
						
					
					
						
							7.0 KiB
						
					
					
				
								<template>
							 | 
						|
								  <view class="uni-file-picker__container">
							 | 
						|
								    <view class="file-picker__box" v-for="(url, index) in list" :key="index" :style="boxStyle">
							 | 
						|
								      <view class="file-picker__box-content" :style="borderStyle">
							 | 
						|
								        <image
							 | 
						|
								          class="file-image"
							 | 
						|
								          :src="getImageUrl(url)"
							 | 
						|
								          mode="aspectFill"
							 | 
						|
								          @click.stop="previewImage(url, index)"
							 | 
						|
								        ></image>
							 | 
						|
								        <view v-if="delIcon && !readonly" class="icon-del-box" @click.stop="delFile(index)">
							 | 
						|
								          <view class="icon-del"></view>
							 | 
						|
								          <view class="icon-del rotate"></view>
							 | 
						|
								        </view>
							 | 
						|
								        <!-- <view v-if="item.errMsg" class="file-picker__mask" @click.stop="uploadFiles(item, index)">
							 | 
						|
								          点击重试
							 | 
						|
								        </view> -->
							 | 
						|
								      </view>
							 | 
						|
								    </view>
							 | 
						|
								    <view v-if="list.length < limit && !readonly" class="file-picker__box" :style="boxStyle">
							 | 
						|
								      <view class="file-picker__box-content is-add" :style="borderStyle" @click="choose">
							 | 
						|
								        <slot>
							 | 
						|
								          <view class="icon-add"></view>
							 | 
						|
								          <view class="icon-add rotate"></view>
							 | 
						|
								        </slot>
							 | 
						|
								      </view>
							 | 
						|
								    </view>
							 | 
						|
								  </view>
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
								  import sheep from '@/sheep';
							 | 
						|
								  export default {
							 | 
						|
								    name: 'uploadImage',
							 | 
						|
								    emits: ['uploadFiles', 'choose', 'delFile'],
							 | 
						|
								    props: {
							 | 
						|
								      filesList: {
							 | 
						|
								        type: [Array, String],
							 | 
						|
								        default() {
							 | 
						|
								          return [];
							 | 
						|
								        },
							 | 
						|
								      },
							 | 
						|
								      disabled: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: false,
							 | 
						|
								      },
							 | 
						|
								      disablePreview: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: false,
							 | 
						|
								      },
							 | 
						|
								      limit: {
							 | 
						|
								        type: [Number, String],
							 | 
						|
								        default: 9,
							 | 
						|
								      },
							 | 
						|
								      imageStyles: {
							 | 
						|
								        type: Object,
							 | 
						|
								        default() {
							 | 
						|
								          return {
							 | 
						|
								            width: 'auto',
							 | 
						|
								            height: 'auto',
							 | 
						|
								            border: {},
							 | 
						|
								          };
							 | 
						|
								        },
							 | 
						|
								      },
							 | 
						|
								      delIcon: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: true,
							 | 
						|
								      },
							 | 
						|
								      readonly: {
							 | 
						|
								        type: Boolean,
							 | 
						|
								        default: false,
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								    computed: {
							 | 
						|
								      list() {
							 | 
						|
								        if (typeof this.filesList === 'string') {
							 | 
						|
								          if (this.filesList) {
							 | 
						|
								            return [this.filesList];
							 | 
						|
								          } else {
							 | 
						|
								            return [];
							 | 
						|
								          }
							 | 
						|
								        }
							 | 
						|
								        return this.filesList;
							 | 
						|
								      },
							 | 
						|
								      styles() {
							 | 
						|
								        let styles = {
							 | 
						|
								          width: 'auto',
							 | 
						|
								          height: 'auto',
							 | 
						|
								          border: {},
							 | 
						|
								        };
							 | 
						|
								        return Object.assign(styles, this.imageStyles);
							 | 
						|
								      },
							 | 
						|
								      boxStyle() {
							 | 
						|
								        const { width = 'auto', height = 'auto' } = this.styles;
							 | 
						|
								        let obj = {};
							 | 
						|
								        if (height === 'auto') {
							 | 
						|
								          if (width !== 'auto') {
							 | 
						|
								            obj.height = this.value2px(width);
							 | 
						|
								            obj['padding-top'] = 0;
							 | 
						|
								          } else {
							 | 
						|
								            obj.height = 0;
							 | 
						|
								          }
							 | 
						|
								        } else {
							 | 
						|
								          obj.height = this.value2px(height);
							 | 
						|
								          obj['padding-top'] = 0;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (width === 'auto') {
							 | 
						|
								          if (height !== 'auto') {
							 | 
						|
								            obj.width = this.value2px(height);
							 | 
						|
								          } else {
							 | 
						|
								            obj.width = '33.3%';
							 | 
						|
								          }
							 | 
						|
								        } else {
							 | 
						|
								          obj.width = this.value2px(width);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        let classles = '';
							 | 
						|
								        for (let i in obj) {
							 | 
						|
								          classles += `${i}:${obj[i]};`;
							 | 
						|
								        }
							 | 
						|
								        return classles;
							 | 
						|
								      },
							 | 
						|
								      borderStyle() {
							 | 
						|
								        let { border } = this.styles;
							 | 
						|
								        let obj = {};
							 | 
						|
								        const widthDefaultValue = 1;
							 | 
						|
								        const radiusDefaultValue = 3;
							 | 
						|
								        if (typeof border === 'boolean') {
							 | 
						|
								          obj.border = border ? '1px #eee solid' : 'none';
							 | 
						|
								        } else {
							 | 
						|
								          let width = (border && border.width) || widthDefaultValue;
							 | 
						|
								          width = this.value2px(width);
							 | 
						|
								          let radius = (border && border.radius) || radiusDefaultValue;
							 | 
						|
								          radius = this.value2px(radius);
							 | 
						|
								          obj = {
							 | 
						|
								            'border-width': width,
							 | 
						|
								            'border-style': (border && border.style) || 'solid',
							 | 
						|
								            'border-color': (border && border.color) || '#eee',
							 | 
						|
								            'border-radius': radius,
							 | 
						|
								          };
							 | 
						|
								        }
							 | 
						|
								        let classles = '';
							 | 
						|
								        for (let i in obj) {
							 | 
						|
								          classles += `${i}:${obj[i]};`;
							 | 
						|
								        }
							 | 
						|
								        return classles;
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								    methods: {
							 | 
						|
								      getImageUrl(url) {
							 | 
						|
								        if ('blob:http:' === url.substr(0, 10)) {
							 | 
						|
								          return url;
							 | 
						|
								        } else {
							 | 
						|
								          return sheep.$url.cdn(url);
							 | 
						|
								        }
							 | 
						|
								      },
							 | 
						|
								      uploadFiles(item, index) {
							 | 
						|
								        this.$emit('uploadFiles', item);
							 | 
						|
								      },
							 | 
						|
								      choose() {
							 | 
						|
								        this.$emit('choose');
							 | 
						|
								      },
							 | 
						|
								      delFile(index) {
							 | 
						|
								        this.$emit('delFile', index);
							 | 
						|
								      },
							 | 
						|
								      previewImage(img, index) {
							 | 
						|
								        let urls = [];
							 | 
						|
								        if (Number(this.limit) === 1 && this.disablePreview && !this.disabled) {
							 | 
						|
								          this.$emit('choose');
							 | 
						|
								        }
							 | 
						|
								        if (this.disablePreview) return;
							 | 
						|
								        this.list.forEach((i) => {
							 | 
						|
								          urls.push(this.getImageUrl(i));
							 | 
						|
								        });
							 | 
						|
								
							 | 
						|
								        uni.previewImage({
							 | 
						|
								          urls: urls,
							 | 
						|
								          current: index,
							 | 
						|
								        });
							 | 
						|
								      },
							 | 
						|
								      value2px(value) {
							 | 
						|
								        if (typeof value === 'number') {
							 | 
						|
								          value += 'px';
							 | 
						|
								        } else {
							 | 
						|
								          if (value.indexOf('%') === -1) {
							 | 
						|
								            value = value.indexOf('px') !== -1 ? value : value + 'px';
							 | 
						|
								          }
							 | 
						|
								        }
							 | 
						|
								        return value;
							 | 
						|
								      },
							 | 
						|
								    },
							 | 
						|
								  };
							 | 
						|
								</script>
							 | 
						|
								
							 | 
						|
								<style lang="scss">
							 | 
						|
								  .uni-file-picker__container {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    box-sizing: border-box;
							 | 
						|
								    /* #endif */
							 | 
						|
								    flex-wrap: wrap;
							 | 
						|
								    margin: -5px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__box {
							 | 
						|
								    position: relative;
							 | 
						|
								    // flex: 0 0 33.3%;
							 | 
						|
								    width: 33.3%;
							 | 
						|
								    height: 0;
							 | 
						|
								    padding-top: 33.33%;
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    box-sizing: border-box;
							 | 
						|
								    /* #endif */
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__box-content {
							 | 
						|
								    position: absolute;
							 | 
						|
								    top: 0;
							 | 
						|
								    right: 0;
							 | 
						|
								    bottom: 0;
							 | 
						|
								    left: 0;
							 | 
						|
								    margin: 5px;
							 | 
						|
								    border: 1px #eee solid;
							 | 
						|
								    border-radius: 5px;
							 | 
						|
								    overflow: hidden;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__progress {
							 | 
						|
								    position: absolute;
							 | 
						|
								    bottom: 0;
							 | 
						|
								    left: 0;
							 | 
						|
								    right: 0;
							 | 
						|
								    /* border: 1px red solid; */
							 | 
						|
								    z-index: 2;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__progress-item {
							 | 
						|
								    width: 100%;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-picker__mask {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    justify-content: center;
							 | 
						|
								    align-items: center;
							 | 
						|
								    position: absolute;
							 | 
						|
								    right: 0;
							 | 
						|
								    top: 0;
							 | 
						|
								    bottom: 0;
							 | 
						|
								    left: 0;
							 | 
						|
								    color: #fff;
							 | 
						|
								    font-size: 12px;
							 | 
						|
								    background-color: rgba(0, 0, 0, 0.4);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .file-image {
							 | 
						|
								    width: 100%;
							 | 
						|
								    height: 100%;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .is-add {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    align-items: center;
							 | 
						|
								    justify-content: center;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-add {
							 | 
						|
								    width: 50px;
							 | 
						|
								    height: 5px;
							 | 
						|
								    background-color: #f1f1f1;
							 | 
						|
								    border-radius: 2px;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .rotate {
							 | 
						|
								    position: absolute;
							 | 
						|
								    transform: rotate(90deg);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-del-box {
							 | 
						|
								    /* #ifndef APP-NVUE */
							 | 
						|
								    display: flex;
							 | 
						|
								    /* #endif */
							 | 
						|
								    align-items: center;
							 | 
						|
								    justify-content: center;
							 | 
						|
								    position: absolute;
							 | 
						|
								    top: 3px;
							 | 
						|
								    right: 3px;
							 | 
						|
								    height: 26px;
							 | 
						|
								    width: 26px;
							 | 
						|
								    border-radius: 50%;
							 | 
						|
								    background-color: rgba(0, 0, 0, 0.5);
							 | 
						|
								    z-index: 2;
							 | 
						|
								    transform: rotate(-45deg);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  .icon-del {
							 | 
						|
								    width: 15px;
							 | 
						|
								    height: 2px;
							 | 
						|
								    background-color: #fff;
							 | 
						|
								    border-radius: 2px;
							 | 
						|
								  }
							 | 
						|
								</style>
							 |