視頻批量上傳

接下來項目中的一個功能是視頻批量上傳,前期作調研寫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,本身寫一個簡單的表格形式

       

相關文章
相關標籤/搜索