当前位置:首页 » 《关注互联网》 » 正文

【Vue】以RuoYi框架前端为例,ElementUI封装图片上传组件——将图片信息转成base64后提交到后端保存

20 人参与  2024年10月14日 09:20  分类 : 《关注互联网》  评论

点击全文阅读


RuoYi 框架本身对于图片上传功能,在ElementUI<el-upload> 组件的基础装封装了 @/components/ImageUpload/index.vue 组件。本组件就是在 RuoYi 自定义的 <ImageUpload> 组件的基础上进行改造,将图片的信息在上传之前处理成 base64 格式,用于提交到后端接口,以及前端图片相应的预览展示。

自定义组件 ImageUploadBase64

组件目录 : @/components/ImageUploadBase64/index.vue

<template>  <div class="component-upload-image">    <el-upload ref="imageUploadRef"               action="#"               list-type="picture-card"               accept=".png, .jpeg, .jpg"               :limit="limit"               :on-change="handleChange"               :on-remove="handleRemove"               :on-preview="handlePictureCardPreview"               :on-exceed="handleExceed"               :file-list="fileList"               :class="{hide: this.fileList.length >= this.limit}"               :show-file-list="true"               :auto-upload="false">      <i class="el-icon-plus"></i>    </el-upload>    <el-dialog :visible.sync="previewDialogVisible" title="图片预览" width="800" append-to-body>      <el-image style="display: block; max-width: 100%; margin: 0 auto"                :src="previewDialogImageUrl" alt=""></el-image>    </el-dialog>  </div></template><script>export default {  props: {    // 对应父组件 v-model绑定,对应本组件 this.$emit("input",参数)绑定    value: [String, Object, Array],    // 图片数量限制    limit: {      type: Number,      default: 5,    },    // 大小限制(MB)    fileSize: {      type: Number,      default: 5,    },    // 文件类型, 例如['png', 'jpg', 'jpeg']    fileType: {      type: Array,      default: () => ["png", "jpg", "jpeg"],    },  },  data() {    return {      // 图片预览弹窗 显隐      previewDialogVisible: false,      // 图片预览 url      previewDialogImageUrl: '',      // 待上传的图片集合 是转化完base64 后的结果      fileList: [        /*{          name:'',          url:''        }*/      ]    }  },  watch: {    value: {      handler(val) {        if (val) {          // 首先将值转为数组          const list = Array.isArray(val) ? val : this.value.split(',');          // 然后将数组转为对象数组          this.fileList = list.map(item => {            if (typeof item === "string") {              item = {name: item, url: item};            }            return item;          });        } else {          this.fileList = [];          return [];        }      },      deep: true,      immediate: true    }  },  methods: {    /**     * 校验文件尺寸是否符合要求 和类型是否是图片     * @param file     * @returns {boolean}     */    handleFileValidate(file) {      // 上传文件的类型      let type = file.raw.type || file.type;      let isImg = type.indexOf("image") > -1;      if (isImg) {        if (this.fileSize) {          const isLt = file.size / 1024 / 1024 < this.fileSize;          if (!isLt) {            this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`);            return false;          } else {            return true;          }        }      } else {        this.$message.error(          `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`        );        // 不是图片格式        return false;      }    },    /* 添加文件、上传成功和上传失败时都会被调用 */    handleChange(file, fileList) {      if (this.handleFileValidate(file)) {        this.fileToBase64(file);      } else {        // 删除尺寸大的图片 或者非图片类型的文件        let lastIndex = fileList.length - 1;        if (lastIndex > -1) {          fileList.splice(lastIndex, 1);        }      }    },    /**     * 删除图片     * @param file 被删除的图片     * @param fileList 剩余的文件信息列表     */    handleRemove(file, fileList) {      const findex = this.fileList.map(f => f.url).indexOf(file.url);      if (findex > -1) {        // 删除对应的 文件数据        this.fileList.splice(findex, 1);        this.$emit("input", this.listToArray(this.fileList));      }    },    /*预览图片*/    handlePictureCardPreview(file) {      this.previewDialogImageUrl = file.url;      this.previewDialogVisible = true;    },    /**     * 文件个数超出     * @param files 超出的文件信息     * @param fileList 原来已经添加的文件信息     */    handleExceed(files, fileList) {      this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);    },    /**     * 将el-upload组件上传的文件转为base64     * @param file     */    fileToBase64(file) {      var reader = new FileReader();      reader.readAsDataURL(file.raw); // 转换为Base64      reader.onload = e => {        // 当转换完成后,e.target.result就是Base64字符串        const base64 = e.target.result;        this.fileList.push({name: base64, url: base64});        this.$emit("input", this.listToArray(this.fileList));      };    },    // list中的元素{name:'',url:''} 转 url字符串    listToArray(list) {      let arr = [];      for (let i in list) {        arr.push(list[i].url);      }      return arr;    }  }}</script><style scoped lang="scss">// .el-upload--picture-card 控制加号部分::v-deep.hide .el-upload--picture-card {  display: none;}// 去掉动画效果::v-deep .el-list-enter-active,::v-deep .el-list-leave-active {  transition: all 0s;}::v-deep .el-list-enter, .el-list-leave-active {  opacity: 0;  transform: translateY(0);}</style>

表单中引用如下

<template>  <div class="app-container">    <!-- 添加或修改对话框 -->    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>      <el-form ref="form" :model="form" :rules="rules" :show-message="false" label-width="80px">          <el-col :span="24">            <el-form-item label="上传图片">            <ImageUploadBase64 v-model="form.base64DataList" :file-size="10" @input="handleImageInput"></ImageUploadBase64>            </el-form-item>          </el-col>        </el-row>      </el-form>      <div slot="footer" class="dialog-footer">        <el-button type="primary" @click="submitForm()">保 存</el-button>        <el-button @click="cancel">取 消</el-button>      </div>    </el-dialog>  </div></template><script>import ImageUploadBase64 from "@/components/ImageUploadBase64/index.vue";import {listWorkInfo, getWorkInfo, delWorkInfo, addWorkInfo, updateWorkInfo} from "@/api/basic/work";export default {  name: "Work",  components: {ImageUploadBase64},  data() {    return {      // 弹出层标题      title: "",      // 是否显示弹出层      open: false,      // 表单参数      form: {},    };  },  created() {    this.getList();  },  methods: {     /**     * 子组件 this.$emit("input", this.listToArray(this.fileList)); 返回的数据     * @param fileList     */    handleImageInput(fileList){      // 这里返回的就是base64字符串的数组,可以直接提交后端接口,也可以根据业务做其他处理      console.log("handleImageInput-----:", fileList)    },    // 取消按钮    cancel() {      this.open = false;      this.reset();    },    // 表单重置    reset() {      this.form = {        id: null        base64DataList:[]      };      this.resetForm("form");    },    /** 新增按钮操作 */    handleAdd() {      this.reset();      this.title = "添加工作信息";      this.open = true;    },    /** 修改按钮操作 */    handleUpdate(row) {      this.reset();      const id = row.id || this.ids      getWorkInfo(id).then(response => {        this.form = response.data;        this.open = true;        this.title = "修改工作信息";      });    },    /** 提交按钮 */    submitForm: function () {      this.$refs["form"].validate(valid => {        if (valid) {          if (this.form.id != undefined) {            updateWorkInfo(this.form).then(response => {              this.$modal.msgSuccess("修改成功");              this.open = false;              this.getList();            });          } else {            addWorkInfo(this.form).then(response => {              this.$modal.msgSuccess("新增成功");              this.open = false;              this.getList();            });          }        }      });    }  }};</script>

这个组件将图片信息直接在前端转化成 base64格式的字符串数字,后端可以直接使用List<String> 接收图片的信息并进行后续的处理。


点击全文阅读


本文链接:http://zhangshiyu.com/post/171501.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1