zoukankan      html  css  js  c++  java
  • element ui实现手动上传文件,且只能上传单个文件,并能覆盖上传

    element ui提供了成熟的组件场景,但实际工作中难免会遇到认(sha)真(diao)的产品。比如,最近遇到的,要求实现手动上传特定格式文件(用户点击“上传文件”按钮,确定之后,只是单纯选择了文件,点击页面上的“提交”按钮才上传),并展示用户选择的文件名称,且只能选择一个文件,如果用户选择第2,3,4...等文件,要求后者覆盖前者,即用户看到的总是最新选择的文件。

      OK,需求合理,但是,查了查API,呃。。。貌似不太好完美实现。

      查源码,改样式。完美奉上解决方案。

    一,实际应用场景

          实现手动上传特定格式的文件,展示所选文件名称,且能实现覆盖上传

    二,分析

          1, 解决手动上传问题

               官网API(https://element.eleme.cn/#/zh-CN/component/upload),给出“手动上传”,只需要在Upload组件添加 属性  :auto-upload="false" ,然后调用  this.$refs.upload.submit(); 方法即可。

          2,解决特定格式文件问题

                这块,也有例子,对于本项目,要求添加txt格式或者csv格式, 所以,Upload组件添加 属性 accept=".txt,.csv"

          3,最麻烦的是上传限制问题

                首先想到官网API里的 limit属性, Upload组件添加属性 :limit="1",但是这样,无聊怎么选择文件,页面上展示的始终是第一次选择的文件,这效果和我想的大相径庭。

                              

               “单身限制了你的想象力”

                继续翻,看到file-list属性,保存的是用户选择的文件数组。 

                             

        想通过on-change方法,改变file-list里选择的文件列表,只保留最后一项。逻辑上来说行得通。

                代码如下:

                      模板代码(已精简):                          

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <template>
      <div>
          <el-upload
             class="upload-demo"
             ref="upload"       // 注意1
             accept=".csv"      // 注意2
             :file-list="fileList"  // 注意3
             :on-change="handleChange"  // 注意4
             :action="uploadUrl" 
             :show-file-list="true"
             :on-success="onSuccess"
             :on-error="onError"
             :auto-upload="false"  // 注意5
           >
             <el-button type="primary" slot="trigger">选取文件</el-button>
           </el-upload>
           <el-button type="primary" @click="handleSubmit">提交</el-button>
        </div>
    </template>

                script代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <script>
        export default {
            name: 'Upload',
            data() {
                fileList: [],
                uploadUrl: ''
            },
         methods: {
              onSuccess(res) {
                    this.$alert(res.data, '提示', {
                        confirmButtonText: '确定',
                        callback: action => {
                          console.log("上传成功")
                        },
                   })
                },
              onError(res) {
                    this.$alert('创建失败''提示', {
                        confirmButtonText: '确定',
                        callback: action => {
                           console.log("上传失败")
                        },
                    })
                 },
                 handleChange(file, fileList) {
                     if (fileList.length > 0) {
                         this.fileList = [fileList[fileList.length - 1]]  // 这一步,是 展示最后一次选择的csv文件
                     }
                 },
                submit() {<br>                 this.uploadUrl = '/upload'  // 这里,读者换成实际项目中的上传接口
                     this.$nextTick(() => {
                         this.$refs.upload.submit()
                     })
                 },
             },
        }
    </script>

      到这里,基本功能上实现了目标场景,但是有一个样式问题,因为是认为改变file-list,取最后一项,因此,用户选择第二个文件后,从第一个文件到第二个文件,有动态切换的效果,这不是我想要的,我想要的是 用户点击“上传文件”,本地电脑 选择文件,点击“确定”,页面上直接展示所选文件,不要动态切换。 

          鼓捣很久(省略很多字),翻看element upload组件的css源码。 

         

          去掉这一部分动画,完美解决。

         css代码如下: 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style lang="scss" scoped>
        .upload-demo {
          display: flex;
        }
        /deep/ .el-list-enter-active,
        /deep/ .el-list-leave-active {
          transition: none;
        }
     
        /deep/ .el-list-enter,
        /deep/ .el-list-leave-active {
          opacity: 0;
        }
        /deep/ .el-upload-list {
          height: 40px;
        }
    </style>

       至于css中的 /deep/ 是干嘛的,其实是修改elementui等第三方组件内部样式,做的渗透。如果不用scss, 可以使用 >>> 符号来修改第三方组件内部样式。

    三,总结

      “什么都不懂的时候,我曾拥有全部。”

          本文思路,从 踩过的坑 到解决问题,耗时许久,如需转载,请标明出处,感谢配合。

          还是同样的ps,每次用element ui 都会有一些感触,

          苦笑。

    转自:https://www.cnblogs.com/lovemomo/p/11777608.html

  • 相关阅读:
    React.render和reactDom.render的区别
    CSS中position的4种定位详解
    React.js入门必须知道的那些事
    JS处理事件小技巧
    React.js深入学习详细解析
    React.js实现原生js拖拽效果及思考
    Linux ./configure && make && make install 编译安装和卸载
    Redis set集合结构及命令详解
    Redis数据过期策略
    Redis TTL命令
  • 原文地址:https://www.cnblogs.com/ccv2/p/13550240.html
Copyright © 2011-2022 走看看