Vue使用Input大文件上传切片、修改file文件上传控件样式、清空已选择文件

前言:

最近重构公司项目核心内容就是大文件的上传功能,文件基本上都是几个G的,着手的是原生的input标签file,
大文件我们首先考虑到一个分片上传这样的功能我们先来说一说分片的好处
好处: 分片上传的好处是将一个大请求分成多个小请求来执行,这样当其中一些请求失败后,不需要重新上传整个文件,而只需要上传失败的分片就可以了 .
可想而知如果不分片会造成文件的丢失,下一次上传从新开始上传,极大的浪费资源一方面给用户体验也不是很好
CSS样式:
修改前:修改前是和其他表单共用的弹窗
在这里插入图片描述
修改后:这里是另外单独的弹窗把上传事件加到确定事件上了

在这里插入图片描述

技术栈:

框架Vue2.0+Ant Design Vue组件库

代码展示:

template中

  <a-modal
    title="文件上传"
    :width="900"
    :visible="visible"
    :confirmLoading="confirmLoading"
    okText="点击上传文件"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
  <!-- UI组件库的加载效果 -->
    <a-spin :spinning="confirmLoading"> 
      <a-row>
        <a-col :span="12" :offset="6">
          <a-form :form="form" :label-col="{ span: 7 }" :wrapper-col="{ span: 10 }" has-feedback>
            <a-form-item label="模型压缩包" :label-col="{ span: 7 }" :wrapper-col="{ span: 10 }">
              <div class="ipts">
                请选择模型压缩包<input
                  v-if="!cancel_img"
                  type="file"
                  id="file"
                  name="file"
                  class="uploads"
                  @change="handleFiles"
                />
              </div>
              <!-- 文件上传的名称 -->
              <div class="fileInfo">{{ filesName }}</div>
            </a-form-item>
          </a-form>
        </a-col>
      </a-row>
    </a-spin>
  </a-modal>

script中

export default {
  data() {
    return {
      filesName: '', //获取上传文件的名称
      cancel_img: '',
      tton: 0,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
      // 机构行样式
      labelCol_JG: {
        xs: { span: 24 },
        sm: { span: 3 },
      },
      wrapperCol_JG: {
        xs: { span: 24 },
        sm: { span: 20 },
      },
    }
  },
  methods: {
    // 获取上传文件的名称
    handleFiles(event) {
      this.filesName = event.target.files[0].name
    },
    save() {
      // 每个文件切片大小定为1M(1024*1024字节)(需要跟服务器协商好)
      var BYTES_PER_SLICE = (1 << 20) * 100 //这里定义的是每个包分的是100MB
      // 已发送的数量
      var hasSendNum = 0
      // 总切片数
      var totalSlices
      this.tton == 1
      this.confirmLoading = true //loading加载
      // 拿出选中的第一个文件
      var file = document.getElementById('file').files[0]
      // 文件的总字节数
      var totalSize = file.size
      // 当前片数
      var index = 0
      // 分片的开始、结束(不含)
      var start, end
      // 文件名
      var fileName = file.name
      // 初始化已发送数量为0
      hasSendNum = 0
      // 计算文件切片总数(向上取整)
      totalSlices = Math.ceil(file.size / BYTES_PER_SLICE)
      // 不断循环将切片上传
      while (index < totalSlices) {
        start = index * BYTES_PER_SLICE
        end = start + BYTES_PER_SLICE
        var slice = file.slice(start, end) //切割文件
        this.handleChangeupload(slice, index++, fileName, totalSlices, totalSize)
      }
    },
    handleChangeupload(slice, index, fileName, totalSlices, totalSize) {
      var retry = 1
      var FormDate = new FormData()
      FormDate.append('totalSlices', totalSlices) //总数
      FormDate.append('index', index) //当前数
      FormDate.append('totalSize', totalSize) //字节数
      FormDate.append('filename', fileName) //文件名
      FormDate.append('file', slice) //文件流
      addThreeDUrl(FormDate).then((res) => {//调用上传接口
        if (res.code == 200) {
          this.$message.success('上传成功')
          this.confirmLoading = false //关闭loading加载
          this.visible = false //关闭弹窗
          //nextTick 函数是在下一次dom更新后回调,
          //这就可以实现先执行的上面的代码,让input[file]节点消失,
          //然后再dom更新后回调该函数,又执行了让input[file]节点显示,这样就实现了刷新
          this.cancel_img = true
          this.$nextTick(() => {
            this.cancel_img = false
          })
          this.filesName = '' //清除上传文件名称
        } else {
          this.$message.console.error('上传失败')
          this.confirmLoading = false //关闭loading加载
        }
      })
    },
    // 点击上传文件按钮
    handleSubmit() {
      if (this.filesName != '') {
        this.save()
      } else {
        this.$message.error('请选择模型压缩包再点击上传')
      }
    },
    // 取消按钮
    handleCancel() {
      this.cancel_img = true
      this.$nextTick(() => {
        this.cancel_img = false
      })
      this.filesName = '' //清除上传文件名称
      this.visible = false
    },
  },
}

CSS样式

.ipts {
  width: 210px;
  height: 128px;
  padding: 4px 10px;
  line-height: 127px;
  position: relative;
  border: 1px solid #999;
  text-decoration: none;
  color: #333;
  background-color: #fafafa;
  text-align: center;
  border: 1px dashed #999;
  border-radius: 5px;
  cursor: pointer;
}
.uploads {
  position: absolute;
  overflow: hidden;
  right: 0;
  top: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}

注意:请求接口只能用POST 切记不能用GET

商务插播:网站 清悠业务网
每天签到奖励现金哦!
快来和我一起领取吧!
网址:点击跳转
每天免费领取2000名片赞
建议收藏网站可天天领取

总结:

以上就是所有内容和代码,欢迎大家指教



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张清悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值