前端vue 上传base64图片组件带获取展示 功能

npm找到的组件 带图片压缩 上传限制 数量限制等!!!
地址:https://www.npmjs.com/package/vue-upload-imgs

这个组件还有其他功能有需要的都可以自行研究.
在这里插入图片描述

实现思路是前端上传图片把图片前端处理转换成base64发送给后端,后端保存base64转换成图片保存到后端数据库,当需要展示或者修改时,把图片以base64传给前端,利用这个组件处理base64的性质,直接展示并增删图片.

图片修改部分!!!:我这边和后端商量的是前端先获取原始数据后端发现数据变化会先删之前的数据再把编辑后的所有数据进行保存,相当于每次图片的保存都是对后台图片的先删除再保存最新的数据,这样可能有些耗费性能,但是业务需求可能没那么处理大量图片所以采用了这个方法.

效果图:
在这里插入图片描述

关键节点展示:
新增的请求:
在这里插入图片描述
关键节点代码:


```javascript
<template>
  <Modal
    v-model="dataOutput.show2"
    class-name="vertical-center-modal"
    :visible.sync="modal1"
    title="档案-新增"
    width="720"
    ok-text="保存"
    :loading="loading"
    @on-ok="handleSubmit('formInline')"
  >
    <!-- <Form
      ref="formValidate"
      :model="formInline"
      :label-width="100"
      :rules="ruleInline"
    > -->
    <Form
      ref="formInline"
      :model="formInline"
      :rules="ruleInline"
      :label-width="100"
    >
      <FormItem label="档案类别:">
        <!-- <Input v-model="formValidate.name" placeholder="档案类别" /> -->
        <Cascader :data="casData" v-model="casValue"></Cascader>
      </FormItem>

      <FormItem label="签发时间:" style="margin-top: 30px" prop="create_time">
        <DatePicker
          type="date"
          placeholder="请选择"
          style="margin-top: 5px"
          format="yyyy-MM-dd"
          :value="formInline.create_time"
          @on-change="endDateTime"
        ></DatePicker>
      </FormItem>
    </Form>
    <!-- 图片上传  把后端要的base64传过去组件已写好    待处理-->
    <vue-upload-imgs
      multiple
      compress
      :before-read="beforeRead"
      :after-read="afterRead"
      :before-remove="beforeRemove"
      :limit="limit"
      :type="type"
      @preview="preview"
      @exceed="exceed"
      @oversize="oversize"
      v-model="files"
    >
      <div>请上传jpg和png格式的图片</div>
    </vue-upload-imgs>
    <div class="preview-bg" v-show="isPreview">
      <div class="dialog">
        <button class="close-preview" @click="closePreview">关闭</button>
        <img :src="previewIMG" class="preview-img" />
      </div>
    </div>
  </Modal>
</template>



<script>
import CompTable from "../components/CompTable";
import { Message, Modal } from "view-design";
export default {
  components: {
    CompTable,
  },
  data() {
    return {
      loading: "",
      ruleInline: {
        create_time: [
          {
            required: true,
            message: "请输入签发时间!",
            trigger: "blur",
          },
        ],
      },

      // 图片上传
      files: [
        // {
        //   url:
        //     "https://pic3.zhimg.com/v2-058f646c41b55206f8110489d82fa103_is.jpg",
        //   name: "user.jpg",
        // },
      ],
      maxSize: 1024 * 10, // 10 KB
      previewIMG: null,
      limit: 50,
      isPreview: false,
      type: 1, // 0 预览模式 1 列表模式 2 预览模式 + 上传按钮

      data: [],
      casValue: [],
      casData: [],
      modal1: false,
      formInline: {
        create_time: "",
        name: "",
        number: "",
        company_id: "",
      },
    };
  },
  props: {
    dataOutput: Object,
    // params: Object,
    company_id: String,
  },
  mounted() {
    this.postInsertNewFile2();
  },

  watch: {},
  methods: {
    //表单验证
    handleSubmit(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          this.postInsertNewFile1(name);
          // Message.success("添加企业成功!");
          // this.loading = true;
        } else {
          Message.error("请输入有效信息!");
          this.loading = false;
        }
      });
    },
    //处理组件时间问题:
    endDateTime: function (time) {
      this.formInline.create_time = time;
    },
    //测试档案新增请求
    postInsertNewFile1: async function () {
      var name = this.casValue[this.casValue.length - 1];
      let vm = this;
      let filedata = vm.formInline;
      let picture = vm.files;
      filedata.company_id = this.company_id;
      filedata.name = name;
      filedata.picture = picture; //上传图片
      const res = await vm.http.post(vm.api.file, filedata);
      console.log(res, "res-----------999");
      this.$emit("refresh");
      if (res.data.success) {
        this.formInline.create_time = "";
        this.files = [];
        // this.casData = [];
        this.casValue = [];
        Message.success("添加成功!");
        this.dataOutput.show2 = false;
        // this.loading = true;
      } else {
        Message.error("请输入有效信息!");
        // this.loading = false;
      }
    },

    //测试三级表单请求
    postInsertNewFile2: async function () {
      // console.log("casValue-----",this.casValue);
      // return;
      let vm = this;
      let file = {};
      file.department_id = this.$route.params.type;
      // file.department_id = 41
      const res = await vm.http.get(vm.api.service, file);
      console.log(res, "ressanji-------------");
      this.casData = res.data.data;
    },

    //图片上传逻辑
    oversize(file) {
      console.log("oversize");
      console.log("filesize:" + file.size / 1024 + "KB");
    },

    afterRead(file) {
      console.log("after-read");
      console.log(file);
    },

    beforeRemove(index, file) {
      console.log(index, file); //图片
      return true;
    },

    preview(index, file) {
      this.previewIMG = file.url;
      this.isPreview = true;
    },

    exceed() {
      alert(`只能上传${this.limit}张图片`);
    },

    beforeRead(files) {
      console.log("before-read");
      for (let i = 0, len = files.length; i < len; i++) {
        const file = files[i];
        if (file.type != "image/jpeg" && file.type != "image/png") {
          alert("只能上传jpg和png格式的图片");
          return false;
        }
      }

      return true;
    },

    closePreview() {
      this.isPreview = false;
    },
  },
};
</script>

<style scoped lang="scss">
/deep/ .ivu-icon-ios-close {
  display: none;
}
.vue-upload-imgs {
  margin-left: 60px;
}
</style>



图片编辑代码:

```javascript
<template>
  <Modal
    v-model="dataOutput.show3"
    class-name="vertical-center-modal"
    :visible.sync="modal1"
    title="档案-修改"
    width="1150"
    ok-text="提交"
    @on-ok="handleSubmit('formInline')"
  >
    <Form
      ref="formInline"
      :model="formInline"
      :rules="ruleInline"
      :label-width="160"
    >
      <FormItem label="档案状态:" prop="file_status">
        <Select v-model="formInline.file_status">
          <Option value="正常">正常</Option>
          <Option value="废弃">废弃</Option>
        </Select>
      </FormItem>
      <FormItem label="签发时间:" style="margin-top: 30px" prop="create_time">
        <DatePicker
          type="date"
          placeholder="请选择"
          style="margin-top: 5px"
          format="yyyy-MM-dd"
          v-model="formInline.create_time"
          @on-change="endDateTime"
        ></DatePicker>
      </FormItem>
    </Form>
    <!-- 图片上传  把后端要的base64传过去组件已写好    待处理-->
    <vue-upload-imgs
      multiple
      compress
      :before-read="beforeRead"
      :after-read="afterRead"
      :before-remove="beforeRemove"
      :limit="limit"
      :type="type"
      @preview="preview"
      @exceed="exceed"
      @oversize="oversize"
      v-model="files"
    >
      <div></div>
      <div>请上传jpg和png格式的图片</div>
    </vue-upload-imgs>
    <div class="preview-bg" v-show="isPreview">
      <div class="dialog">
        <!-- <button class="close-preview" @click="closePreview">关闭</button> -->
        <Button
          type="warning"
          class="mar_r_30 close-preview"
          @click="closePreview"
          >关闭</Button
        >
        <img :src="previewIMG" class="preview-img" />
      </div>
    </div>

    <!-- <button @click="handleSubmit">提交</button> -->
  </Modal>
</template>



<script>
// import CompTable from "../components/CompTable";
// import axios from "axios";
import { Message, Modal } from "view-design";
import $ from "jquery";
export default {
  components: {
    // CompTable,
  },
  data() {
    return {
      formInline: {
        file_status: "",
        create_time: "",
      },
      ruleInline: {
        file_status: [
          {
            required: true,
            message: "请输入企业名称",
            trigger: "blur",
          },
        ],
      },
      offset: 0,
      id: "",
      files: [
        // {
        //   url:
        //     "https://pic3.zhimg.com/v2-058f646c41b55206f8110489d82fa103_is.jpg",
        //   name: "user.jpg",
        // },
      ],
      maxSize: 1024 * 10, // 10 KB
      previewIMG: null,
      limit: 50,
      isPreview: false,
      type: 2, // 0 预览模式 1 列表模式 2 预览模式 + 上传按钮

      data: [],
      modal1: false,
    };
  },
  props: {
    dataOutput: Object,
    iddata: String,
  },
  mounted() {
    this.postInsertNewFile2();
  },

  watch: {
    iddata: function (newVal, oldVal) {
      console.log("newVal---", newVal);
      this.postInsertNewFile2();
    },
  },
  methods: {
    //处理组件时间问题:
    endDateTime: function (time) {
      this.formInline.create_time = time;
    },
    //表单验证
    handleSubmit(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          this.updataNewFile(name);
          // Message.success("添加成功!");
        } else {
          Message.error("请输入有效信息!");
          return;
        }
      });
    },
    //更新数据
    updataNewFile: async function () {
      let vm = this;
      let params = {
        id: this.iddata,
        status: this.formInline.file_status, //档案的id字段  department_id
        create_time: this.formInline.create_time,
      };
      let status = vm.formInline;
      let picture = vm.files;
      params.picture = picture; //上传图片
      const res = await vm.http.put(vm.api.file, params);
      this.$emit("refresh1");
      console.log("更新档案", res);
      Message.success("修改成功!");
      this.postInsertNewFile2();
    },

    //档案信息编辑获取请求
    postInsertNewFile2: async function () {
      let vm = this;
      let params = {
        id: this.iddata, //档案的id字段  department_id
      };
      //let Base64 = require("js-base64").Base64; //base64转换
      const res = await vm.http.get(vm.api.picture, params);
      if (!res.data.success) {
        // Message.error("数据请求失败或未上传");
        // console.log("数据错误或为空");
        return;
      }
      vm.files = res.data.data.map((item) => {
        console.log(typeof item.url);
        let url = item.url.slice(2);

        return {
          url: `data:image/png;base64,${url.replace("'", "")}`,
        };
      });
      console.log("res-----8888888888811", res.data);
      this.formInline = res.data;
    },

    //图片上传逻辑
    oversize(file) {
      console.log("oversize");
      console.log("filesize:" + file.size / 1024 + "KB");
    },

    afterRead(file) {
      console.log("after-read");
      console.log(file);
    },

    beforeRemove(index, file) {
      console.log(index, file); //图片
      return true;
    },

    preview(index, file) {
      this.previewIMG = file.url;
      this.isPreview = true;
    },

    exceed() {
      alert(`只能上传${this.limit}张图片`);
    },

    beforeRead(files) {
      console.log("before-read");
      for (let i = 0, len = files.length; i < len; i++) {
        const file = files[i];
        if (file.type != "image/jpeg" && file.type != "image/png") {
          alert("只能上传jpg和png格式的图片");
          return false;
        }
      }

      return true;
    },

    closePreview() {
      this.isPreview = false;
    },
    //图片上传结束
  },
};
</script>

<style scoped lang="scss">
/deep/ .ivu-icon-ios-close {
  display: none;
}
.vue-upload-imgs {
  margin-left: 25px;
}
.preview-img {
  position: absolute;
  top: 50px;
  left: 160px;
  width: 800px;
  height: 600px;
}
.close-preview {
  position: absolute;
  top: 50px;
  left: 900px;
  z-index: 500;
}
</style>

有些可能用不到,但为了保证完整性所以都粘上去了.


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