Element: <upload> 图片/文件上传组件的希望能够控制上传数量

Created on 6 Jan 2017  ·  19Comments  ·  Source: ElemeFE/element

因为很多场景中只需要上传一个文件或者一张图片。
带图片预览的上传框大部分情况下只需要上传一个文件。
upload组件能不能设置一个最大上传数量,默认是0代表不限制
如果上传的文件达到最大上传数量, 上传组件内的 继续上传 按钮就隐藏。

还有就是,带预览的上传组件里面的 查看图片 按钮能不能添加一个属性自行选择显示或者隐藏呀, 或者干脆再给一个 slot 让我们自定义里面的按钮好了

discussion feature request

Most helpful comment

给el-upload标签添加:on-change="handleChange"
然后添加方法:

handleChange(file, fileList){
      if(fileList.length>1){
        fileList.splice(0,1);
      }
    }

可以限制为只能选择一个文件,再选就会被覆盖,原理就是对fileList进行限制,其他功能或则逻辑改改应该也可以使用。

All 19 comments

@k55k32 ,我想改下上传的图标和提示信息,样式,应该怎么弄呢?

@598220654 现有的组件是不支持这样的功能的。 如果要做的话,就得自己封装一个组件了

@k55k32 那就是只能用他现有样式??

image
我们的项目也有这个需求;既要预览图片也要限制上传图片数量,还有好几个场景需要限制数量。
希望考虑加一下这个特性:)

数量限制:

        <el-upload
                        v-show="ruleForm.username?true:false"
                        class="upload-demo"
                        ref="upload"
                        list-type="picture-card"
                        action="https://jsonplaceholder.typicode.com/posts/"
                        :on-success="handleSuccess"
                        :file-list="fileList"
                        :auto-upload="false"
                        :disabled="count>1?true:false">

    export default {
        data() {
            return {
                fileList: [],
                count: 0    //数量控制,每次上传成功后触发on-success,count + 1,当count大于 1时,disabled为true, 达到限制效果
}
}

给el-upload标签添加:on-change="handleChange"
然后添加方法:

handleChange(file, fileList){
      if(fileList.length>1){
        fileList.splice(0,1);
      }
    }

可以限制为只能选择一个文件,再选就会被覆盖,原理就是对fileList进行限制,其他功能或则逻辑改改应该也可以使用。

@itimor 这种方法,有一个地方不行,就是disable后,这个唯一的文件不能删除。

@HobaiRiku 这种方法有个地方,就是添加文件、上传成功、上传失败都会运行

靠CSS解决了这个问题,思路是把上传按钮(?)藏到预览图片后面。这种做法的缺点是CSS不scoped,可能污染其他组件的样式

<template>
  <div class="uploader-wrapper">
    <el-upload list-type="picture-card" :limit="1" action="http://...">
      <i class="el-icon-plus"></i>
    </el-upload>
  </div>
</template>

<style lang="scss">
  .uploader-wrapper {
    >div {
      position: relative;
      min-width: 148px;
      height: 148px;
      ul.el-upload-list--picture-card>li {
        z-index: 999;
      }

      .el-upload--picture-card {
        position: absolute;
        top: 0;
        left: 0;
      }
    }
  }
</style>

我目前也是css解决的,当只需要上传一张图片时候,如果已经有一张图片了,就不让选择器出现:

.el-upload-list--picture-card:not(:empty) + .el-upload--picture-card {
  display: none;
}

@aweiu 有没有不污染全局的 CSS 方法,因为别的地方可能不止上传一张图片

我用的是是手动上传的照片墙组件。

el-upload里面绑定一个占位class:

:class="{hide:hideUpload}"

data里面初始值:

hideUpload: false,

onChange里面(添加文件、上传成功和上传失败时都会被调用的那个):

this.hideUpload = fileList.length >= this.limitCount;

handleRemove里面(删除文件被调用的那个):

this.hideUpload = fileList.length >= this.limitCount;

style,把scoped去掉:

<style>
.hide .el-upload--picture-card {
    display: none;
}
</style>
<template>
    <div class="page">
        <el-upload
            id="key"
            class="avatar-uploader region-item"
            action="string"
            list-type="picture-card"
            :http-request="uploadPic"
            :file-list="fileList"
            :on-error="handleAvatarError"
            :on-remove="handleRemove"
            :on-preview="handlePictureCardPreview"
            :before-upload="handleAvatarBeforeUpload">
            <i :class="{'avatar-uploader-icon': true, 'el-icon-plus': !isUploading, 'el-icon-loading': isUploading}"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible">
            <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
    </div>
</template>

handleChange(fileList) {
    const files = fileList ? fileList : this.fileList;
    const uploadPlus = document.getElementById('key').lastChild;
    if (files.length > this.limit) {
        uploadPlus.style.visibility = 'hidden';
    } else {
        uploadPlus.style.visibility = 'visible';
    }
}

思路:

  1. 把el-uploader封装成一个组件,由父组件传进来id,defaultImg, limit。ps:(1 防止在一个页面中多个引用,通过选择器找错dom 2 默认要显示的url 3 设置组件长度 )
  2. 每次上传或者删除图片,触发 handleChange 方法,判断数组长度,拿到upload中控制上传的dom,也就是👆代码中的 uploadPlus, 控制显示,隐藏

@lebuslebos
onChange里面(添加文件、上传成功和上传失败时都会被调用的那个):

this.hideUpload = fileList.length >= this.limitCount;

this.limitCount 哪里来的

这个功能确实有必要加上去,你都已经limit了,还把那个添加的按钮显示在那里完全多余.
我目前是这么处理的
packages/upload/src/upload.vue 第200行,在文件列表超限的时候就将后边这个元素display:none

 <div {...data} tabindex="0" style={(this.limit && this.fileList.length >= this.limit)?'display:none;':''} >

如果不想重编源码,也可以直接加两个针对文件列表发生改变时的监听on-change 和 on-remove,

 <el-upload ref="uploader"
           :action="uploadAction"
           :data="uploadData"
           list-type="picture-card"
           :limit='1'
           :before-upload="beforeUpload"
           :on-change="afterFileListChange"
           :on-remove="afterFileListChange"
>

然后下边

afterFileListChange:function(files, fileList){
    if(this.$refs.uploader.limit && fileList.length>=this.$refs.uploader.limit) {
      this.$refs.uploader.$el.querySelector(".el-upload").style.display='none'
    }else{
      this.$refs.uploader.$el.querySelector(".el-upload").style.display=null;
    }
  },

唯一有点尴尬的就是,当前一个删除的时候,后边这个元素显示出来的时候会因为前边元素的移开,会抖一下

if (this.Upload.fileList.length === 5) {
    this.$refs.upload.$children[1].$el.style.display = 'none'
 } else {
    this.$refs.upload.$children[1].$el.style.display = 'block'
 }

this.Upload.fileList 数组动态的维护就好了

给el-upload标签添加:on-change="handleChange"
然后添加方法:

handleChange(file, fileList){
      if(fileList.length>1){
        fileList.splice(0,1);
      }
    }

可以限制为只能选择一个文件,再选就会被覆盖,原理就是对fileList进行限制,其他功能或则逻辑改改应该也可以使用。

个人觉得这算是最简单的解决方案了

这个功能确实有必要加上去,你都已经limit了,还把那个添加的按钮显示在那里完全多余.
我目前是这么处理的
packages/upload/src/upload.vue 第200行,在文件列表超限的时候就将后边这个元素display:none

 <div {...data} tabindex="0" style={(this.limit && this.fileList.length >= this.limit)?'display:none;':''} >

如果不想重编源码,也可以直接加两个针对文件列表发生改变时的监听on-change 和 on-remove,

 <el-upload ref="uploader"
           :action="uploadAction"
           :data="uploadData"
           list-type="picture-card"
           :limit='1'
           :before-upload="beforeUpload"
           :on-change="afterFileListChange"
           :on-remove="afterFileListChange"
>

然后下边

afterFileListChange:function(files, fileList){
    if(this.$refs.uploader.limit && fileList.length>=this.$refs.uploader.limit) {
      this.$refs.uploader.$el.querySelector(".el-upload").style.display='none'
    }else{
      this.$refs.uploader.$el.querySelector(".el-upload").style.display=null;
    }
  },

唯一有点尴尬的就是,当前一个删除的时候,后边这个元素显示出来的时候会因为前边元素的移开,会抖一下
其实可以加个延时。。。六七百毫秒即可。。。

我师傅,真的太厉害了,之前看了好多解决办法,都没有我师傅这个好,简单快捷不说,特别容易理解,话不多说,上代码
整体思路: 外层的div设置宽高,然后overflow:hidden;当图片张数>limit时,多出的图片也会不显示,因为设置了固定高度。
<el-upload class="uploader-child-annex" :style="{'width': 'auto', 'max-width': 158 * max + 'px'}" :class="{'hide': disabled}" multiple :file-list="fileList" :action="action" list-type="picture-card" :limit="max" :http-request="httpRequest" :on-preview="handlePreview" :on-remove="handleMultiRemove" :on-success="handleMultiSuccess" :before-upload="beforeUpload"></el-upload>

.uploader-child-annex { overflow: hidden; height: 148px; }

真的超级简单,就这么就解决了,不影响增删修改

Was this page helpful?
0 / 5 - 0 ratings

Related issues

smallpath picture smallpath  ·  3Comments

dbskccc picture dbskccc  ·  3Comments

chao-hua picture chao-hua  ·  3Comments

no5no6 picture no5no6  ·  3Comments

chenzhe-pro picture chenzhe-pro  ·  3Comments