您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Springboot+Vue-Cropper如何實(shí)現(xiàn)頭像剪切上傳效果,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
先看一下效果吧,如果效果不能滿足你的需求,就不必再浪費(fèi)時(shí)間往下看了
點(diǎn)擊選擇圖片之后
然后再點(diǎn)擊上傳圖片就可以上傳成功,具體效果和頁(yè)面布局就是這樣
使用先建議詳細(xì)閱讀vue-cropper官方文檔,里面介紹的很詳細(xì),可以根據(jù)自己的需求進(jìn)行修改:鏈接
補(bǔ)充一點(diǎn):整個(gè)項(xiàng)目中使用了elelment-ui組件庫(kù),使用前先導(dǎo)入element-ui
關(guān)于解釋我會(huì)在代碼中添加注釋,畢竟知其然要知其所以然,學(xué)習(xí)還是得有溯源精神
<template> <div > <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs"> <el-tab-pane label="個(gè)人信息" name="first"> </el-tab-pane> <el-tab-pane label="更換頭像" name="second"> <div class="avatar_header"> <span>當(dāng)前頭像</span> </div> <div class="avatar_current"> <img :src="currentimg"> </div> <div class="avatar_select"> <!-- 這里這樣做是因?yàn)? 原來(lái)的 <input type="file">標(biāo)簽太丑了,可以自己去嘗試一下,看看有多丑 所以使用button來(lái)控制觸發(fā)input來(lái)進(jìn)行選擇文件 --> <input type="file" ref="uploads" id="uploads" accept="image/png, image/jpeg, image/gif, image/jpg" hidden @change="setImage($event)"> <el-button type="primary" @click="selectAvatar">選擇圖片</el-button> <el-button type="success" @click="uploadImg('blob')">上傳圖片</el-button> </div> <div class="cropper_box"> <div class="avatar_cropper"> <vue-cropper ref="cropper" :img="option.img" :outputSize="option.outputSize" :outputType="option.outputType" :info="option.info" :canScale="option.canScale" :autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :fixed="option.fixed" :fixedNumber="option.fixedNumber" :full="option.full" :fixedBox="option.fixedBox" :canMove="option.canMove" :canMoveBox="option.canMoveBox" :original="option.original" :centerBox="option.centerBox" :height="option.height" :infoTrue="option.infoTrue" :maxImgSize="option.maxImgSize" :enlarge="option.enlarge" :mode="option.mode" @realTime="realTime" @imgLoad="imgLoad"> </vue-cropper> </div> <div class="show_preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'margin': '5px'}"> <div :> <img :src="option.img" :> </div> </div> </div> </el-tab-pane> <el-tab-pane label="修改密碼" name="third"> </el-tab-pane> </el-tabs> </div> </template> <script> import qs from 'qs' import { VueCropper } from 'vue-cropper' export default { data() { return { activeName:'second', currentimg:this.$store.getters.getAvatar, //這里我是將用戶信息保存在Vuex進(jìn)行管理 previews:{}, option:{ img:'', //裁剪圖片的地址, outputSize:1, //裁剪生成的圖片質(zhì)量可選(0,1,-1) outputType:'jpeg', //裁剪生成圖片的格式 info:true, //圖片大小信息 canScale:true, //是否允許滾輪縮放 autoCrop:true, //是否默認(rèn)生成截圖框 autoCropWidth:240, autoCropHeight:240, //默認(rèn)生成截圖框大小 fixed:true, //是否開啟截圖框?qū)捀吖潭ū壤? fixedNumber:[1,1], //截圖框的寬高比, full:false, //按原比例裁剪圖片,不失真 fixedBox:true, //固定截圖框大小,不允許改變 canMove:false, //上傳圖片是否可以移動(dòng), canMoveBox:true, //截圖框是否可以拖動(dòng) original:false, //上傳圖片按照原始比例渲染 centerBox:false, //截圖框是否被限制在圖片里面 height:true, //是否按照設(shè)備的dpr,輸出等比例圖片 infoTrue:false, //true為展示真實(shí)輸出圖片寬高,false展示看到的截圖框?qū)捀撸? maxImgSize:3000, //限制圖片最大寬度和高度 enlarge:1, //圖片根據(jù)截圖框輸出比例倍數(shù) mode:'400px 300px' //圖片渲染方式 } } }, methods: { // 標(biāo)簽頁(yè)切換調(diào)用方法,不重要!刪掉了一些不必要的代碼 handleClick(){ }, // 選擇圖片調(diào)用方法 selectAvatar(){ this.$refs.uploads.click(); }, // 真正的選擇圖片方法,姑且先這么命名吧 setImage(e){ let file = e.target.files[0]; if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) { // this.$message.info("圖片類型不正確"); console.log("圖片類型不正確"); return false; } //轉(zhuǎn)化為blob,使用blob是為了在頁(yè)面中展示上傳的那張圖片 let reader = new FileReader(); // 文件讀取成功后觸發(fā)onload方法 reader.onload = (e) => { let data; // 要在頁(yè)面中展示,轉(zhuǎn)化為url形式 if(typeof e.target.result === 'object'){ data = window.URL.createObjectURL(new Blob([e.target.result])) }else{ data = e.target.result } this.option.img = data //轉(zhuǎn)化為base64 } reader.readAsDataURL(file) }, realTime(data){ this.previews = data; }, //初始化函數(shù) imgLoad(msg){ console.log("工具初始化函數(shù)====="+msg); }, // 頭像上傳調(diào)用方法 uploadImg(type){ let _this = this; if(type === 'blob'){ //獲取截圖的blob數(shù)據(jù)類型 this.$refs.cropper.getCropBlob(async (data) => { let formData = new FormData(); // 發(fā)數(shù)據(jù)傳遞到后端,注意這里請(qǐng)根據(jù)自己的后端邏輯進(jìn)行處理,我是將用戶名保存在Vuex中,可以直接進(jìn)行命名 formData.append("username",this.$store.getters.getUsername); formData.append('file',data,this.$store.getters.getUsername+".jpg"); this.axios.post('/updateavatar',formData).then(function(response){ console.log(response); if(response.data.code == 200){ console.log(response); _this.currentimg = response.data.data; _this.$store.commit('setAvatar',response.data.data); //把新頭像重新保存回Vuex _this.$router.go(0); //刷新網(wǎng)頁(yè) } }) }) } } }, components:{VueCropper} }; </script> <style scoped> .tab-create{ position: absolute; right: 80px; top: 115px; margin-top: 5px; z-index: 999; } .avatar_header{ width: 100%; height: 50px; font-size: 14; line-height: 50px; font-weight: 550; padding-left: 20px; text-align: left; } .avatar_current{ width: 100%; height: 260px; text-align: left; } .avatar_current img{ width: 240px; height: 240px; margin-left: 20px; } .avatar_select{ text-align: left; } .cropper_box{ text-align: left; position: relative; } .avatar_cropper{ margin-top: 40px; height: 350px; width: 450px; display: inline-block; } .show_preview{ display: inline-block; position: absolute; top:30px; left: 500px; } </style>
后端代碼
這里先講述后端的處理邏輯:
1、獲取到頭像后,會(huì)將圖片保存在云服務(wù)器上,這里我們?cè)O(shè)定的自己的靜態(tài)文件目錄在D盤,見static_root。
2、然后將圖片在云服務(wù)器上的url保存在后端mysql數(shù)據(jù)庫(kù)中。
3、返回給前端上傳成功的消息,攜帶圖片的url這樣就可以通過(guò)url訪問(wèn)到這張圖片,從而在前端進(jìn)行顯示。
Controller層
@ResponseBody @PostMapping("/updateavatar") public Result updateAvatar(@RequestParam("username") String username,@RequestParam("file") MultipartFile file) throws IOException { return userService.uploadAvatar(username,file); }
Service層直接上impl實(shí)現(xiàn)
//這是導(dǎo)的工具包,需要在pom.xml安裝依賴 import cn.hutool.core.io.FileUtil; //一些端口信息 @Value("${server.port}") private String port; private static final String ip = "http://localhost"; private static final String static_root = "D:/devplatform_files"; @Override public Result uploadAvatar(String username, MultipartFile file) throws IOException { //獲取原文件的名稱 String originalFilename = file.getOriginalFilename(); // String rootFilePath = System.getProperty("user.dir")+"/src/main/resources/files/"+originalFilename; //獲取到文件路徑 String rootFilePath = static_root +"/avatar/"+ originalFilename; //保存在文件中 FileUtil.writeBytes(file.getBytes(),rootFilePath); //圖片訪問(wèn)用到的url String avatar = ip+":"+port+"/avatar/"+originalFilename; try{ //頭像信息存入數(shù)據(jù)庫(kù) userMapper.updateAvatar(avatar,username); //自己封裝的Result結(jié)果返回類 return Result.success(200,"上傳成功",avatar); }catch (Exception e){ System.out.println(e); return Result.fail("上傳失敗"); } }
mapper持久層
@Mapper @Repository public interface UserMapper{ String getAvatarByUsername(String username); }
mapper.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.devplatform.mapper.UserMapper"> <update id="updateAvatar"> update user set avatar = #{avatar} where username = #{username} </update> </mapper>
關(guān)于Result結(jié)果類的封裝
public class Result { private int code; //200是正常 非200表示異常 private String msg; private Object data; public static Result success(Object data){ return success(200,"操作成功",data); } public static Result success(String msg){ return success(200,msg,null); } public static Result success(int code, String msg, Object data){ Result r = new Result(); r.setCode(code); r.setData(data); r.setMsg(msg); return r; } public static Result fail(String msg){ return fail(400, msg, null); } public static Result fail(String msg, Object data){ return fail(400, msg, data); } public static Result fail(int code, String msg, Object data){ Result r = new Result(); r.setCode(code); r.setData(data); r.setMsg(msg); return r; } public int getCode() {return code;} public void setCode(int code) {this.code = code;} public String getMsg() {return msg;} public void setMsg(String msg) {this.msg = msg;} public Object getData() {return data;} public void setData(Object data) {this.data = data;} }
當(dāng)圖片保存在云服務(wù)器上后,就可以通過(guò)url直接訪問(wèn)到圖片了,這里我本地展示這一效果,實(shí)現(xiàn)了這一效果,前端才能夠在img標(biāo)簽中訪問(wèn)到圖片。
關(guān)于“Springboot+Vue-Cropper如何實(shí)現(xiàn)頭像剪切上傳效果”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。