The way to efficiently implement requirements is to avoid reinventing the wheel. There are also many plugins for picture clipping. I choose Vue-Cropper here because it is powerful, simple and easy to use. Without further ado, on the renderings:
rendering
The installation
npm install vue-cropper
Copy the code
use
import { VueCropper } from 'vue-cropper'
Copy the code
Code implementation
Take Element-UI + vue-cropper as an example to achieve profile picture clipping
src/App.vue
<template> <div> <el-button @click="dialogVisible = true"> Upload avatar </el-button> <avatar-cropper :dialogVisible.sync="dialogVisible" @closeAvatarDialog="closeAvatarDialog"></avatar-cropper> </div> </template> <script> import avatarCropper from '@/components/avatarCropper' export default { components: { avatarCropper }, data() { return { dialogVisible: false } }, methods: { closeAvatarDialog(data) { console.log(data) this.dialogVisible = false } } } </script>Copy the code
src/components/avatarCropper.vue
<template> <el-dialog title=" cut profile picture ":visible.sync="dialogVisible" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false" @close="closeDialog" width="600px" > <div class="avatar-container"> <! <div v-show="! options.img"> <el-upload class="upload" ref="upload" action="" :on-change="upload" accept="image/png, image/jpeg, image/jpg" :show-file-list="false" :auto-upload="false" > <el-button slot="trigger" size="small" type="primary" Ref ="uploadBtn"> select uploadBtn </el-button> </el-upload> <div> JPG, PNG, no more than 5M</div> </div> </div> <! <div v-show="options.img" class="avatar-crop"> <vueCropper v-if="dialogVisible" class="crop-box" ref="cropper" :img="options.img" :autoCrop="options.autoCrop" :fixedBox="options.fixedBox" :canMoveBox="options.canMoveBox" :autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight" :centerBox="options.centerBox" :fixed="options.fixed" :fixedNumber="options.fixedNumber" :canMove="options.canMove" :canScale="options.canScale" ></vueCropper> </div> </div> <span slot="footer" class="dialog-footer"> <div Class ="reupload" @click="reupload"> <span v-show="options.img" @click="closeDialog"> </el-button> <el-button type="primary" @click="getCrop"> </el-dialog> </template> <script> import { VueCropper } from 'vue-cropper' export default { components: { VueCropper }, name: 'avatarCropper', props: { dialogVisible: { type: Boolean, default: False}}, data() {return {// vueCropper component clipping configuration information options: {img: ", // autoCrop: true, // default generated screenshot box fixedBox: CanMoveBox: true, // Can drag autoCropWidth: 200, // autoCropHeight: 200, // Fixed: FixedNumber: [1, 1], // centerBox: true, // canMove: CanScale: false}}}, methods: {{/ / read the original upload (file) const isIMAGE = file. Raw. Type = = = 'image/jpeg' | | file. Raw. Type = = = 'image/PNG' const isLt5M = file.raw.size / 1024 / 1024 < 5 if (! $message({showClose: true, message: 'please select JPG, PNG ', type: 'warning'}) return false} if (! IsLt5M) {this.$message({showClose: true, message: 'image size cannot exceed 5MB', type: 'warning' }) return false } let reader = new FileReader() reader.readAsDataURL(file.raw) reader.onload = e => { this.options.img = e.target.result // base64 } }, $refs.cropper.getCropData((data) => {// getCrop() {$refs.cropper.getcropData ((data) => {// this.$emit('closeAvatarDialog', data) // this.closeDialog() // }); $emit('closeAvatarDialog', $emit('closeAvatarDialog', $emit('closeAvatarDialog'), CloseDialog () {this.uploadbtn.$el.click()}, // Close closeDialog() {this.$emit('update:dialogVisible', false) this.options.img = '' } } } </script> <style lang="scss" scoped> .dialog-footer { display: flex; justify-content: space-between; align-items: center; font-size: 14px; .reupload { color: #409eff; cursor: pointer; } } .avatar-container { display: flex; justify-content: center; align-items: center; width: 560px; height: 400px; background-color: #f0f2f5; margin-right: 10px; border-radius: 4px; .upload { text-align: center; margin-bottom: 24px; } .avatar-crop { width: 560px; height: 400px; position: relative; .crop-box { width: 100%; height: 100%; border-radius: 4px; overflow: hidden; } } } </style>Copy the code
conclusion
Once clipping is complete, base64 and BLOB data can be retrieved and uploaded to the back end. Vue-cropper also has a number of properties and methods that are very easy to use and can be previewed in real time if you are interested.
Do not forget to click a praise yo, I heard that the next year’s promotion and pay rise, love business double harvest 😃