美文网首页
vue中利用element UI实现文件上传

vue中利用element UI实现文件上传

作者: 初见_JS | 来源:发表于2021-04-12 15:18 被阅读0次

项目中经常会用到文件上传的功能,为避免重复犯错,现将近阶段亲测过的方法,记录下

  • 首先后端接口需求,需同时传文件FormData和其他所需参数,如下图所示:
    文件上传接口.png
  • 前端简单的配置界面,如图所示,利elementUI组件el-upload
    前端界面设置.png
  • 实现方法

关键点:el-uploadhttp-request方法获取文件File信息和FormData方式传参

1.利用http-request函数获取上传的文件File信息

http-request主要为覆盖默认的上传行为,可以自定义上传的实现,因需要实现手动上传,故应用到此方法

<template></template>

<template>
  <el-upload
    class="upload-demo"
    ref="upload"
    accept=".dat"
    action=""
    :http-request="httpRequest"
    :auto-upload="false"
    :file-list="fileList"
    :on-change="handleFileChange"
  >
    <el-button slot="trigger" size="small" type="success">选取文件</el-button>
    <div slot="tip" class="el-upload__tip" style="color: #ee4234">
      {{ tips }}
    </div>
  </el-upload>
</template>

手动上传时,会触发http-request的回调函数httpRequest

httpRequest方法

httpRequest(param) {
      let fileObj = param.file; // 相当于input里取得的files
      let fileName = fileObj.name;
      let formData = new FormData(); // FormData 对象
      formData.append("MultipartFile", fileObj); // 文件对象
      formData.append("fileCreateName", fileName);//传递其他参数
      this.$emit("upload", formData);
 }

2.利用axiopost方法,实现与后端接口联调

关键点:设置headersmultipart/form-data

注意:uploadFile方法为封装好的方法

//文件上传
export function uploadFile(formData) {
  return request({
    url: '/dataFileRecord/add',
    method: 'post',
    data: formData,
    isFormData: true,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}

3.完整代码,包括判断上传文件格式每次切换文件只显示最新选择的一个

自己封装的Upload组件

<template>
  <el-upload
    class="upload-demo"
    ref="upload"
    accept=".dat"
    action=""
    :http-request="httpRequest"
    :auto-upload="false"
    :file-list="fileList"
    :on-change="handleFileChange"
  >
    <el-button slot="trigger" size="small" type="success">选取文件</el-button>
    <div slot="tip" class="el-upload__tip" style="color: #ee4234">
      {{ tips }}
    </div>
  </el-upload>
</template>
<script>
export default {
  name: "upload",
  data() {
    return {
      tips: "只能上传dat格式的文件",
      fileList: [],
    };
  },
  props: ["fileName"],
  methods: {
    init() {
      this.fileList = [];
      this.tips = "只能上传dat格式的文件";
    },
    httpRequest(param) {
      let fileObj = param.file; // 相当于input里取得的files
      let fileName = fileObj.name;
      let formData = new FormData(); // FormData 对象
      formData.append("MultipartFile", fileObj); // 文件对象
      formData.append("fileCreateName", fileName);
      this.$emit("upload", formData);
    },
    isFormatValid(type) {
      let pStrDAt = /\.dat?$/i;
      return pStrDAt.test(type);
    },
    handleFileChange(file, fileList) {
      this.beforeUpload(file);
      if (fileList.length > 0) {
        this.fileList = [fileList[fileList.length - 1]]; // 这一步,是 展示最后一次选择的dat文件
      }
    },
    beforeUpload(file) {
      let fileName = file.name;
      this.$emit("update:fileName", fileName);
      let isDat = this.isFormatValid(fileName);
      if (!isDat) {
        this.tips = "当前选择的文件格式不正确,请重新选择!";
      } else {
        this.tips = "";
      }
      return isDat;
    },
    handleSubmit() {
      if (!this.tips) {
        this.$refs.upload.submit();
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.el-upload__tip {
  color: #ee4234;
  position: absolute;
  top: 40px;
}
</style>

注意:点击确定按钮,调用组件uploadsubmit方法,从而触发httpRequest方法,实现手动上传

 this.$refs.upload.submit();

主页面

<template>
  <MainPanel
    ref="panel"
    :tableInfo="tableInfo"
    :dialogInfo="dialogInfo"
    @table-update="handlePageUpdate"
    @table-edit="handleTableEdit"
    @table-delete="handleTableDelete"
    @btn-search="handleSearch"
    @btn-add="handleAdd"
    @btn-batch-delete="handleBatchDelete"
    @dialog-confirm="handleDialogConfirm"
    @dialog-cancel="handleDialogCancel"
  >
    <el-col :span="1" class="search-text">文件名称:</el-col>
    <el-col :span="3">
      <el-input
        v-model="searchFileName"
        placeholder="请输入文件名称"
        style="width: 100%"
        clearable
      ></el-input>
    </el-col>
    <template #dialog>
      <el-col :span="6">
        <Upload
          v-if="!isEdit"
          ref="upload"
          :fileName.sync="fileName"
          @upload="handleUpload"
        ></Upload>
      </el-col>
    </template>
  </MainPanel>
</template>
<script>
import MainPanel from "@/components/MainPanel";
import { uploadFile, getFileList, updateFile, delFile } from "@/api/api.js";
import Upload from "@/components/Upload";
export default {
  name: "fileManage",
  data() {
    var columns = [
      {
        label: "文件名称",
        prop: "fileCreateName",
        required: true,
      },
      {
        label: "文件大小",
        prop: "fileSize",
      },
      {
        label: "文件类型",
        prop: "fileType",
      },
      {
        label: "创建时间",
        prop: "createTime",
      },
      {
        label: "更新时间",
        prop: "updateTime",
      },
    ];
    var validateName = (rule, value, callback) => {
      if (!this.dialogInfo.condition.fileCreateName) {
        callback(new Error("文件名不能为空"));
      } else {
        callback();
      }
    };
    return {
      tableInfo: {
        tableData: [],
        columns: columns,
        tableTotal: 0,
        pageInfo: {},
      },
      dialogInfo: {
        title: "文件上传",
        columns: columns.filter((item) => item.required),
        condition: {
          fileCreateName: "",
        },
        dialogWidth: "50%",
        rules: {
          fileCreateName: [
            { required: true, validator: validateName, trigger: "blur" },
          ],
        },
      },
      isEdit: false,
      condition: {
        pageNo: 1,
        pageSize: 10,
      },
      currentId: "",
      fileName: "",
      searchFileName: "",
    };
  },
  components: { MainPanel, Upload },
  watch: {
    fileName(val) {
      this.dialogInfo.condition.fileCreateName = val;
    },
  },
  mounted() {
    //获取文件列表
    this.getFileList();
  },
  methods: {
    async getFileList() {
      let pInfo = await getFileList(this.condition);
      this.tableInfo.tableData = pInfo.data.data.content;
      this.tableInfo.tableTotal = pInfo.data.data.totalElements;
    },
    handlePageUpdate(condition) {},
    handleTableEdit(row) {
      this.isEdit = true;
      this.dialogInfo.title = "文件编辑";
      this.currentId = row.id;
    },
    handleTableDelete(row) {
      this.deleteFiles([row.id]);
    },
    handleBatchDelete(items) {
      let idArray = items.map((item) => item.id);
      this.deleteFiles(idArray);
    },
    handleAdd() {
      this.isEdit = false;
      this.dialogInfo.condition.fileCreateName = "";
      if (this.$refs.upload) {
        this.$refs.upload.init();
      }
    },
    handleSearch() {
      this.tableInfo.pageInfo = {
        pageNo: 1,
        pageSize: 10,
      };
      this.condition.pageNo = 1;
      this.condition.pageSize = 10;
      this.condition.param = JSON.stringify({
        fileCreateName: this.searchFileName,
      });
      this.getFileList();
    },
    handleDialogConfirm() {
      if (this.isEdit) {
        this.updateFile();
      } else {
        if (this.$refs.upload) {
          this.$refs.upload.handleSubmit();
        }
      }
    },
    handleDialogCancel() {
      this.fileName = "";
    },
    addFile(formData) {
      uploadFile(formData).then((res) => {
        if (res.data.code === "0") {
          this.handleSuccess("上传");
        } else {
          this.handleError("上传");
        }
      });
    },
    updateFile() {
      updateFile({
        fileCreateName: this.dialogInfo.condition.fileCreateName,
        id: this.currentId,
      }).then((res) => {
        if (res.data.code === "0") {
          this.handleSuccess("更新");
        } else {
          this.handleError("更新");
        }
      });
    },
    deleteFiles(idArray) {
      delFile(idArray).then((res) => {
        if (res.data.code === "0") {
          this.handleSuccess("删除");
        } else {
          this.handleError("删除");
        }
      });
    },
    handleUpload(formData) {
      this.addFile(formData);
    },
    handleSuccess(type) {
      this.$message({
        type: "success",
        message: "文件" + type + "成功!",
      });
      if (this.$refs.panel) {
        this.$refs.panel.init();
      }
      this.fileName = "";
      this.getFileList();
    },
    handleError(type) {
      this.$message({
        type: "error",
        message: "文件" + type + "失败,请检查服务连接!",
      });
    },
  },
};
</script>
<style lang="scss" scoped>
</style>

相关文章

网友评论

      本文标题:vue中利用element UI实现文件上传

      本文链接:https://www.haomeiwen.com/subject/galxlltx.html