vue+阿里oss存储——封装上传组件——uploadFileSingle

下面组件是支持单个文件上传的,可以通过指定accept字段来限制上传文件的类型。
如果需要多个文件同时上传,则需要对下面的组件进行稍微的改动。自行处理哈。

直接上代码:

1.组件的使用

<UploadFileSingle
  style="display:inline-block;margin-left:10px;"
  :buttonFlag="true"
  :filePath="orderInfo.filePath"
  title="修改文件"
  :accept="[
    { title: '2D格式', extensions: 'dwg,dxf,pdf' },
    {
      title: '3D格式',
      extensions: 'step,stp,sldprt,prt,CATPart',
    },
    { title: '压缩包', extensions: 'zip,rar' },
  ]"
  max_file_size="100mb"
  @ok="getFile"
></UploadFileSingle>

2.回调方法

getFile(val) {
	console.log(val)
}

3.组件内容

<template>
  <div class="upload-wrapper">
    <a-button
      v-if="buttonFlag"
      slot="addonAfter"
      type="primary"
      :id="id"
      :loading="loading"
      >{{ title }}</a-button
    >
    <a-input
      v-else
      placeholder="请输入内容"
      v-model="url"
      @change="handleChange"
      allowClear
    >
      <a-button slot="addonAfter" type="primary" :id="id" :loading="loading">{{
        title
      }}</a-button>
    </a-input>
  </div>
</template>
<script>
import uploader from "@/utils/ali-oss.js";
export default {
  name: "fileUpload",
  props: {
    buttonFlag: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: "上传",
    },
    id: {
      type: String,
      default: "fileSingle",
    },
    filePath: {
      type: String,
      default: "",
    },
    extraData: {
      type: Object,
      default: function() {
        return {};
      },
    },
    max_file_size: {
      type: String,
      default: "10mb",
    },
    accept: {
      type: Array,
      default: () => [],
    },
  },
  watch: {
    filePath(newVal, oldVal) {
      this.url = newVal;
    },
  },
  data() {
    return {
      url: "",
      loading: false,
    };
  },
  mounted() {
    this.url = this.filePath;
    this.$nextTick(() => {
      this.initUploader();
    });
  },
  methods: {
    initUploader() {
      let that = this;
      uploader({
        that: this,
        el: this.id,
        extraData: that.extraData,
        accept: this.accept,
        max_file_size: this.max_file_size,
        file_added(uploader, files) {
          that.loading = true;
        },
        file_uploaded(url, file) {
          const path = url.host + url.key + (file.target_name || file.name);
          that.loading = false;
          that.$emit("ok", path, that.id);
          that.$message.success("上传成功");
        },
      }).init();
    },
    handleChange() {
      this.$emit("ok", this.url, this.id);
    },
  },
};
</script>

<style lang="less" scoped>
.upload-wrapper {
  /deep/ .ant-input-group-addon {
    padding: 0;
    border: none;
    background-color: transparent;
    button {
      border-radius: 0 4px 4px 0;
    }
  }
}
</style>

4.ali-oss.js文件

/**
 * plupload中文文档
 * https://www.phpin.net/tools/plupload/
 */
import plupload from "plupload";
import { getOssToken } from '@/services/uploader/uploader';
let host = '';
let key = '';
export default ({
    that = "", //vue实例
    el = "", //点击触发上传的元素
    extraData = {}, //获取上传参数接口的额外参数
    accept = [], //限制文件类型
    multi_selection = false, //是否多文件上传
    limitNum = 0,
    prevent_duplicates = false, //是否允许选取重复文件
    max_file_size = '10mb', //文件大小限制,传数字默认单位b,可以数字和单位组合
    unique_names = false, //生成唯一的文件名
    file_added = new Function(),
    file_uploaded = new Function(),
    uploader_progress = new Function(),
}) => {
    if (!el) {
        console.log("el 不能为空")
        return;
    }
    if (!that) {
        console.log("请传入this")
        return;
    }
    console.log('获取文件类型', accept);
    const uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        // 服务器上传地址,后续获取上传token后会通过setOption进行设置覆盖
        url: 'http://oss.aliyuncs.com',
        // 上传文件类型限制
        filters: {
            mime_types: accept,
            // 限制上传文件大小
            max_file_size: max_file_size,
            // 不允许选取重复文件
            prevent_duplicates: prevent_duplicates
        },
        unique_names: unique_names
    })

    // 设置上传配置
    uploader.setOption({
        browse_button: el,
        multi_selection: multi_selection
    });

    // 文件上传进度
    uploader.bind("UploadProgress", (uploader, file) => {
        uploader_progress(file);
    })

    // 文件上传成功
    uploader.bind("FileUploaded", (up, file, info) => {
        file_uploaded({ host, key }, file);
    })

    // 发生错误
    uploader.bind("Error", (up, info) => {
        switch (info.code) {
            case -600:
                if (/[a-zA-Z]+/g.test(max_file_size)) {
                    that.$message.error('文件不能大于' + max_file_size);
                } else {
                    that.$message.error('文件不能大于' + max_file_size + 'b');
                }
                break;
            default:
                that.$message.error(info.message);
                break;
        }
        that.loading = false;
    })

    // 文件添加成功并且上传
    uploader.bind("FilesAdded", (up, files) => {
        if (multi_selection && limitNum > 0 && (up.files.length > limitNum)) {
            that.$message.error(`只能选择${limitNum}个文件上传`);
            up.files.forEach((file, i) => {
                uploader.splice();
            })
            return false;
        }
        file_added(uploader, files, el);
        // 请求签名、临时host、callback
        //这里替换成项目对应后端接口
        getOssToken(extraData).then(res => {
            host = res.host;
            let policyBase64 = res.policy;
            let accessid = res.accessId;
            let signature = res.signature;
            let callbackbody = res.callback;
            key = res.dir;
            let new_multipart_params = {
                'key': key + '${filename}',
                'policy': policyBase64,
                'OSSAccessKeyId': accessid,
                'success_action_status': '200', //让服务端返回200,不然,默认会返回204
                'callback': callbackbody,
                'signature': signature,
            };

            uploader.setOption({
                'url': host,
                'multipart_params': new_multipart_params
            });
            uploader.start();
        }).catch(() => {
            that.loading = false;
        })
    })

    return uploader;
}

完成!!!多多积累,多多收获!!!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐