高效实现需求的办法,就是防止反复造轮子。图片裁剪的插件也不少,这里我抉择 vue-cropper,起因是功能强大、简略易上手。话不多说,上效果图:
效果图
装置
npm install vue-cropper
应用
import { VueCropper } from 'vue-cropper'
代码实现
以 element-ui + vue-cropper 为例实现头像裁剪
src/App.vue
<template> <div> <el-button @click="dialogVisible = true">上传头像</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>
src/components/avatarCropper.vue
<template> <el-dialog title="裁剪头像" :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"> 抉择图片 </el-button> </el-upload> <div>反对jpg、png格局的图片,大小不超过5M</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">从新上传</span> </div> <div> <el-button @click="closeDialog">取 消</el-button> <el-button type="primary" @click="getCrop">确 定</el-button> </div> </span> </el-dialog></template><script>import { VueCropper } from 'vue-cropper'export default { components: { VueCropper }, name: 'avatarCropper', props: { dialogVisible: { type: Boolean, default: false } }, data() { return { // vueCropper组件 裁剪配置信息 options: { img: '', // 原图文件 autoCrop: true, // 默认生成截图框 fixedBox: false, // 固定截图框大小 canMoveBox: true, // 截图框能够拖动 autoCropWidth: 200, // 截图框宽度 autoCropHeight: 200, // 截图框高度 fixed: true, // 截图框宽高固定比例 fixedNumber: [1, 1], // 截图框的宽高比例 centerBox: true, // 截图框被限度在图片外面 canMove: false, // 上传图片不容许拖动 canScale: false // 上传图片不容许滚轮缩放 } } }, methods: { // 读取原图 upload(file) { const isIMAGE = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png' const isLt5M = file.raw.size / 1024 / 1024 < 5 if (!isIMAGE) { this.$message({ showClose: true, message: '请抉择 jpg、png 格局的图片', type: 'warning' }) return false } if (!isLt5M) { this.$message({ showClose: true, message: '图片大小不能超过 5MB', type: 'warning' }) return false } let reader = new FileReader() reader.readAsDataURL(file.raw) reader.onload = e => { this.options.img = e.target.result // base64 } }, // 获取截图信息 getCrop() { // 获取截图的 base64 数据 // this.$refs.cropper.getCropData((data) => { // this.$emit('closeAvatarDialog', data) // this.closeDialog() // }); // 获取截图的 blob 数据 this.$refs.cropper.getCropBlob(data => { this.$emit('closeAvatarDialog', data) this.closeDialog() }) }, // 从新上传 reupload() { this.$refs.uploadBtn.$el.click() }, // 敞开弹框 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>
总结
裁剪实现之后能够获取到 base64 和 blob 数据,而后上传至后端。vue-cropper 还有泛滥属性和办法,用起来都很不便,有趣味的同学能够实现一下实时预览。
文档地址:https://github.com/xyxiao001/...
看完不要忘了点个赞呦,据说点赞的来年升职加薪,恋情事业双丰收