基于vue-cropper的上传裁剪后的头像
No.1
需求
上传头像
图片格式为jpg/jpge || png,大小为1M以内
上传头像必须进行裁剪
No.2
思路
选择图片作为头像。
上传图片前进行判断,符合要求就进行下一步,不符合要求,则提示错误。
符合要求后,到裁剪页面,进行图片裁剪。
裁剪完成后,在进行上传图片。
显示上传成功后的头像。
以上,就是上次头像的大概思路了。接下来,就是如何开发。
No.3
开发
安装vue-cropper
vue-cropper的官网:
https://github.com/xyxiao001/vue-cropper
在项目根目录打开cmd输入安装指令:
npm install vue-cropper
封装vue-cropper
安装成功后,因为我是封装成一个组件,所以,我先创建一个vue文件,用于封装cropper组件。
template模板内容
<!--裁剪图片 组件传参:1、show.sync 是否显示 Boolean false2、url 上传文件路径 String3、callback 返回裁剪后的图片路径 function(data)4、close 右上角关闭按钮 function()5、shadebackground 更改遮罩层的背景颜色6、shadeopacity 更改遮罩层的透明度--><template><el-dialog title="裁剪图片" :visible.sync="visible" @close="close"><div id="cropper"><VueCropperref="cropper":img="src":outputSize="option.outputSize":outputType="option.outputType":canMove="option.canMove":autoCrop="option.autoCrop":autoCropWidth="option.autoCropWidth":autoCropHeight="option.autoCropHeight":fixedBox="option.fixedBox":original="option.original":infoTrue="option.infoTrue":centerBox="option.centerBox":canMoveBox="option.canMoveBox":canScale="option.canScale"></VueCropper></div><span slot="footer" class="dialog-footer"><el-button type="primary" @click="startCrop()">确 定</el-button></span></el-dialog></template>
javascript内容
option是剪裁插件的属性配置,具体更多含义查看官网介绍
<script>import { VueCropper } from "vue-cropper";export default {props: {show: {type: Boolean,default: false},src: {type: String,default: ''},shadebackground: {type: String,default: "#000"},shadeopacity: {type: String,default: ".5"}},components: { VueCropper },data() {return {option: {outputSize: 1, // 裁剪生成图片的质量 0.1 - 1outputType: "jepg", // 裁剪生成图片的格式 jpeg || png || webpcanScale: true, // 图片是否允许滚轮缩放 默认trueautoCrop: true, // 是否默认生成截图框 默认falsecanMove: true, //上传图片是否可以移动 默认trueautoCropWidth: 367, //默认生成截图框宽度 容器的80% 0~maxautoCropHeight: 280, //默认生成截图框高度 容器的80% 0~maxfixedBox: true, //是否开启截图框宽高固定比例original: false, // 上传图片按照原始比例渲染 false true | falseinfoTrue: true, // 为展示真实输出图片宽高 false 展示看到的截图框宽高 false true | falsecenterBox: true, // 截图框是否被限制在图片里面 false true | falsecanMoveBox: false, //截图框能否拖动 true true | false},visible: this.show,modal: {}};},methods: {// 开始截图startCrop() {let othis = this;othis.$refs.cropper.getCropData(function(data){let arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}let type = mime.split('/')[1];let newfile = new File([u8arr], "newimg" + "." + type, { type: mime });let URL = window.URL || window.webkitURL;let newimg = URL.createObjectURL(newfile);othis.modal.backgroundColor = "#000"; //裁剪的背景色othis.modal.opacity = ".5"; //裁剪的透明度othis.$emit("callback",newimg); //子传父 返回裁剪后的图片路径});},//右上角关闭弹窗close(){let othis = this;othis.modal.backgroundColor = "#000";othis.modal.opacity = ".5";othis.$emit("callback");}},watch: {show () {let othis = this;othis.visible = othis.show;othis.modal = othis.$tools.getstyle(".v-modal");othis.modal.backgroundColor = othis.shadebackground;othis.modal.opacity = othis.shadeopacity;}}}</script>
css内容
剪裁框的样式
<style>#cropper {margin: 0 auto;height: 350px;}</style>
No.4
使用
我使用的是ElementUI的上传图片的模块
template模板数据
<template><div><el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" drag :auto-upload="false" :show-file-list="false" :on-change='changeUpload'><img v-if="details.qrCode" :src="details.qrCode" class="avatars2"><div v-else class="avatar-uploader-icon"><i class=" el-icon-upload"></i><p class="el-upload__text f14">上传头像</p><p class="el-upload__tip red" slot="tip">格式jpg/png,不超1M</p></div></el-upload><cropper-all :show.sync="cropperShow" :src="cropperImg" @callback="callback"></cropper-all></div></template>
使用element-ui的上传按钮,要配置:auto-upload="false"(不要自动上传), :on-change='changeUpload'(选择完图片后的方法)
在当前页面引入封装的组件
import cropperAll from '@/components/cropper.js'
data数据
data() {return {//显示剪切cropperShow: false,cropperImg: '',//头像details: {qrCode: ''},};},
methods方法
/*** 上传按钮* @param {Object} file 上传文件返回的数据*/changeUpload(file){const isLt1M = file.size / 1024 / 1024 < 1if (!isLt1M) {this.$message.error('上传文件大小不能超过 1MB!')return false}// 上传成功后将图片地址赋值给裁剪框显示图片this.$nextTick(() => {this.cropperImg = URL.createObjectURL(file.raw)this.cropperShow = true})},/*** 接收裁剪后的图片* @param {String} img 裁剪后的图片路径*/callback(img){if(img) this.details.qrCode = img;this.cropperShow = false;this.cropperImg = ''}
No.5
效果
希望对大家有帮助,共勉!
更多前端分享,请关注:
前端路人甲
