视频批量上传

接下来项目中的一个功能是视频批量上传,前期作调研写demo,发现这其中的逻辑还挺复杂的,没有想像中那么简单


一、点击选取视频按钮,选择上传的视频ios

<el-upload
  ref="upload"
  :show-file-list="false"
  action
  multiple
  :before-upload="beforeUpload"
  :http-request="devUpload">
  <el-button  slot="trigger" type="primary">选取视频</el-button>
</el-upload>
<el-dialog title="图片上传" :visible.sync="dialogVisible" :file-list="videoList" width="800px" @close="closeEvent">
  <div>
    <ul class="upload-box">
      <li>视频名称</li>
      <li>大小(MB)</li>
      <li>导入状态</li>
      <li>操做</li>
    </ul>
    <ul class="upload-box" v-for="(item, key) in videoList" :key="key">
      <li>{{item.name}}</li>
      <li>{{(item.size / (1024 * 1024)).toFixed(2)}}</li>
      <li>
        <el-progress v-if="item.status === 1" :text-inside="true" :stroke-width="20" :percentage="item.progress"></el-progress>
        <span v-if="item.status === 0">等待导入</span>
        <span v-if="item.status === 1">导入中</span>
        <span v-if="item.status === 2" @click="reUpload(item)">导入失败</span>
      </li>
      <li>
        <el-button type="text" @click="deleteBtn(item, key)">删除</el-button>
      </li>
    </ul>
  </div>
</el-dialog>复制代码

beforeUpload (file) {
  this.dialogVisible = true
  file.status = 0
  this.videoList.push(file)
},
devUpload () {},复制代码

二、弹窗显示,将视频信息展现在弹窗中,同时视频依次上传,上传进度由进度条展现element-ui

watch: {
  dialogVisible (val) {
    if (!val) {
      this.videoList = []
    } else {
      this.videoList[0].status = 1
      this.uploadEvent(this.videoList[0], 0)
    }
  },
count (val) {
  for (let i = 0; i < this.videoList.length; i++) {
    if (this.videoList[i].status === 0) {
      this.videoList[i].status = 1
      this.uploadEvent(this.videoList[i], i)
      break
    }
  }
}}复制代码

uploadEvent (file, i) {
  this.nowIndex = i
  let url = this.$baseUrl + '/upload/file'
  let fd = new FormData()
  fd.append('file', file)
  let that = this
  axios({
    url: url,
    method: 'post',
    data: fd,
    cancelToken: new axios.CancelToken(function executor (c) {
      // executor 函数接收一个 cancel 函数做为参数
      that.cancel = c
    }),
    onUploadProgress (progressEvent) {
      if (progressEvent.lengthComputable) {
        // 属性lengthComputable主要代表总共须要完成的工做量和已经完成的工做是否能够被测量
        // 若是lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
        let val = (progressEvent.loaded / progressEvent.total * 100).toFixed(0)
        var progress = parseInt(val)
        that.$forceUpdate()
        that.$set(that.videoList.filter(item => item.uid === file.uid)[0], 'progress', progress)
      }
    }
  }).then(res => {
    let self = this
    if (res.success) {
      this.$message('200')
      setTimeout(function () {
        self.videoList.splice(this.nowIndex, 1)
      }, 500)
    } else {
      self.$set(self.videoList[this.nowIndex], 'status', 2)
      this.$forceUpdate()
    }
  this.count++    this.cancel = null
  }).catch(error => {    console.log(error)  })复制代码

三、从新上传、删除、关闭弹窗axios

reUpload (item) {
  item.status = 0
  if (!this.cancel) {
    this.count++
  }
},
deleteBtn (item, key) {
  if (item.status === 1) {
    this.cancel()
    this.count++
    this.cancel = null
  }
  if (key < this.nowIndex) {
    this.nowIndex = this.nowIndex - 1
  }
  this.videoList.splice(key, 1)
},
closeEvent () {
  if (this.cancel) {
    this.cancel()
    this.cancel = null
  }
}复制代码

难点数组

  1. 将上传进度展现在进度条中,用$forceUpdate强制刷新数据和视图
  2. 由于没法监听到数组中对象的某一个属性,因此放弃了watch去监听数据,而是采用计数的方式去驱动事件
  3. 点击删除按钮时,终止发送的上传请求,用到了axios的axios.CancelToken
  4. 在element-ui的el-table中使用进度条时,进度没法实时展现,因此没有用el-table,本身写一个简单的表格形式

       

相关文章
相关标签/搜索