记录vue+element+vue-cropper 图片上传裁剪功能

1、图片上传功能
<template>
<el-upload
   drag
   ref="upload"
   :data="uploadData"
   :http-request="uploadFile"
   :auto-upload="false"
   :on-remove="handleRemove"
   :on-change="addFileChange"
   :limit="1"
   action
   :show-file-list="false"
  ></el-upload>
</template>

element upload图片上传功能,首先上传图片,拿到file文件

async addFileChange(file, fileList) {
    //上传,拿到file文件
      this.files = file.raw;
      this.$nextTick(() => {
        this.optionImg = URL.createObjectURL(file.raw);
        this.fileinfo = file.raw;
        this.dialogCropperVisible = true;
      });
},
uploadFile(param) {
      console.log(param);
      this.fileData.append("file", param.file);
    },

handleRemove(file, fileList) {
      if (file && file.status === "success") {
        //移除方法  element的upload组件在before-upload之后return false之后自动触发了before-remove以及后面on-remove方法
        this.fileList = fileList;
      }
    },
2、剪切功能
第一步:安装 vue-cropper
npm install vue-cropper --save-dev
第二步:在main.js中引入或者在组件的script里面引入vue-cropper
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
或者组件使用
components: { VueCropper },

新建cropper.vue组件

<template>
  <el-dialog title="图片剪裁" :visible="true" append-to-body>
    <div class="cropper-content">
      <div class="cropper" style="text-align: center">
        <vueCropper
          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"
          :fixedBox="option.fixedBox"
          :fixedNumber="option.fixedNumber"
        ></vueCropper>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="cancel">取 消</el-button>
      <el-button type="primary" @click="finish" :loading="loading"
        >确认</el-button
      >
    </div>
  </el-dialog>
</template>

<script>
import { VueCropper } from "vue-cropper";
import { projectList } from "@/api/contribute/contributeMana.js"; //api接口

export default {
  components: { VueCropper },
  name: "Cropper",
  props:{
      fileinfo:{
          type:File,
      },
      optionImg:{
          type:String,
          default:""
      }
  },
  data() {
    return {
      loading: false,
    //   fileinfo: {},
      formImage: "",
      pageMethods: projectList,
      form:{
          backgroundImage:"",
      },
      // 裁剪组件的基础配置option
      option: {
        img: this.optionImg, // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputSize: 1, // 裁剪生成图片的质量
        outputType: "jpeg", // 裁剪生成图片的格式
        canScale: true, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 780, // 默认生成截图框宽度
        autoCropHeight: 500, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [16, 10], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: false, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        canMove: true,
      },
    };
  },
  mounted(){
      console.log(this.fileinfo)
  },
  methods: {
    cancel() {
      this.$emit("formClose", false);
    },
    //将base64转换为blob
    dataURLtoBlob(dataurl) {
      var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    //将blob转换为file
    blobToFile(theBlob, fileName = "111") {
      theBlob.lastModifiedDate = new Date();
      theBlob.name = fileName;
      return theBlob;
    },
    async finish() {
        console.log(this.fileinfo)
      //   this.loading = false;
      this.$refs.cropper.getCropData((data) => {
        let fileName = "bc" + this.fileinfo.uid + ".jpg";
        this.formImage = data;
        var blob = this.dataURLtoBlob(this.formImage);
        var file = this.blobToFile(blob, fileName);
        let formData = new FormData();
        formData.append("file", file);
        formData.append("fileName", fileName);
        formData.append("accessToken", "hggydg728778");
        // 文件对象
        this.pageMethods.uploadApi.baseMethod(formData).then((data) => {
          if (data) {
            //filePre 域名  fileUrl 路径
            this.editoImg = true
            this.formImage = `${data.filePre}${data.fileUrl}`;
            this.form.backgroundImage = data.fileUrl;
            this.$emit("formSubmit",this.formImage,this.form.backgroundImage,this.editoImg)
          }
        });
      });
    },
  },
};
</script>

<style scoped lang='scss'>
.cropper-content {
  width: 500px;
  height: 500px;
  background: pink;
}

.cropper {
  width: 500px;
  height: 500px;
  background: yellow;
}
</style>

在上传图片组件引入cropper组件

import  Cropper from './cropper.vue'
components: { Cropper },
<template>
  <transition name="fade">
      <Cropper
      :optionImg='option.img'
        :fileinfo="fileinfo"
        v-if="dialogCropperVisible"
        @formSubmit='cropperSubmit'
        @formClose="cropperClose"
      />
  </transition>
</template>
methods:{
 //裁剪确定按钮
    cropperSubmit(preImg,urlPre,isEdito){
      // preImg 完整路径  urlPre 不包含域名
      this.formImage = preImg
      this.form.backgroundImage = urlPre
      this.editoImg = isEdito
      this.dialogCropperVisible = false;
    },
    //裁剪取消
    cropperClose(){
      this.dialogCropperVisible = false;
    },
    beforeAvatarUpload(file) {
      file.url = URL.createObjectURL(file);
      this.fileList.push(file);
      return false;
    },
}
 
 
 
posted @ 2022-06-08 14:03  〆浮生如梦〆  阅读(741)  评论(0)    收藏  举报