vlambda博客
学习文章列表

基于vue-cropper的上传裁剪后的头像

No.1

需求

  1. 上传头像

  2. 图片格式为jpg/jpge || png,大小为1M以内

  3. 上传头像必须进行裁剪

No.2

思路

  1. 选择图片作为头像。

  2. 上传图片前进行判断,符合要求就进行下一步,不符合要求,则提示错误。

  3. 符合要求后,到裁剪页面,进行图片裁剪。

  4. 裁剪完成后,在进行上传图片。

  5. 显示上传成功后的头像。

以上,就是上次头像的大概思路了。接下来,就是如何开发。

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 false 2、url 上传文件路径 String 3、callback 返回裁剪后的图片路径 function(data) 4、close 右上角关闭按钮 function() 5、shadebackground 更改遮罩层的背景颜色  6、shadeopacity 更改遮罩层的透明度--><template> <el-dialog title="裁剪图片" :visible.sync="visible" @close="close"> <div id="cropper"> <VueCropper ref="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 - 1 outputType: "jepg", // 裁剪生成图片的格式 jpeg || png || webp canScale: true, // 图片是否允许滚轮缩放 默认true autoCrop: true, // 是否默认生成截图框 默认false canMove: true, //上传图片是否可以移动 默认true autoCropWidth: 367, //默认生成截图框宽度 容器的80% 0~max autoCropHeight: 280, //默认生成截图框高度 容器的80% 0~max fixedBox: true, //是否开启截图框宽高固定比例 original: false, // 上传图片按照原始比例渲染 false true | false infoTrue: true, // 为展示真实输出图片宽高 false 展示看到的截图框宽高 false true | false centerBox: true, // 截图框是否被限制在图片里面 false true | false canMoveBox: 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 < 1 if (!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

效果

希望对大家有帮助,共勉!





更多前端分享,请关注:



前端路人甲