Vue:利用Plupload插件封装文件上传组件

    接上回《Plupload插件》,已经尝试将Plupload插件引入到HTML页面中,并进行参数配置,然后联合后端接口进行调试,完成了文件上传的工作。但是在Vue项目的开发中,我们更想将它封装成一个可复用的Vue组件,在使用的时候,只需要快捷引入,并配置参数与回调函数即可。
    有兴趣的小伙伴可以也可点击此处,从Gitee上直接拉取项目源码运行。

调用方式

    使用自定义的FileUploader组件时,调用方式如下。

<template>
  <div class="home">
    <!-- 文件上传组件 -->
    <FileUploader
      :url="url"
      :params="params"
      :mime_types="mimeTypes"
      :max_file_size="maxFileSizeLimit"
      @whenUpload="whenUpload"
      @successCallBackLater="uploadCallBack"
      @errorCallBackLater="errorCallBack"
    />
  </div>
</template>

<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'
//导出文件上传组件
import FileUploader from "@/components/fileTools/FileUploader";

export default {
  name: "home",
  components: {
    //注册组件
    FileUploader,
  },
  data() {
    return {
    //这里是后端接口-可参考前一篇文章的示例代码
      url: "http://localhost:8099/sci_web/upload",
      //params参数对应后端编写的JavaBean/pojo类对象+属性值
      params: {
        username: "小张",
        password: "258596",
        role: 0,
        state: 1,
      },
      mimeTypes: "image/*,audio/*,video/*,text/*,application/zip", //MIME类型-默认支持文本/图像/音视频/二进制压缩包
      maxFileSizeLimit: 1024,
    };
  },
  methods: {
  	//以下三个函数是暴露出来的回调函数接口
    whenUpload(msg) {
      console.log(msg);
    },
    uploadCallBack(uploader, file, responseObject) {
      console.log(responseObject);
    },
    errorCallBack(uploader, error) {
      console.log(error);
    },
  },
};
</script>

组件封装源码

FileUploader组件简介

    组件名称:FileUploader.vue,支持:多文件选择、已选文件移除、多文件分块上传,此外,也暴露出了如下3个接口,

        ①whenUpload:执行文件上传操作时的回调函数
        ②successCallBackLater:文件上传成功时的回调函数
        ③errorCallBackLater:文件上传发生错误时的回调函数。

在这里插入图片描述

图1-默认样式

在这里插入图片描述

图2-选择文件后的样式

在这里插入图片描述

图3-文件上传后的样式

    上图是组件示例(有点丑,样式可根据自己需要进行调整哈)。

FileUploader组件源码

以下部分是我在Plupload插件基础上封装好的Vue组件,源码如下。

<template>
  <div class="wrapper">
    <br />
    <div class="btns_group">
      <div class="select_file btn default" id="browse">选择文件</div>
      <div
        class="upload_btn btn success"
        id="start-upload"
        @click="startUpload"
      >
        开始上传
      </div>
      <div class="upload_btn btn success" id="start-upload" @click="clearFiles">
        重新选择
      </div>
    </div>
    <!-- <div class="horizen_splitLine"></div> -->
    <div class="selectedFiles">
      <!-- 动态渲染文件列表 -->
      <div class="file_row" v-for="(item, index) in fileList" :key="index">
        <img :src="require('@/assets/icons/file-icon.png')" />
        <span>{{ item.name }}</span>
        <span>{{ (item.size / 1024).toFixed(2) + "MB" }}</span>
        <span>{{ item.percent != 0 ? item.percent + "%" : "" }}</span>
      </div>
    </div>
  </div>
</template>
<script>
//导入plupload插件库
import plupload from "plupload";
export default {
	name:"FileUploader",
  props: [
    "url", //文件上传请求地址
    "mime_types", //要上传的文件类型
    "max_file_size", //单个文件大小上限
    "params", //除文件之外的附加参数
  ],

  data() {
    return {
      pluploadObj: undefined, //plupload文件上传插件对象
      fileList: [], //已选择的文件列表
    };
  },
  methods: {
    /**
     * 执行文件上传操作
     */
    startUpload() {
      this.pluploadObj && this.pluploadObj.files.length > 0
        ? this.pluploadObj.start()
        : this.$emit("whenUpload", { msg: "plupload happened error!" });
    },
    /**
     * 重新选择文件-清空文件列表
     */
    clearFiles() {
      if (this.pluploadObj && this.fileList && this.fileList.length > 0) {
        //清空文件列表
        let _that = this;
        this.fileList.some(function (value, index, array) {
          _that.pluploadObj.removeFile(value);
        });
        this.fileList.splice(0, this.fileList.length);
      }
    },
    /**
     * 文件上传成功时的回调函数
     *
     */
    callBack(uploader, file, responseObject) {
      //自定义事件-文件上传成功之后-接收服务器端返回值
      this.$emit("successCallBackLater", uploader, file, responseObject);
    },
    errorCallBack(uploader, error) {
      //自定义事件-文件上传发生错误时-自定义处理方式
      this.$emit("errorCallBackLater", uploader, error);
    },
  },
  mounted() {
    let _that = this;
    //plupload插件参数配置
    let pluploadConfig = {
      browse_button: "browse", //文件上传按钮
      url: this.$props.url, //文件请求接口
      filters: {
        //文件类型过滤器-默认支持所有文件类型
        mime_types: this.$props.mime_types
          ? this.$props.mime_types
          : "image/*,audio/*,video/*,text/*,application/zip",
        //单个文件大小定义
        max_file_size: this.$props.max_file_size
          ? this.$props.max_file_size + "mb"
          : "0", //默认0-无上限
        //防止文件重复选择
        prevent_duplicates: true, //default-false
        multipart: true, //default -true ,是否将文件作为 multipart/form-data (default) 或者binary stream上传
        drop_element: "browse", //拖拽方式选择文件
        multi_selection: true, //开启多文件上传
        unique_names: true, //为每个文件自动生成唯一名称-作为额外的参数post到服务器端,参数明为name,值为生成的文件名
        chunk_size: "1Mb", //文件分块大小
      },
      init: {
        //文件上传之前的回调函数
        BeforeUpload: function (up, files) {
          up.setOption("multipart_params", _that.$props.params);
        },
        //添加文件时的回调函数
        FilesAdded: function (up, files) {
          // var html = "";
          plupload.each(files, function (file) {
            //记录当前选中的文件-Vue组件自动刷新-无需定制
            _that.fileList.push(file);
          });
        },
        //文件上传时的进度条绑定
        UploadProgress: function (up, file) {
          //已经封装到Vue组件中-自动刷新-无须定制
        },
        /**
         * uploader为当前的plupload实例对象,file为触发此事件的文件对象,responseObject为服务器返回的信息对象,它有以下3个属性:
         *          response:服务器返回的文本
         *          responseHeaders:服务器返回的头信息
         *          status:服务器返回的http状态码,比如200
         */
        FileUploaded: function (uploader, file, responseObject) {
          //回调函数处理
          _that.callBack(uploader, file, responseObject);
        },
        //错误处理回调函数
        Error: function (up, err) {
          //回调函数处理
          _that.errorCallBack(up, err);
        },
      },
    };
    //初始化plupload插件
    this.pluploadObj = new plupload.Uploader(pluploadConfig);
    //调用初始化方法
    this.pluploadObj.init();
  },
};
</script>
<style scoped>
.wrapper {
  position: absolute;
  /* top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); */
  width: 350px;
  border: 1px solid #ccc;
  border-radius: 5%;
  background-color: #ffffff;
}
.default {
  background-color: #409eff;
}
.success {
  background-color: #67c23a;
}
.btn {
  color: #ffffff;
  padding: 5px;
  border: 1px solid #ccc;
  border-radius: 10%;
}
.btns_group {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}

div {
  cursor: pointer;
}

/* 文件上传列表样式 */
.filelist {
  list-style: none;
}
.selectedFiles {
  margin: 15px 5px;
  border-top: 1px solid #ccc;
}
.selectedFiles .file_row {
  padding: 10px 5px;
}
.selectedFiles img {
  margin-left: 5px;
}
.selectedFiles span {
  margin: 5px 10px;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是席木木啊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值