vue +elementui 项目中表单提交 同时上传图片,转为base64格式传给后端

1.新增应用时时一个form 表单,其中一个是用户上传应用图标。
在这里插入图片描述
2.要求传给后端时以base64格式,需要前端转换。在上传时的chaneg事件里转,完整代码如下

<template>
  <j-page>
    <div slot="content">
      <!-- <el-button type="text" icon="el-icon-back">返回</el-button> -->
      <el-button :loading="btnLoading" type="primary" @click="saveInfo">保存</el-button>
    </div>
    <el-card>
      <el-form ref="appForm" :model="appForm" :rules="appRules">
        <el-form-item label="应用名称" prop="name">
          <el-input v-model="appForm.name" placeholder="请输入应用名称" />
        </el-form-item>
        <el-form-item label="应用标识" prop="key">
          <el-input v-model="appForm.key" placeholder="请输入应用标识" />
        </el-form-item>

        <el-form-item label="应用描述" prop="description">
          <el-input v-model="appForm.description" placeholder="请输入应用描述" style="width:100%" />
        </el-form-item>
        <el-form-item label="应用类型" prop="type">
          <el-select v-model="appForm.type" placeholder="请选择应用类型" style="width:100%">
            <el-option label="默认应用" value="0" />
            <el-option label="接入应用" value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="应用状态" prop="state">
          <el-select v-model="appForm.state" placeholder="请选择应用状态" style="width:100%">
            <el-option label="可用" value="0" />
            <el-option label="不可用" value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="是否启动" prop="status">
          <el-radio-group v-model="appForm.status">
            <el-radio label="0"></el-radio>
            <el-radio label="1"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="分组" prop="group">
          <el-select v-model="appForm.group" placeholder="请选择分组" style="width:100%">
            <el-option
              v-for="item in groupList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="失效日期" prop="invalidDate">
          <el-date-picker v-model="appForm.invalidDate" type="datetime" placeholder="选择日期" />
        </el-form-item>
        <el-form-item label="应用访问根路径" prop="url">
          <el-input v-model="appForm.url" placeholder="请输入应用访问根路径" />
        </el-form-item>
        <el-form-item label="应用访首页路由" prop="homeUrl">
          <el-input v-model="appForm.homeUrl" placeholder="请输入应用访首页路由" />
        </el-form-item>
        <el-form-item label="关键字" prop="keyWords">
          <el-input v-model="appForm.keyWords" placeholder="请输入应用关键字" />
        </el-form-item>
        <el-form-item label="应用图标" prop="image">
          <el-upload
            class="upload-img"
            :style="{backgroundImage:'url(' + appForm.image + ')', backgroundRepeat:'no-repeat', backgroundPosition:'center center', backgroundSize: 'contain'}"
            action
            ::limit="1"
            :show-file-list="false"
            :on-change="handleChange"
            :before-upload="beforeUpload"
            accept="image/png, image/gif, image/jpg, image/jpeg"
          >
            <i v-show="!appForm.image" class="el-icon-upload avatar-uploader-icon" />

            <div v-show="!appForm.image" slot="tip" class="el-upload__text upload__tip">上传照片</div>
          </el-upload>
        </el-form-item>
      </el-form>
    </el-card>
  </j-page>
</template>

<script>
import { apiBaseAppAdd, apiBaseAppUpdate } from "@/api/application/application";
import moment from "moment";

import { apiBaseGetDic } from "@/api/dictionary/dictionary";

export default {
  props: {
    visible: {
      type: Boolean,
      default: true,
    },
    ip: {
      type: String,
      default: null,
    },
    dicTitle: {
      default: undefined,
      type: String,
    },
    data: {
      type: Object,
      default: () => undefined,
    },
  },
  data() {
    return {
      btnLoading: false,
      appForm: {
        image: undefined,
        type: "0",
        state: "0",
        status: "0",
      },
      appRules: {
        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
        key: [{ required: true, message: "请输入key", trigger: "blur" }],
        image: [{ required: true, message: "请选择图片", trigger: "blur" }],
      },
      groupList: [],
    };
  },
  mounted() {
    this.getDic();
  },
  methods: {
    onClose() {
      this.$emit("update:visible", false);
      // console.log(this.$refs.appForm);
      // if (!this.data) {
      this.$refs.appForm.resetFields();
      // }

      // if (this.data) this.appForm = this.data;
      // this.appForm.imageUrl = "";
    },
    async getDic() {
      const { data, success, message } = await apiBaseGetDic();
      if (!success) {
        this.$message.warning(message);
        return;
      }
      this.groupList = data;
    },
    async saveInfo() {
      try {
        await this.$refs.appForm.validate();
      } catch (error) {
        return;
      }
      this.btnLoading = true;
      const { success, message } = await apiBaseAppUpdate(this.appForm);
      if (!success) {
        this.$message.warning(message);
        return;
      }
      this.btnLoading = false;
      this.$message.success(message);
      this.$router.go(-1);
    },

    handleChange(file, fileList) {
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (isLt2M) {
        // uploadImgToBase64()返回一个Promise对象,通过.then()获取其数据。其中data.result是图片转成的base64值
        this.uploadImgToBase64(file.raw).then((data) => {
          this.appForm.image = data.result;
        });
      } else {
        this.$message.error("上传图片大小不能超过 2MB!");
      }
    },
    uploadImgToBase64(file) {
      // 核心方法,将图片转成base64字符串形式
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function () {
          // 图片转base64完成后返回reader对象
          resolve(reader);
        };
        reader.onerror = reject;
      });
    },
    beforeUpload(file) {
      return false;
    },
  },
};
</script>

<style lang="scss" scoped>
input[type="file"] {
  display: none;
}

.avatar-uploader /deep/ .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader /deep/ .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 36px;
  color: #8c939d;
  width: 120px;
  height: 120px;
  line-height: 120px;
  text-align: center;
}
.avatar {
  width: 120px;
  height: 120px;
  display: block;
}
.add-keyperson-dialog .upload-img:hover {
  border-color: #409eff;
  color: #409eff;
}
.el-dialog__body {
  height: 400px;
  overflow-y: auto;
  overflow-x: hidden;
}

/deep/ .el-form {
  width: 50%;
  margin: auto;
}
/deep/ .el-date-editor.el-input,
.el-date-editor.el-input__inner {
  width: 100%;
}
</style>

3.上传成功后端返回数据如下
在这里插入图片描述
4.前端展示只需要这样写
在这里插入图片描述


版权声明:本文为u010328533原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。