iview-上传组件

416 阅读1分钟

iview框架自带了upload上传组件,但是感觉:default-file-list属性用起来比较麻烦,自己改写了一下。用uploadList来展示上传的图片,外部传进来的图片就用urlList,然后监听urlList,有数据变化就更新uploadList,初始化的时候也把urlList的值作为uploadList的初始值。

要注意的是上传成功后抛出uploadList,我在父组件处又更新了值

    onUploadChange (data) {
      this.formValidate.floorImgsList[data.index].imgUrl = data.list[0]
    },

这导致传入uploader组件的props值被改变了,我在父组件传值给子组件(image-uploader)的时候又把这个url值传给了子组件

    <image-uploader
        @upload-change="onUploadChange"
        :isDisEdit="isDisEdit"
        :remark="index"
        :urlList="[formValidate.floorImgsList[index].imgUrl]"
        >
    </image-uploader>

实际意义上变成了双向流动的数据,又触发了watch监听,刚开始做的时候没有注意到这一点,觉得奇怪怎么upladList的值连续变了2次。

做完这些之后,我觉得或许用原来的upload组件也可以实现,无非就是组装一下defaultList...

完整代码为: /imageUploader.vue

<template>
  <div class="">
    <div class="" style="display:flex;">
      <div class="upload-list" v-for="(item,index) in uploadList">
        <img :src="item">
        <div class="upload-list-cover">
          <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
          <Icon type="ios-trash-outline" v-if="!isDisEdit" @click.native="handleRemove(index)"></Icon>
        </div>
      </div>
      <div v-show="loading" class="spin-container">
        <Spin fix></Spin>
      </div>

      <Upload
        ref="upload"
        type="drag"
        v-show="this.uploadList.length < this.size && !isDisEdit"
        :show-upload-list="false"
        :action="uploadUrl"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :format="['jpg','jpeg','png','bmp', 'gif']"
        :max-size="5120"
        :on-format-error="handleFormatError"
        :on-exceeded-size="handleMaxSize"
        :before-upload="handleBeforeUpload"
        style="display: inline-block;width:58px;"
        >
        <div style="width: 58px;height:58px;line-height: 58px;">
          <Icon type="ios-camera" size="20"></Icon>
        </div>
      </Upload>
    </div>


    <Modal title="图片" v-model="visible">
      <img :src="imgSrc" v-if="visible" style="width: 100%">
    </Modal>
  </div>
</template>

<script>
import { uploadUrl } from '@/view/appDeploy/utils'

export default {
  name: 'image-uploader',
  props: {
    size: {
      type: Number,
      default: 1
    },
    isDisEdit: {
      type: Boolean,
      default: false
    },
    remark: {
      type: Number,
      default: 0
    },
    urlList: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data () {
    return {
      uploadUrl: uploadUrl,
      visible: false,
      loading: false,
      uploadList: this.urlList.filter(i=>!!i)
    }
  },

  watch: {
    urlList(newval,oldval) {
      this.uploadList = this.urlList.filter(i => !!i)
    }
  },

  methods: {
    handleView (imgSrc) {
      this.imgSrc = imgSrc;
      this.visible = true;
    },
    handleRemove (index) {
      this.uploadList.splice(index,1)
      this.$emit('upload-change',{list: this.uploadList, index:this.remark})
    },
		handleUploadSuccess(res, file, list) {
      this.loading = false
      this.uploadList.push(res.data)
      this.$emit('upload-change',{list: this.uploadList, index:this.remark})
		},
		handleUploadError(res, file, list) {
      this.loading = false
			console.log('handleUploadError', res, file, list)
		},
    handleFormatError(file) {
			this.$Notice.warning({
        title: '格式错误',
        desc: file.name + ' 格式不支持, 请上传bmp,jpg,png,gif格式图片'
      });
		},
		handleMaxSize (file) {
      this.$Notice.warning({
        title: '文件大小超出范围',
          desc: file.name + ' 文件太大了, 请不要超出5M'
      });
    },
    handleBeforeUpload () {
      const check = this.uploadList.length < this.size;
      if (!check) {
        this.$Notice.warning({
          title: `只能上传 ${this.size} 张图片`
        });
      }else {
        this.loading = true
      }
      return check;
    }
  }
}
</script>

<style lang="css" scoped>
.upload-list{
    display: inline-block;
    width: 60px;
    height: 60px;
    text-align: center;
    line-height: 60px;
    border: 1px solid transparent;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    position: relative;
    box-shadow: 0 1px 1px rgba(0,0,0,.2);
    margin-right: 4px;
}
.upload-list img{
    width: 100%;
    height: 100%;
}
.upload-list-cover{
    display: none;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0,0,0,.6);
}
.upload-list:hover .upload-list-cover{
    display: block;
}
.upload-list-cover i{
    color: #fff;
    font-size: 20px;
    cursor: pointer;
    margin: 0 2px;
}
.spin-container{
	display: inline-block;
  width: 60px;
  height: 60px;
  position: relative;
  border: 1px solid #eee;
}

</style>