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

Analysis and summary of the impact of MySQL transactions on efficiency

1. Database transactions will reduce database per...

Pure CSS to achieve three-dimensional picture placement effect example code

1. Percentage basis for element width/height/padd...

Detailed explanation of Vue's monitoring method case

Monitoring method in Vue watch Notice Name: You s...

Practical experience of implementing nginx to forward requests based on URL

Preface Because this is a distributed file system...

MySQL detailed explanation of isolation level operation process (cmd)

Read uncommitted example operation process - Read...

Beginners learn some HTML tags (2)

Related article: Beginners learn some HTML tags (1...

Implementing login page based on layui

This article example shares the specific code of ...

How to load third-party component libraries on demand in Vue3

Preface Take Element Plus as an example to config...

Vue Learning - VueRouter Routing Basics

Table of contents 1. VueRouter 1. Description 2. ...

Summary of methods to improve mysql count

I believe many programmers are familiar with MySQ...

Mysql database recovery actual record by time point

Introduction: MySQL database recovery by time poi...

How to simply configure multiple servers in nginx

1: I won’t go into the details of how to install ...