«

Avue+vue2实现大型文件切片上传

时间:2024-3-14 18:08     作者:小诸葛     分类: Vue     正在检查是否收录...


1.Avue配置项avue-crud中需要添加文件上传前函数

<avue-crud
:upload-before="uploadBefore"
>
</avue-crud>

2.工具函数代码

// 引入axios进行http请求
import axios from "axios";
// 异步函数Fileslicing,用于处理文件的分片上传
async function Fileslicing(vueInstance, file, done, loading, column) {
  let _this = vueInstance; // 将vue实例保存在_this中,用于后续引用
  const CHUNK_SIZE = 1 * 1024 * 1024; // 定义每个分片的大小为1MB
  // const CHUNK_SIZE = 512 * 1024; // 或定义分片大小为500KB
  const totalChunks = Math.ceil(file.size / CHUNK_SIZE); // 计算总的分片数量
  let uploadedChunks = 0; // 已上传分片的计数器
  const overallStartTime = performance.now(); // 记录开始上传的时间

  // 循环处理每个分片
  for (let index = 0; index < totalChunks; index++) {
    const start = index * CHUNK_SIZE; // 计算当前分片的起始位置
    const end = Math.min(start + CHUNK_SIZE, file.size); // 计算结束位置,确保不超出文件大小
    const blob = file.slice(start, end); // 从文件中切割出当前分片
    // 创建一个新的文件对象用于上传,包含当前分片内容
    const chunkFile = new File([blob], `${file.name}-${index}`, {
      type: file.type,
    });
    const formData = new FormData(); // 使用FormData上传分片
    formData.append("file", chunkFile); // 添加当前分片
    formData.append("chunkNumber", index); // 当前分片的序号
    formData.append("totalChunks", totalChunks); // 总分片数
    formData.append("fileName", file.name); // 原文件名

    try {
      // 发起分片上传请求
      const response = await axios.post(
        "/api/blade-resource/oss/endpoint/chunk",
        formData,
        {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        }
      );
      uploadedChunks++; // 上传成功后,已上传分片数+1
      // 计算并显示上传进度
      const progressPercentage = ((uploadedChunks / totalChunks) * 100).toFixed(2);
      // 显示上传进度的通知
      vueInstance.$notify.info({
        title: "进度",
        message: `当前上传进度: ${progressPercentage}%`,
      });
      if(progressPercentage == 100){
          // 如果上传进度达到100%,显示文件上传完成的通知
          vueInstance.$notify({
            type: 'success',
            title: "通知",
            message: `文件已上传完成!正在处理中请稍等......`,
          });
      }

      // 如果当前分片是最后一个分片
      if (index === totalChunks - 1) {
        // 发起合并文件的请求
        const fileData = {
          fileName: file.name,
          totalChunks: totalChunks,
        };
        const Stresponse = await axios.post(
          "/api/blade-resource/oss/endpoint/mergeFile",
          fileData,
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        if (Stresponse.data.code === 200) {
          // 如果文件合并成功
          const overallEndTime = performance.now(); // 记录操作结束时间
          // 计算总耗时
          const totalFunctionTime = (overallEndTime - overallStartTime) / 1000;
          column.tip = ``; // 可根据需要进行操作
          let url = (Stresponse.data.data.domain + '/' + Stresponse.data.data.name);
          _this.form.videoUrl = url; // 更新vue实例中的视频URL
          loading(); // 可能是结束加载状态的函数
          // 显示上传成功的消息
          vueInstance.$message.success(
            `上传成功:文件名:${file.name},文件大小${(file.size / (1024 * 1024)).toFixed(2)} MB, 上传进度: ${progressPercentage}%,总耗时:${totalFunctionTime.toFixed(2)}秒`
          );
        } else {
          // 如果文件合并失败
          loading();
          vueInstance.$message.error("文件合并失败");
        }
      }
    } catch (error) {
      // 如果上传过程中出现错误
      vueInstance.$message.error("上传出错");
      loading(); // 结束加载状态
      return; // 停止执行
    }
  }
}

// 导出Fileslicing函数,使其在Vue实例中可用
export default {
    install(Vue) {
      Vue.prototype.$fileslicing = Fileslicing;
    },
};

3.注册全局,在main.js中引入

import FileslicingPlugin from '../src/util/Fileslicing';
Vue.use(FileslicingPlugin);

4.页面使用

    Avue文件上传前函数
     uploadBefore(file, done, loading, column) {
      this.$fileslicing(this,file,done,loading,column);//文件切换全局函数(初始)
      },

Avue+vue2实现大型文件切片上传 文件切片上传 vue切片上传

推荐阅读:


扫描二维码,在手机上阅读