vue-cropper plug-in realizes the encapsulation of image capture and upload component

vue-cropper plug-in realizes the encapsulation of image capture and upload component

The specific code for encapsulating the image capture and upload component based on the vue-cropper plug-in is provided for your reference. The specific content is as follows

Demand scenario:

Backend development requires uploading pictures and cropping them in the corresponding proportions. This component development uses the Ant Design Vue component library with the vue-cropper plug-in for encapsulation

The implementation is as follows

html

<template>
  <div>
    <a-upload
      name="avatar"
      list-type="picture-card"
      class="avatar-uploader"
      :show-upload-list="false"
      :custom-request="customRequest"
      :before-upload="beforeUpload"
      :style="`width: ${width}; height: ${height};`"
    >
      <img
        v-if="imageUrl && !loading"
        :src="imageUrl"
        alt="avatar"
        :style="`width: ${width}; height: ${height};`"
      />
      <div v-else>
        <a-icon :type="loading ? 'loading' : 'plus'" />
        <div class="ant-upload-text">Upload pictures</div>
      </div>
    </a-upload>
    <a-modal
      v-model="imageCut.isShowModal"
      title="Picture capture"
      width="400px"
      @ok="finish"
      @cancel="imageCut.close"
    >
      <div class="cropper-content" v-if="imageCut.isShowModal">
        <div class="cropper" style="text-align:center">
          <vueCropper
            ref="cropper"
            :img="imageCut.imgFile"
            :outputSize="outputSize"
            :outputType="outputType"
            :info="info"
            :full="full"
            :canMove="canMove"
            :canMoveBox="canMoveBox"
            :original="original"
            :autoCrop="autoCrop"
            :fixed="fixed"
            :fixedNumber="fixedNumber"
            :centerBox="centerBox"
            :infoTrue="infoTrue"
            :fixedBox="fixedBox"
          ></vueCropper>
        </div>
      </div>
    </a-modal>
  </div>
</template>

js

<script>
import { uploadImage } from '@/api/common'
import { VueCropper } from "vue-cropper";
export default {
  name: 'ImageUpload',
  components: { VueCropper },
  data() {
    return {
      loading: false,
      imageCut: {
        isShowModal: false,
        imgFile: '',
        init: imgFile => {
          this.imageCut.imgFile = imgFile
          this.imageCut.isShowModal = true
        },
        close: () => {
          this.imageCut.imgFile = ''
          this.imageCut.isShowModal = false
        }
      }
    }
  },
  props: {
    imageUrl: String,
    width: {
      type: String,
      default: '100px'
    },
    height:
      type: String,
      default: '100px'
    },
    canCut: {
      type: Boolean,
      default: false
    },
    info:
      type: Boolean,
      default: false
    }, // crop box size information outputSize: {
      type: Number,
      default: 0.8
    }, // The quality of the cropped image outputType: {
      type: String,
      default: 'jpeg'
    }, // Cropping to generate the image format canScale: {
      type: Boolean,
      default: true
    }, // Whether the image allows scroll wheel zooming autoCrop: {
      type: Boolean,
      default: true
    }, // Whether to generate a screenshot frame by default // autoCropWidth: 300, // The default width of the screenshot frame // autoCropHeight: 200, // The default height of the screenshot frame fixedBox: {
      type: Boolean,
      default: false
    }, // Fixed screenshot frame size cannot be changed fixed: {
      type: Boolean,
      default: true
    }, // Whether to enable the fixed ratio of the screenshot frame width and height fixedNumber: {
      type: Array,
      default: () => [1, 1]
    }, // The aspect ratio of the screenshot frame full: {
      type: Boolean,
      default: true
    }, // Whether to output the screenshot in the original proportion canMove: {
      type: Boolean,
      default: false
    },
    canMoveBox: {
      type: Boolean,
      default: true
    }, // Can the screenshot frame be dragged original: {
      type: Boolean,
      default: false
    }, // Render the uploaded image according to the original ratio centerBox: {
      type: Boolean,
      default: true
    }, // Is the screenshot box limited to the image? infoTrue: {
      type: Boolean,
      default: true
    } // true to display the actual output image width and height false to display the screenshot frame width and height },
  methods: {
    beforeUpload(file) {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
      if (!isJpgOrPng) {
        this.$message.error('Please upload a JPG or PNG file!')
      }
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isLt2M) {
        this.$message.error('Please upload a file below 2MB!')
      }
      return isJpgOrPng && isLt2M
    },
    customRequest(file) {
      if (this.canCut) {
        this.readFile(file.file)
      } else {
        this.loading = true
        const formData = new FormData()
        formData.append('fileIdcard', file.file)
        uploadImage(formData).then(res => {
          this.loading = false
          this.$emit('uploadSuccess', res.ossUrl)
        })
      }
    },
    readFile(file) {
      var reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        this.imageCut.init(reader.result)
      }
    },
    finish() {
      this.$refs.cropper.getCropBlob(data => {
        this.loading = true
        // Upload to Alibaba Cloud server const formData = new FormData()
        formData.append('fileIdcard', data)
        uploadImage(formData).then(res => {
          this.imageCut.close()
          this.loading = false
          this.$emit('uploadSuccess', res.ossUrl)
        })
      })
    }
  }
}
</script>

CSS

<style lang="less">
.avatar-uploader > .ant-upload {
  width: 100%;
  height: 100%;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
.cropper-content {
  .cropper {
    width: auto;
    height: 400px;
  }
}
</style>

Component usage and instructions

<image-upload
        :imageUrl="form.diagramUrl"
        @uploadSuccess="uploadSuccess"
        width="160px"
        height="90px"
        :can-edit="canCut"
        :fixed-number="[16,9]"
      />

When calling the component, you need to pass in the canEdit attribute to specify whether the component starts the cropping function after the image is selected. The default value is to disable cropping. When cropping is required, you can pass in the fixedNumber attribute to define the aspect ratio of the cropping box.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Vue implements throttle or debounce as a component or plug-in
  • Vue uses zTree plug-in to encapsulate tree component operation example
  • Example of custom paging plugin component in vue
  • Implementing the responsive adaptive carousel component plug-in VueSliderShow function based on Vue2x
  • Usage of vue custom global components (custom plug-ins)
  • The bootstrap select plugin is encapsulated as a Vue2.0 component
  • Summary of the differences and usage of plugins and components in Vue

<<:  Solution to the problem that Docker container cannot be stopped or killed

>>:  Some slightly more complex usage example codes in mysql

Recommend

Detailed explanation of vite2.0+vue3 mobile project

1. Technical points involved vite version vue3 ts...

MySQL 5.6 root password modification tutorial

1. After installing MySQL 5.6, it cannot be enabl...

Some common advanced SQL statements in MySQL

MySQL Advanced SQL Statements use kgc; create tab...

Detailed explanation of HTML document types

Mine is: <!DOCTYPE html> Blog Garden: <!...

VMware Workstation 14 Pro installs CentOS 7.0

The specific method of installing CentOS 7.0 on V...

Ubuntu 20.04 firewall settings simple tutorial (novice)

Preface In today's increasingly convenient In...

What are the attributes of the JSscript tag

What are the attributes of the JS script tag: cha...

A detailed introduction to for/of, for/in in JavaScript

Table of contents In JavaScript , there are sever...

A brief discussion on JavaScript throttling and anti-shake

Table of contents Throttling and anti-shake conce...

Analysis and solution of a.getAttribute(href,2) problem in IE6/7

Brief description <br />In IE6 and 7, in a ...

jQuery realizes the scrolling effect of table row data

This article example shares the specific code of ...

Share some key interview questions about MySQL index

Preface An index is a data structure that sorts o...