什么?封装el-upload组件,开发效率直接翻倍,工作再忙也要记得按时摸鱼

项目需要,主要做薪酬这一块,薪酬又关系到人员统计,部门划分,以及各个站所,因此会产生很多表格展示数据,并且需要导入数据,导出数据,导出表格模板的功能。

依旧是对组件封装,通过JSON管理状态,如需要导出带出表名字,需要后端配合。另外导出接口配置添加

responseType: "blob"

如果icon 加载不出来 自行更替一下即可 我用的项目自带封装

效果展示

代码部分

index.vue 部分

<template>
  <div class="ImportAndExport">
    <div style="display: flex;">
      <ExporTtemplate
        v-if="templateComShow && templateConfig"
        :templateConfig="templateConfig"
        @success="templateSuccess"
        @exTemCheckFun="$emit('exTemCheckFun', $event)"
        @exportTempChange="$emit('exportTempChange', $event)"
      ></ExporTtemplate>
      <div style="width: 8px;" v-if="templateComShow && importComShow"></div>
      <importCom
        v-if="importComShow && importConfig"
        :importConfig="importConfig"
        @success="importSuccess"
      ></importCom>
      <div style="width: 8px;" v-if="importComShow && exportComShow"></div>
      <exportCom
        v-if="exportComShow && exportConfig"
        :exportConfig="exportConfig"
        :isCheck="isCheck"
        @success="exportSuccess"
        @checkFun="$emit('checkFun', $event)"
        @exportChange="$emit('exportChange', $event)"
      ></exportCom>
    </div>
  </div>
</template>

<script>
import importCom from "./importd";
import exportCom from "./exportd";
import ExporTtemplate from "./exporTtemplate";
export default {
  components: {
    importCom,
    exportCom,
    ExporTtemplate
  },
  props: {
    // 参数配置
    config: {
      // 是否必填
      isCheck: false,
      importComShow: true, // 导入组件显示
      exportComShow: true, // 导出组件显示
      templateComShow: true, // 导出模板组件显示
      // 导入配置
      importConfig: {
        // 是否多文件上传
        multiple: false,
        // 导入文件类型
        fileTypeArr: [],
        // 导入方法
        importMethod: null,
        // 导入参数
        importParams: {},
        // 导入名字
        impName: "导入"
      },
      // 导出配置
      exportConfig: {
        // 导出方法
        exportMethod: null,
        // 导出参数
        exportParams: {},
        // 导出按钮名字
        expName: "导出",
        // 导出文件名
        exportFileName: "未命名.xlsx"
      },
      // 导出模板配置
      templateConfig: {
        // 导出模板方法
        temMethod: null,
        // 导出模板参数
        temParams: {},
        // 导出模板按钮名字
        temName: "导出模板",
        // 导出模板文件名
        temFileName: "未命名.xlsx"
      }
    }
  },
  data() {
    return {
      isCheck: false, //是否必填
      importComShow: true, // 导入组件显示
      exportComShow: true, // 导出组件显示
      templateComShow: true, // 导出模板组件显示
      Filetype:
        ".text,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.html,.png,.jpg,.jpeg,.gif,.bmp,.zip,.rar,.7z,.tar,.gz,.bz2,.cab,.iso,.dmg,.apk,.ipa,.exe,.bin,.dll,.so,.sql,.md,.xml,.json,.csv,.ts,.js,.php,.py,.java,.c,.cpp,.h,.hpp,.cs,.bat,.cmd,",
      // 导入配置
      importConfig: {},
      // 导出配置
      exportConfig: {},
      // 导出模板配置
      templateConfig: {}
    };
  },
  computed: {},
  watch: {
    config: {
      handler(newVal, oldVal) {
        this.init();
      },
      deep: true,
      immediate: true
    }
  },
  created() {}, // 生命周期 - 创建完成
  mounted() {}, // 生命周期 - 挂载完成
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  methods: {
    init() {
      if (!this.config) return;
      // 基础部分
      const {
        importComShow,
        exportComShow,
        importConfig,
        exportConfig,
        templateConfig,
        templateComShow,
        isCheck
      } = this.config;
      this.importComShow = importComShow;
      this.exportComShow = exportComShow;
      this.templateComShow = templateComShow;
      this.isCheck = isCheck;
      // 导入配置部分
      if (importConfig) {
        this.importConfig = {
          fileTypeArr: importConfig.fileTypeArr
            ? importConfig.fileTypeArr
            : this.Filetype.split(","),
          importMethod: importConfig.importMethod
            ? importConfig.importMethod
            : null,
          importParams: importConfig.importParams
            ? importConfig.importParams
            : {},
          impName: importConfig.impName ? importConfig.impName : "导入"
        };
      }
      // 导出配置部分
      if (exportConfig) {
        this.exportConfig = {
          exportMethod: exportConfig.exportMethod
            ? exportConfig.exportMethod
            : null,
          exportParams: exportConfig.exportParams
            ? exportConfig.exportParams
            : {},
          exportName: exportConfig.expName ? exportConfig.expName : "导出",
          exportFileName: exportConfig.exportFileName
            ? exportConfig.exportFileName
            : "未命名.xlsx"
        };
      }
      // 导出模板配置部分
      if (templateConfig) {
        this.templateConfig = {
          exportMethod: templateConfig.temMethod
            ? templateConfig.temMethod
            : null,
          exportParams: templateConfig.temParams
            ? templateConfig.temParams
            : {},
          exportName: templateConfig.temName
            ? templateConfig.temName
            : "导出模板",
          exportFileName: templateConfig.temFileName
            ? templateConfig.temFileName
            : "未命名.xlsx"
        };
      }
    },
    importSuccess(val) {
      // 导入回调
      this.$emit("importSuccess", val);
    },
    exportSuccess(val) {
      // 导出回调
      this.$emit("exportSuccess", val);
    },
    templateSuccess(val) {
      // 导出模板回调
      this.$emit("templateSuccess", val);
    }
  }
};
</script>
<style scoped lang="scss"></style>

importd.vue 部分

<template>
  <div class="import">
    <el-upload
      class="upload-import"
      action=" "
      ref="upload"
      :accept="Filetype"
      :http-request="fileUpload"
      :show-file-list="false"
      :before-upload="beforeAvatarUpload"
      :on-change="uploadChange"
    >
      <el-button icon="wk wk-import"
        >{{ impName }}<i class="el-icon-loading" v-if="importLoading"></i
      ></el-button>
    </el-upload>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
    importConfig: {
      type: Object,
      default: () => {
        return {
          // 是否多文件上传
          multiple: false,
          // 导入文件类型
          fileTypeArr: [],
          // 导入方法
          importMethod: null,
          // 导入参数
          importParams: null,
          // 导入名字
          impName: "导入"
        };
      }
    }
  },
  data() {
    return {
      Filetype:
        ".text,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.html,.png,.jpg,.jpeg,.gif,.bmp,.zip,.rar,.7z,.tar,.gz,.bz2,.cab,.iso,.dmg,.apk,.ipa,.exe,.bin,.dll,.so,.sql,.md,.xml,.json,.csv,.ts,.js,.php,.py,.java,.c,.cpp,.h,.hpp,.cs,.bat,.cmd,",
      multiple: false,
      fileTypeArr: [],
      importMethod: null,
      importParams: {},
      impName: "导入",
      importLoading: false
    };
  },
  computed: {},
  watch: {
    importConfig: {
      handler(newVal, oldVal) {
        this.init();
      },
      deep: true,
      immediate: true
    }
  },
  created() {}, // 生命周期 - 创建完成
  mounted() {}, // 生命周期 - 挂载完成
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  methods: {
    // 初始化参数配置
    init() {
      const {
        multiple,
        fileTypeArr,
        importMethod,
        importParams,
        impName
      } = this.importConfig;
      this.multiple = multiple ? multiple : false;
      this.fileTypeArr =
        fileTypeArr && fileTypeArr.length
          ? fileTypeArr
          : this.Filetype.split(",");
      this.importMethod = importMethod ? importMethod : null;
      this.importParams = importParams ? importParams : {};
      this.impName = impName ? impName : "导入";
    },
    // 上传钩子
    beforeAvatarUpload(file) {
      const typeArr = this.fileTypeArr;
      const isType = typeArr.some(item => {
        return file.name.lastIndexOf(item) >= 0;
      });
      if (!isType) {
        this.$message.error("请上传正确文件类型!");
      }
      return isType;
    },
    /** 附件上传 */
    fileUpload(val) {
      this.importLoading = true;
      let file = val.file;
      let params = new FormData();
      params.append("file", file);
      let keys = Object.keys(this.importParams);
      keys &&
        keys.forEach(item => {
          params.append(item, this.importParams[item]);
        });
      // 调用接口
      let importMethod = this.importMethod;
      // 如果是一个函数 就调用接口
      if (importMethod && importMethod instanceof Function) {
        importMethod(params)
          .then(res => {
            this.importLoading = false;
            if (res.code != 0) return this.$message.error("网络异常");
            this.$message.success("导入成功");
            // 成功回调
            this.$emit("success", res);
          })
          .catch(() => {});
      } else {
        this.importLoading = false;
        this.$message.error("请先配置接口数据!");
      }
    },
    // 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    uploadChange(file, fileList) {
      console.log(file, fileList, "文件状态改变时的钩子");
      // this.progressFlag = true; // 显示进度条
      // this.loadProgress = parseInt(event.percent); // 动态获取文件上传进度
      // console.log("上传进度", this.loadProgress);
      // if (this.loadProgress >= 100) {
      //     this.loadProgress = 100
      //     setTimeout( () => {this.progressFlag = false}, 1000) // 一秒后关闭进度条
      // }
    }
  }
};
</script>
<style scoped lang="scss"></style>

exportd.vue 部分

<template>
  <div class="export">
    <el-button icon="wk wk-export" @click="ExportAttendance"
      >{{ expName }}<i class="el-icon-loading" v-if="exportLoading"></i
    ></el-button>
  </div>
</template>

<script>
import { BlobExport } from "@/utils/export.js";
export default {
  components: {},
  data() {
    return {
      exportMethod: null,
      exportParams: {},
      expName: "导出",
      exportLoading: false
    };
  },
  props: {
    exportConfig: {
      type: Object,
      default: () => {
        return {
          // 导出方法
          exportMethod: null,
          // 导出参数
          exportParams: null,
          // 导出按钮名字
          expName: "导出",
          // 导出文件名
          exportFileName: "未命名.xlsx"
        };
      }
    },
    isCheck: {
      type: Boolean,
      default: () => {
        return false;
      }
    }
  },
  computed: {},
  watch: {
    exportConfig: {
      handler(newVal, oldVal) {
        this.init();
      },
      deep: true,
      immediate: true
    }
  },
  created() {}, // 生命周期 - 创建完成
  mounted() {}, // 生命周期 - 挂载完成
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  methods: {
    // 初始化参数配置
    init() {
      const {
        exportMethod,
        exportParams,
        exportName,
        exportFileName
      } = this.exportConfig;
      this.exportMethod = exportMethod ? exportMethod : null;
      this.exportParams = exportParams ? exportParams : {};
      this.exportFileName = exportFileName ? exportFileName : "未命名.xlsx";
      this.expName = exportName ? exportName : "导出";
    },
    // 遍历值
    isNotEmpty(obj) {
      for (let key in obj) {
        if (obj[key] === "") {
          return false;
        }
      }
      return true;
    },
    // 导出
    ExportAttendance() {
      // 传递导出事件
      this.$emit("exportChange", this.exportParams);
      if (this.isCheck) {
        if (this.isNotEmpty(this.exportParams)) {
          this.BlobExport();
        } else {
          this.$emit("checkFun", this.exportParams);
        }
      } else {
        this.BlobExport();
      }
    },
    // 封装导出
    BlobExport() {
      this.exportLoading = true;
      let than = this;
      // 如果是一个函数 就调用接口
      let exportMethod = this.exportMethod;
      if (exportMethod && exportMethod instanceof Function) {
        exportMethod({
          ...this.exportParams
        }).then(workbook => {
          // 判断是否接口返回正常
          this.exportLoading = false;
          let res = workbook.data;
          if (res == null) return this.$message.error("导出错误,请稍候再试!");
          if (res.type === "application/json") {
            const reader = new FileReader();
            reader.readAsText(res, "utf-8");
            // 此处为接口返回值
            reader.onload = function() {
              const _res = JSON.parse(reader.result);
              than.$message.error(_res.msg);
            };
          } else {
            // 获取后端返回的文件名
            let flg =
              (workbook.headers && workbook.headers["content-disposition"]) ||
              false; // 存在文件名字信息
            if (flg) {
              // 存在文件名字信息
              BlobExport(workbook);
              this.$message.success("导出成功!");
              // 成功回调
              this.$emit("success", workbook);
            } else {
              // 不存在文件名字信息
              BlobExport(workbook, this.exportFileName);
              // 成功回调
              this.$emit("success", workbook);
            }
          }
        });
      } else {
        this.exportLoading = false;
        // 成功回调
        this.$message.error("请先配置接口数据!");
      }
    }
  }
};
</script>
<style scoped lang="scss"></style>

exporTtemplate.vue 部分

<template>
  <div class="export">
    <el-button icon="wk wk-download" @click="ExportAttendance"
      >{{ expName }}<i class="el-icon-loading" v-if="exportLoading"></i
    ></el-button>
  </div>
</template>

<script>
import { BlobExport } from "@/utils/export.js";
export default {
  components: {},
  data() {
    return {
      exportMethod: null,
      exportParams: {},
      expName: "导出模板",
      exportLoading: false
    };
  },
  props: {
    templateConfig: {
      type: Object,
      default: () => {
        return {
          // 导出方法
          exportMethod: null,
          // 导出参数
          exportParams: null,
          // 导出按钮名字
          expName: "下载模板",
          // 导出文件名
          exportFileName: "未命名.xlsx"
        };
      }
    },
    isCheck: {
      type: Boolean,
      default: () => {
        return false;
      }
    }
  },
  computed: {},
  watch: {
    templateConfig: {
      handler(newVal, oldVal) {
        this.init();
      },
      deep: true,
      immediate: true
    }
  },
  created() {}, // 生命周期 - 创建完成
  mounted() {}, // 生命周期 - 挂载完成
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  methods: {
    // 遍历值
    isNotEmpty(obj) {
      for (let key in obj) {
        if (obj[key] === "") {
          return false;
        }
      }
      return true;
    },
    // 初始化参数配置
    init() {
      const {
        exportMethod,
        exportParams,
        exportName,
        exportFileName
      } = this.templateConfig;
      this.exportMethod = exportMethod ? exportMethod : null;
      this.exportParams = exportParams ? exportParams : {};
      this.exportFileName = exportFileName ? exportFileName : "未命名.xlsx";
      this.expName = exportName ? exportName : "下载模板";
    },
    // 导出
    ExportAttendance() {
      // 传递导出事件
      this.$emit("exportTempChange", this.exportParams);
      if (this.isCheck) {
        if (this.isNotEmpty(this.exportParams)) {
          this.BlobExport();
        } else {
          this.$emit("exTemCheckFun", this.exportParams);
        }
      } else {
        this.BlobExport();
      }
    },
    // 封装导出
    BlobExport() {
      this.exportLoading = true;
      let than = this;
      // 如果是一个函数 就调用接口
      let exportMethod = this.exportMethod;
      if (exportMethod && exportMethod instanceof Function) {
        exportMethod({
          ...this.exportParams
        }).then(workbook => {
          this.exportLoading = false;
          // 判断是否接口返回正常
          let res = workbook.data;
          if (res == null) return this.$message.error("导出错误,请稍候再试!");
          if (res.type === "application/json") {
            const reader = new FileReader();
            reader.readAsText(res, "utf-8");
            // 此处为接口返回值
            reader.onload = function() {
              const _res = JSON.parse(reader.result);
              than.$message.error(_res.msg);
            };
          } else {
            // 获取后端返回的文件名
            let flg =
              (workbook.headers && workbook.headers["content-disposition"]) ||
              false; // 存在文件名字信息
            if (flg) {
              // 存在文件名字信息
              BlobExport(workbook);
              this.$message.success("导出成功!");
              // 成功回调
              this.$emit("success", workbook);
            } else {
              // 不存在文件名字信息
              BlobExport(workbook, this.exportFileName);
              // 成功回调
              this.$emit("success", workbook);
            }
          }
        });
      } else {
        this.exportLoading = false;
        // 成功回调
        this.$message.error("请先配置接口数据!");
      }
    }
  }
};
</script>
<style scoped lang="scss"></style>

使用方法

HTML

    <ImportAndExport
        @importSuccess="importSuccess"
        @exportSuccess="exportSuccess"
        @templateSuccess="templateSuccess"
        @checkFun="checkFun"
        @exportChange="exportChange"
        @exTemCheckFun="exTemCheckFun"
        @exportTempChange="exportTempChange"
        :config="IeConfig"
    />

JS

    import ImportAndExport from "@/components/ImportAndExport";
    export default {
        components: {
            ImportAndExport
        },
        data(){
            return{
                IeConfig: {
                    importComShow: true, // 导入组件显示
                    exportComShow: true, // 导出组件显示
                    templateComShow: true, // 导出模板组件显示
                    // 导入配置
                    importConfig: {
                    // 是否多文件上传
                    multiple: false,
                    // 导入文件类型
                    fileTypeArr: [],
                    // 导入方法
                    importMethod: null,
                    // 导入参数
                    importParams: {},
                    // 导入名字
                    impName: "导入测试"
                    },
                    // 导出配置
                    exportConfig: {
                    // 导出方法
                    exportMethod: null,
                    // 导出参数
                    exportParams: {},
                    // 导出按钮名字
                    expName: "导出测试",
                    // 导出文件名
                    exportFileName: "未命名.xlsx"
                    },
                    // 导出模板配置
                    templateConfig: {
                    // 导出模板方法
                    temMethod: null,
                    // 导出模板参数
                    temParams: {},
                    // 导出模板按钮名字
                    temName: "导出模板",
                    // 导出模板文件名
                    temFileName: "未命名.xlsx"
                    }
                },
            }
        },
        methods:{
            //导出模板必填校验
            exTemCheckFun(val){
            console.log(val,'exTemCheckFun');
            },      
            // 导出模板事件
            exportTempChange(val){
            console.log(val,'exportTempChange');
            },     
            //导出必填校验
            checkFun(val){
            console.log(val,'checkFun');
            },
            //导入成功回调
            importSuccess(val){
            console.log(val,'importSuccess');
            },
            // 导出事件
            exportChange(val){
            console.log(val,'exportChange');
            },
            // 导出成功回调
            exportSuccess(val){
            console.log(val,'exportSuccess');
            },
            // 导出模板成功回调
            templateSuccess(val) {
            console.log(val, "templateSuccess");
            },
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值