您的位置:首页 > 编程学习 > > 正文

vue图片怎么上传服务器(vue-cropper组件实现图片切割上传)

更多 时间:2022-01-22 01:04:19 类别:编程学习 浏览量:2125

vue图片怎么上传服务器

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

本文实例为大家分享了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)"
        >
        <li style="margin-left:20px;">
          <li class="show-preview" :style="{'overflow': 'hidden', 'margin': '5px'}">
            <li :style="previews.li" class="preview" style="width: 40px;height: 40px;">
              <img :src="previews.url" :style="previews.img">
            </li>
          </li>
        </li>
        <li 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>
        </li>
        <li 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>
        </li>
      </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("上传图片失败");
      }
     }
    
  • 结束

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

    您可能感兴趣