您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

Springboot+Vue-Cropper实现头像剪切上传效果

51自学网 2022-05-02 21:33:47
  javascript

使用Vue-Cropper这一组件实现头像上传,供大家参考,具体内容如下

效果展示

先看一下效果吧,如果效果不能满足你的需求,就不必再浪费时间往下看了

点击选择图片之后

然后再点击上传图片就可以上传成功,具体效果和页面布局就是这样

前端代码

使用先建议详细阅读vue-cropper官方文档,里面介绍的很详细,可以根据自己的需求进行修改:链接

补充一点:整个项目中使用了elelment-ui组件库,使用前先导入element-ui

关于解释我会在代码中添加注释,毕竟知其然要知其所以然,学习还是得有溯源精神

<template>  <div style="height: 800px;">    <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs">      <el-tab-pane label="个人信息" name="first">      </el-tab-pane>      <el-tab-pane label="更换头像" name="second">        <div class="avatar_header">          <span>当前头像</span>        </div>        <div class="avatar_current">          <img :src="currentimg">        </div>        <div class="avatar_select">          <!-- 这里这样做是因为          原来的 <input type="file">标签太丑了,可以自己去尝试一下,看看有多丑          所以使用button来控制触发input来进行选择文件          -->          <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" style="margin-left:100px;" @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 :style="previews.div">            <img :src="option.img" :style="previews.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进行管理      previews:{},      option:{        img:'',                //裁剪图片的地址,        outputSize:1,          //裁剪生成的图片质量可选(0,1,-1)        outputType:'jpeg',     //裁剪生成图片的格式        info:true,             //图片大小信息        canScale:true,         //是否允许滚轮缩放        autoCrop:true,         //是否默认生成截图框        autoCropWidth:240,        autoCropHeight:240,    //默认生成截图框大小        fixed:true,            //是否开启截图框宽高固定比例        fixedNumber:[1,1],     //截图框的宽高比,        full:false,            //按原比例裁剪图片,不失真        fixedBox:true,         //固定截图框大小,不允许改变        canMove:false,         //上传图片是否可以移动,        canMoveBox:true,       //截图框是否可以拖动        original:false,        //上传图片按照原始比例渲染        centerBox:false,       //截图框是否被限制在图片里面        height:true,           //是否按照设备的dpr,输出等比例图片        infoTrue:false,        //true为展示真实输出图片宽高,false展示看到的截图框宽高,        maxImgSize:3000,       //限制图片最大宽度和高度        enlarge:1,             //图片根据截图框输出比例倍数        mode:'400px 300px'     //图片渲染方式       }    }  },  methods: {    // 标签页切换调用方法,不重要!删掉了一些不必要的代码    handleClick(){    },    // 选择图片调用方法    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;      }      //转化为blob,使用blob是为了在页面中展示上传的那张图片      let reader = new FileReader();      // 文件读取成功后触发onload方法      reader.onload = (e) => {        let data;        // 要在页面中展示,转化为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        //转化为base64      }      reader.readAsDataURL(file)    },    realTime(data){      this.previews = data;    },    //初始化函数     imgLoad(msg){      console.log("工具初始化函数====="+msg);    },    // 头像上传调用方法    uploadImg(type){      let _this = this;      if(type === 'blob'){        //获取截图的blob数据类型        this.$refs.cropper.getCropBlob(async (data) => {          let formData = new FormData();          // 发数据传递到后端,注意这里请根据自己的后端逻辑进行处理,我是将用户名保存在Vuex中,可以直接进行命名          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);                                   //刷新网页                          }          })        })      }    }  },  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、获取到头像后,会将图片保存在云服务器上,这里我们设定的自己的静态文件目录在D盘,见static_root。
2、然后将图片在云服务器上的url保存在后端mysql数据库中。
3、返回给前端上传成功的消息,携带图片的url这样就可以通过url访问到这张图片,从而在前端进行显示。

Controller层

@ResponseBody@PostMapping("/updateavatar")    public Result updateAvatar(@RequestParam("username") String username,@RequestParam("file") MultipartFile file) throws IOException {        return userService.uploadAvatar(username,file);    }

Service层直接上impl实现

 //这是导的工具包,需要在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);        //图片访问用到的url        String avatar = ip+":"+port+"/avatar/"+originalFilename;        try{            //头像信息存入数据库            userMapper.updateAvatar(avatar,username);            //自己封装的Result结果返回类            return Result.success(200,"上传成功",avatar);        }catch (Exception e){            System.out.println(e);            return Result.fail("上传失败");        }    }

mapper持久层

@Mapper@Repositorypublic 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>

关于Result结果类的封装

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;}}

当图片保存在云服务器上后,就可以通过url直接访问到图片了,这里我本地展示这一效果,实现了这一效果,前端才能够在img标签中访问到图片。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持wanshiok.com。


JavaScript实现烟花特效(面向对象)
Vue2.x配置路由导航守卫实现用户登录和退出
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1