vue中大文件上传webuploader前端用法

首先呢需要安装webuploader;

命令:

npm i webuploader -S

下载完成以后在vue文件中引入

//引入webuploader
import WebUploader from "webuploader";
import "webuploader/dist/webuploader.css";

然后页面中需要有上传按钮和上传列表以及上传进度条的东西,首先写好dom页面中

<el-row class="webUploader">
    <el-col :span="24" class="mb20" :style="{ display: 'flex' }">
      <el-button
        class="selectFile"
        :disabled="disabled"
        type="primary"
        size="mini"
        ref="selectFile"
      >
        选择文件
      </el-button>
      <el-button
        @click="submitFile"
        :disabled="disabled"
        type="success"
        size="mini"
        >开始上传</el-button
      >
    </el-col>
    <el-col :span="24">
      <el-table :data="value" :disabled="disabled" size="mini">
        <el-table-column
          label="文件名"
          align="left"
          key="fileName"
          prop="fileName"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="大小"
          align="center"
          key="fileSize"
          prop="fileSize"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="进度"
          align="center"
          key="fileProgress"
          prop="fileProgress"
        >
          <template slot-scope="scope">
            <el-progress
              :text-inside="true"
              :stroke-width="16"
              :percentage="scope.row.fileProgress"
            ></el-progress>
          </template>
        </el-table-column>
        <el-table-column
          label="状态"
          align="center"
          key="fileStatus"
          prop="fileStatus"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="操作"
          align="center"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-video-play"
              @click="resume(scope.row.file)"
              v-hasPermi="['system:user:edit']"
              :disabled="scope.row.fileStatus === '上传成功'"
              >开始</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-video-pause"
              @click="stop(scope.row.file)"
              :disabled="scope.row.fileStatus === '上传成功'"
              v-hasPermi="['system:user:remove']"
              >暂停</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              :disabled="disabled"
              @click="remove(scope.row, scope.$index)"
              v-hasPermi="['system:user:resetPwd']"
              >移除</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-video-camera"
              @click="imgLook(scope.row.fileId)"
              :disabled="scope.row.fileStatus !== '上传成功'"
              v-hasPermi="['system:user:resetPwd']"
              >预览</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-col>
  </el-row>

接下来是上传方法的使用,在vue中使用封装,源码如下

export default {
  name: "uploaderList",
  components: {},
  props: {
    accept: {
      type: [String, Object],
      default: null
    },
    // 上传地址
    url: {
      type: String,
      default: "url"
    },
    // 上传最大数量 默认为100
    fileNumLimit: {
      type: Number,
      default: 100
    },
    // 大小限制 默认2M
    fileSingleSizeLimit: {
      type: Number,
      default: 5120000
    },
    fileType: {
      type: String,
      default: "knowledge"
    },
    // 上传时传给后端的参数,一般为token,key等
    formData: {
      type: Object,
      default: () => {
        return { guid: null, code: 9 };
      }
    },
    // 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议
    keyGenerator: {
      type: Function,
      default: () => `${new Date().getTime()}`
    },
    multiple: {
      type: Boolean,
      default: true
    },
    // 上传按钮ID
    uploadButton: {
      type: String,
      default: ""
    },
    value: {
      type: Array,
      default: () => []
    },
    disabled: {
      type: Boolean,
      default: () => false
    }
  },
  data() {
    return {
      uploader: null
    };
  },
  watch: {
    disabled(newVal) {
      if (newVal) {
        this.uploader.destroy();
        return false;
      }
      this.initWebUpload();
    }
  },
  mounted() {
    if (!this.disabled) {
      this.initWebUpload();
    }
  },
  methods: {
    initWebUpload() {
      if (this.uploader) {
        this.uploader.destroy();
      }
      const uploader = (this.uploader = WebUploader.create({
        auto: false, // 选完文件后,是否自动上传
        // swf: '/static/lib/webuploader/Uploader.swf',  // swf文件路径
        server: this.url, // 文件接收服务端
        pick: {
          id: this.$refs.selectFile.$el, // 选择文件的按钮
          multiple: this.multiple // 是否多文件上传 默认false
        },
        accept: this.getAccept(this.accept), // 允许选择文件格式。
        threads: 3,
        fileNumLimit: this.fileNumLimit, // 限制上传个数
        //fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
        formData: this.formData, // 上传所需参数
        chunked: true, //分片上传
        chunkSize: 5120000, //分片大小
        duplicate: true // 重复上传
      }));
      const fun = [
        "fileQueued",
        "uploadStart",
        "uploadProgress",
        "uploadSuccess",
        "error"
      ];
      for (const item of fun) {
        uploader.on(item, this[item]);
      }
      return uploader;
    },
    // 当有文件被添加进队列的时候,添加到页面预览
    fileQueued(file) {
      const { name, size, id } = file;
      const obj = {
        id,
        fileName: name,
        fileSize: WebUploader.Base.formatSize(size),
        fileProgress: 0,
        fileStatus: "待上传",
        file
      };
      this.value.push(obj);
    },
    // 在这里可以准备好formData的数据
    uploadStart() {
      this.uploader.options.formData.guid = this.keyGenerator();
    },
    // 文件上传过程中创建进度条实时显示。
    uploadProgress(file, percentage) {
      const fileObj = this.value.find(obj => file.id == obj.id);
      fileObj.fileStatus = "上传中";
      fileObj.fileProgress = parseInt(percentage * 100);
      fileObj.file = file;
    },
    // 文件上传成功
    async uploadSuccess(file, res) {
      const fileObj = this.value.find(obj => file.id == obj.id);
      try {
        const { data } = await combine({
          guid: res.guid,
          fileName: file.name,
          fileType: this.fileType,
          code: res.code
        });
        fileObj.fileId = data.fileId;
        fileObj.fileStatus = "上传成功";
        this.$emit("input", this.value);
      } catch (err) {
        fileObj.fileProgress = 0;
        fileObj.fileStatus = "上传失败,请点击开始重新上传";
      }
    },
    error(type) {//报错信息
      let errorMessage = "";
      if (type === "F_EXCEED_SIZE") {
        errorMessage = `文件大小不能超过${this.fileSingleSizeLimit /
          (1024 * 1000)}M`;
      } else if (type === "Q_EXCEED_NUM_LIMIT") {
        errorMessage = "文件上传已达到最大上限数";
      } else {
        errorMessage = `上传出错!请检查后重新上传!错误代码${type}`;
      }
      console.error(errorMessage);
    },
    // 开始
    resume(file) {
      this.uploader.upload(file);
    },
    // 暂停
    stop(file) {
      file.fileStatus = "暂停中";
      this.uploader.stop(file);
    },
    // 移除
    async remove(row, idx) {
      const { fileId, file } = row;
      try {
        if (fileId) await delFileApi(fileId);
        this.value.splice(idx, 1);
        if (file) {
          // 取消并中断文件上传
          this.uploader.cancelFile(file);
          // 在队列中移除文件
          this.uploader.removeFile(file, true);
        }
        this.$emit("input", this.value);
      } catch (error) {}
    },
    // 预览
    imgLook(fileId) {
      if (!fileId) {
        return false;
      }
      lookImg(fileId).then(res => {
        const sourceImages = [];
        sourceImages.push({
          thumbnail:
            process.env.VUE_APP_BASE_API +
            this.profile +
            res.data.thumbnailFile,
          source:
            process.env.VUE_APP_BASE_API + this.profile + res.data.thumbnailFile
        });
        // console.log(sourceImages);
        this.$refs.viewer.show(sourceImages, 0);
      });
    },
      //上传文件格式
    getAccept(accept) {
      switch (accept) {
        case "text":
          return {
            title: "Texts",
            exteensions: "doc,docx,xls,xlsx,ppt,pptx,pdf,txt",
            mimeTypes: ".doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt"
          };
        case "video":
          return {
            title: "Videos",
            exteensions: "mp4",
            mimeTypes: ".mp4"
          };
        case "image":
          return {
            title: "Images",
            exteensions: "gif,jpg,jpeg,bmp,png,tif",
            mimeTypes: ".gif,.jpg,.jpeg,.bmp,.png,.tif"
          };
        default:
          return accept;
      }
    },
    submitFile() {
      this.uploader.upload();
    }
  }
};

封装完毕,在想用的地方使用

//引入
import UploaderList from "@/components/upload/uploadList.vue";
components: { UploaderList },
//使用
 <UploaderList
    v-model="imageList"
    :formData="{ guid: null, fileCategory: 1, code: 7 }"
    :fileType="'targetFacility'"
/>

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐