elementui和vue-cropper实现裁剪并上传图片

预期效果:

裁剪时:

裁剪完:

实现方法: 

1、安装vue-cropper

npm install vue-cropper

2、写裁剪弹框组件

  放在/components/commons/imageCropper/index.vue文件里

这里默认的宽autoCropWidth、高autoCropHeight是400*400,如果想改变裁剪的尺寸,可以在父组件传参

<template>
  <div class="image-cropper-modal">
    <el-dialog
      :visible="visible"
      :append-to-body="true"
      :close-on-click-modal="false"
      title="裁剪图片"
      width="700px"
      class="image-cropper-dialog"
      @close="visible = false"
    >
      <vue-cropper
        ref="imageCropper"
        :img="url"
        :auto-crop-width="autoCropWidth"
        :auto-crop-height="autoCropHeight"
        :auto-crop="true"
        :fixed="false"
        :fixed-number="[1, 1]"
        :fixed-box="true"
        :output-size="1"
        output-type="png"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button class="common-btn cancel" @click="onCancel">取 消</el-button>
          <el-button class="common-btn confirm" type="primary" @click="onConfirm">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { VueCropper } from 'vue-cropper'

export default {
  name: 'ImageCropperModal',
  components: {
    VueCropper
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    url: {
      type: String,
      default: ''
    },
    autoCropWidth: {
      type: String,
      default: `${100 * 4}`
    },
    autoCropHeight: {
      type: String,
      default: `${100 * 4}`
    }
  },
  methods: {
    onCancel() {
      this.$emit('cancel')
    },
    onConfirm() {
      this.$refs.imageCropper.getCropBlob((blob) => {
        this.$emit('confirm', blob)
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.image-cropper-dialog {
  .vue-cropper {
    height: 500px;
  }
}
</style>

3、 使用组件

(1)html代码

<el-form
   ref="queryForm"
   class="formData"
   :label-suffix="labelSuffix"
   :label-width="labelWidth"
   :rules="rulesForm"
   :model="queryParams"
   style="min-width:900px"
 >
   <el-form-item label="营业执照上传" prop="companyImgUrl">
     <ImageCropperModal
       :visible="cropperVisible"
       :url="file"
       :auto-crop-width="autoCropWidth"
       :auto-crop-height="autoCropHeight"
       @cancel="cropperVisible = false"
       @confirm="onConfirm"
     />
     <el-upload
        v-model="queryParams.companyImgUrl"
        class="avatar-uploader"
        action
        :auto-upload="false"
        :show-file-list="false"
        :on-change="changeUpload"
     >
     <img v-if="queryParams.companyImgUrl" :src="queryParams.companyImgUrl" class="avatar">
     <i v-else class="el-icon-plus avatar-uploader-icon" />
     </el-upload>
   </el-form-item>
</el-form>

(2)js部分代码

import ImageCropperModal from '@/components/commons/imageCropper/index'

export default {
  // ...
  components: {
    ImageCropperModal
  },
  data(){
    return{
      // ...
      queryParams: {
        companyImgUrl: ''
      },
      autoCropWidth: '400', // 要裁剪的宽
      autoCropHeight: '400', // 要裁剪的高
      file: '',
      fileName: '', // 存放文件名
      cropperVisible: false // 控制弹窗打开关闭
    }
  },
  methods:{
    // 文件状态改变时
    changeUpload(file) {
      var img = file.name.substring(file.name.lastIndexOf('.') + 1)
      const suffix = img === 'jpg' || img === 'png' || img === 'jpeg'
      if (!suffix) {
        this.$message.error('只能上传图片!')
        return false
      }
      // URL.createObjectURL的参数只能是blob或者file类型
      // 第一种方法用FileReader,URL.createObjectURL接收blob类型
      const reader = new FileReader()
      reader.onload = () => {
        // 把Array Buffer转化为blob 如果是base64不需要
        this.file = typeof reader.result === 'object' ? window.URL.createObjectURL(new Blob([reader.result]))
          : reader.result
      }
      // 转化为base64
      this.cropperVisible = true
      reader.readAsArrayBuffer(file.raw)

      // 第二种方法,URL.createObjectURL接收file类型
      // this.$nextTick(() => {
      //   this.file = URL.createObjectURL(file.raw)
      //   this.cropperVisible = true
      // })

      this.fileName = file.name
    },
    // 点击剪裁弹框的确定按钮
    async onConfirm(blob) {
      // 这里的new FormData()指,以文件的方式传给后端(FormData的数据)
      const form = new FormData()
      // new File()的第一个参数是一个字符串数组,数组中的每一个元素对应着文件中一行的内容
      // 第二个参数就是文件名字符串
      // 第三个参数可以设定一些文件的属性,比如文件的MIME,最后更新时间等
      const file = new File([blob], this.fileName, { type: blob.type, lastModified: Date.now() })
      file.uid = Date.now()
      form.append('file', file)
      // 如果想在这里打印查看form的值,会发现它是空对象
      // 解决办法,需要用form.get('键')的方法获取值
      // console.log(form.get('file'))
      // 这里调用接口,获取后端返给的图片地址
      const { data } = await upload(form)
      this.queryParams.companyImgUrl = data
      this.cropperVisible = false
    },
  }
}

大功告成! 

属性:

具体可以参考官网:https://github.com/xyxiao001/vue-cropper

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值