vue-cropper组件实现图片切割上传


Posted in Vue.js onMay 27, 2021

本文实例为大家分享了vue-cropper组件实现图片切割上传的具体代码,供大家参考,具体内容如下

这几日,等来了些空闲,用vue和spring boot实践一次头像上传,因此记下了,望将来的开发有所帮助。

vue-cropper在vue中的引入

1、组件内引入

import { VueCropper }  from 'vue-cropper' 
components: {
  VueCropper,
},

2、全局引入

在main.js中配置如下代码

import VueCropper from 'vue-cropper' 

Vue.use(VueCropper)

3、使用示例

vue文件

<template>
  <el-dialog
    title="编辑头像"
    :visible.sync="dialogFormVisible"
    :close-on-click-modal="false"
    append-to-body
  >
    <label class="btn" for="uploads">选择图片</label>
    <input
      type="file"
      id="uploads"
      :value="imgFile"
      style="position:absolute; clip:rect(0 0 0 0);"
      accept="image/png, image/jpeg, image/gif, image/jpg"
      @change="uploadImg($event, 1)"
    >
    <div style="margin-left:20px;">
      <div class="show-preview" :style="{'overflow': 'hidden', 'margin': '5px'}">
        <div :style="previews.div" class="preview" style="width: 40px;height: 40px;">
          <img :src="previews.url" :style="previews.img">
        </div>
      </div>
    </div>
    <div class="cut">
      <vueCropper
        ref="cropper"
        :img="option.img"
        :outputSize="option.size"
        :outputType="option.outputType"
        :info="true"
        :full="option.full"
        :canMove="option.canMove"
        :canMoveBox="option.canMoveBox"
        :original="option.original"
        :autoCrop="option.autoCrop"
        :autoCropWidth="option.autoCropWidth"
        :autoCropHeight="option.autoCropHeight"
        :fixedBox="option.fixedBox"
        @realTime="realTime"
        @imgLoad="imgLoad"
      ></vueCropper>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false" size="small">取 消</el-button>
      <el-button type="primary" @click="finish('blob')" size="small">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { VueCropper } from "vue-cropper";
export default {
  components: {
    VueCropper
  },
  data() {
    return {
      previews: {},
      model: false,
      modelSrc: "",
      fileName: "",
      imgFile: "",
      dialogFormVisible: false,
      option: {
        img: "",
        outputSize: 1, //剪切后的图片质量(0.1-1)
        full: false, //输出原图比例截图 props名full
        outputType: "png",
        canMove: true,
        original: false,
        canMoveBox: true,
        autoCrop: true,
        autoCropWidth: 40,
        autoCropHeight: 40,
        fixedBox: true
      }
    };
  },
  methods: {
    //上传图片(点击上传按钮)
    finish(type) {
      let selft = this;
      let formData = new FormData();
      // 输出
      if (type === "blob") {
        selft.$refs.cropper.getCropBlob(data => {
          let img = window.URL.createObjectURL(data);
          selft.model = true;
          selft.modelSrc = img;
          formData.append("file", data, selft.fileName);
          selft.$api.writer.userUpload(formData, r => {
            if (r.code) {
              selft.$alert.error(r.msg);
            } else {
              selft.$message({
                message: r.data.msg,
                type: "success"
              });
              selft.$store.state.userInfo = r.data.data;
              selft.dialogFormVisible = false;
            }
          });
        });
      } else {
        this.$refs.cropper.getCropData(data => {});
      }
    },
    //选择本地图片
    uploadImg(e, num) {
      console.log("uploadImg");
      var selft = this;
      //上传图片
      var file = e.target.files[0];
      selft.fileName = file.name;
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alert("图片类型必须是.gif,jpeg,jpg,png,bmp中的一种");
        return false;
      }
      var reader = new FileReader();
      reader.onload = e => {
        let data;
        if (typeof e.target.result === "object") {
          // 把Array Buffer转化为blob 如果是base64不需要
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        if (num === 1) {
          selft.option.img = data;
        } else if (num === 2) {
          selft.example2.img = data;
        }
      };
      // 转化为base64
      // reader.readAsDataURL(file)
      // 转化为blob
      reader.readAsArrayBuffer(file);
    },
    show() {
      this.dialogFormVisible = true;
    },
    // 实时预览函数
    realTime(data) {
      console.log("realTime");
      this.previews = data;
    },
    imgLoad(msg) {
      console.log("imgLoad");
      console.log(msg);
    }
  }
};
</script>

<style lang="less">
@import "./userLogo.less";
</style>

less文件

.cut {
    width: 300px;
    height: 300px;
    margin: 0px auto;
}

.hh {
    .el-dialog__header {
        padding: 0px;
        line-height: 2;
        background-color: #f3f3f3;
        height: 31px;
        border-bottom: 1px solid #e5e5e5;
        background: #f3f3f3;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
    }
    .el-dialog__title {
        float: left;
        height: 31px;
        color: #4c4c4c;
        font-size: 12px;
        line-height: 31px;
        overflow: hidden;
        margin: 0;
        padding-left: 10px;
        font-weight: bold;
        text-shadow: 0 1px 1px #fff;
    }
    .el-dialog__headerbtn {
        position: absolute;
        top: 8px;
        right: 10px;
        padding: 0;
        background: 0 0;
        border: none;
        outline: 0;
        cursor: pointer;
        font-size: 16px;
    }
}

.btn {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #c0ccda;
    color: #1f2d3d;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    //margin: 20px 10px 0px 0px;
    padding: 9px 15px;
    font-size: 14px;
    border-radius: 4px;
    color: #fff;
    background-color: #50bfff;
    border-color: #50bfff;
    transition: all 0.2s ease;
    text-decoration: none;
    user-select: none;
}

.show-preview {
    flex: 1;
    -webkit-flex: 1;
    display: flex;
    display: -webkit-flex;
    justify-content: center;
    -webkit-justify-content: center;
    .preview {
        overflow: hidden;
        border-radius: 50%;
        border: 1px solid #cccccc;
        background: #cccccc;
    }
}

发送请求的时候配置axios的Content-Type

// http request 拦截器
axios.interceptors.request.use(
  config => {debugger
    let token = sessionStorage.getItem('token')
    if (token) {
      config.headers.Authorization = token;
    }
    if (config && config.url && config.url.indexOf('upload') > 0) {
      config.headers['Content-Type'] = 'multipart/form-data'
    }
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

boot的controller

@RequestMapping("/upload")
 public ResultData upload(@RequestParam("file") MultipartFile file) {
  return userService.upload(file);
 }

boot的service

@Override
 public ResultData upload(MultipartFile file) {
  if (!file.isEmpty()) {
   
   StringBuffer requestURL = sessionUtil.getRequestURL();
   int end = requestURL.indexOf("/user/upload");
   String basePath = requestURL.substring(0, end);
   String savePath = basePath + "/static/img/logo/";
   // 获取文件名称,包含后缀
   String fileName = file.getOriginalFilename();

   String saveDbPath = savePath + fileName;

   // 存放在这个路径下:该路径是该工程目录下的static文件下:(注:该文件可能需要自己创建)
   // 放在static下的原因是,存放的是静态文件资源,即通过浏览器输入本地服务器地址,加文件名时是可以访问到的
   String path = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/img/logo/";

   // 该方法是对文件写入的封装,在util类中,导入该包即可使用,后面会给出方法
   try {
    FileUtil.fileupload(file.getBytes(), path, fileName);
    // 接着创建对应的实体类,将以下路径进行添加,然后通过数据库操作方法写入
    User user = sessionUtil.getSessionUser();
    user.setLogo(saveDbPath);
    User whereUser = new User();
    whereUser.setId(user.getId());
    ConfigHelper.upate(user, "user", whereUser);
    Map<String, Object> map = new HashMap<>();
    map.put("msg", "头像修改成功");
    map.put("data", user);
    return ResultData.ok(map);
   } catch (IOException e) {
    log.error("图片上传==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   } catch (Exception e) {
    log.error("图片上次==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   }

  } else {
   return ResultData.failed("上传图片失败");
  }
 }

结束

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
VUE中鼠标滚轮使div左右滚动的方法详解
Dec 14 Vue.js
vue使用过滤器格式化日期
Jan 20 Vue.js
vue 计算属性和侦听器的使用小结
Jan 25 Vue.js
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
vue-video-player 断点续播的实现
Feb 01 Vue.js
Vue实现todo应用的示例
Feb 20 Vue.js
vue中data改变后让视图同步更新的方法
Mar 29 Vue.js
深入理解Vue的数据响应式
May 15 Vue.js
vue2实现provide inject传递响应式
May 21 Vue.js
浅谈Vue的computed计算属性
Mar 21 Vue.js
Vue OpenLayer测距功能的实现
Apr 20 Vue.js
Vue3实现简易音乐播放器组件
Aug 14 Vue.js
vue-cropper插件实现图片截取上传组件封装
May 27 #Vue.js
HTML+VUE分页实现炫酷物联网大屏功能
Vue实现动态查询规则生成组件
详解vue身份认证管理和租户管理
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
You might like
php学习笔记 PHP面向对象的程序设计
2011/06/13 PHP
PHP函数之日期时间函数date()使用详解
2013/09/09 PHP
使用php自动备份数据库表的实现方法
2017/07/28 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser
2007/11/30 Javascript
JSQL 基于客户端的成绩统计实现方法
2010/05/05 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
JS实现固定在右下角可展开收缩DIV层的方法
2015/02/13 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
2016/09/04 Javascript
浅谈JavaScript事件绑定的常用方法及其优缺点分析
2016/11/01 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
QML实现圆环颜色选择器
2019/09/25 Javascript
PHP读取远程txt文档到数组并实现遍历
2020/08/25 Javascript
[03:43]2014DOTA2西雅图国际邀请赛 newbee战队巡礼
2014/07/07 DOTA
Python类的动态修改的实例方法
2017/03/24 Python
详解python基础之while循环及if判断
2017/08/24 Python
浅析Git版本控制器使用
2017/12/10 Python
python unittest实现api自动化测试
2018/04/04 Python
Python实现多条件筛选目标数据功能【测试可用】
2018/06/13 Python
python实现自动解数独小程序
2019/01/21 Python
python3 下载网络图片代码实例
2019/08/27 Python
用Python画小女孩放风筝的示例
2019/11/23 Python
pytorch梯度剪裁方式
2020/02/04 Python
Python安装与卸载流程详细步骤(图解)
2020/02/20 Python
Python3 shelve对象持久存储原理详解
2020/03/23 Python
使用Python-OpenCV消除图像中孤立的小区域操作
2020/07/05 Python
浅析Python 条件控制语句
2020/07/15 Python
医学专业毕业生推荐信
2013/11/14 职场文书
土木工程专业个人求职信
2013/12/30 职场文书
教师党员思想汇报
2014/01/06 职场文书
红领巾心向党广播稿
2014/01/19 职场文书
结婚通知短信怎么写
2015/04/17 职场文书
2016幼儿园毕业感言
2015/12/08 职场文书
2016党员学习作风建设心得体会
2016/01/21 职场文书