vue cropperjs图片裁剪组件(精简版)

341 阅读1分钟

调用

    <template>
        <div>
            ...
            <!-- 图片裁剪 -->
            <ImpCropper
              ref="imgcropper"
              @cancel="cropperCancel"
              @finish="cropperFinish"
            ></ImpCropper>
            ...
        </div>
    </template>
    <script>
        import ImpCropper from "@/components/images/cropper/index.vue";
        
        export default {
            components: { ImpCropper },
            methods:{
                // 通过上传组件获取到选取的文件后 调起图片裁剪组件
                fn(file){
                    // 传入文件
                    this.$refs.imgcropper.init(file.file);
                },
                // 取消裁剪
                cropperCancel(){
                
                },
                // 裁剪完成
                cropperFinish(file) {
                   // 裁剪后的文件
                  console.log(file)
                },
            }
        }
    </script>

组件

<template>
  <div>
    <!--弹出框-->
    <el-dialog
      @opened="onDialogOpened"
      @closed="onDialogClosed"
      :append-to-body="true"
      :close-on-click-modal="false"
      title="修改头像"
      :visible.sync="imgCropperShow"
    >
      <div class="preview-image-wrap">
        <img
          ref="preview-image"
          class="preview-image"
          :src="previewImage"
          alt=""
        />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="onDialogClosed">取 消</el-button>
        <el-button
          type="primary"
          @click="onUpdatePhoto"
          :loading="updatePhotoLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>
<script>
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
export default {
  data() {
    return {
      imgCropperShow: false,
      updatePhotoLoading: false,
      previewImage: "",
      cropper: null,
    };
  },
  methods: {
    // 启动  可直接传入文件
    init(file) {
      this.imgCropperShow = true;
      // 将图片文件转化并展示
      this.previewImage = window.URL.createObjectURL(file);
    },
    // 对话框完全打开后
    onDialogOpened() {
      // 图片裁切器必须基于image初始化
      // 注意:image必须是可见状态才能正常进行初始化
      // 获取图片DOM节点
      const image = this.$refs["preview-image"];
      // 初始化裁切器
      if (this.cropper) {
        this.cropper.replace(this.previewImage);
      }
      const cropper = new Cropper(image, {
        aspectRatio: 1 / 1,
        viewMode: 1,
        dragMode: "none",
        background: true,
        cropBoxResizable: false,
      });
      this.cropper = cropper;
    },
    // 对话框完全关闭后
    onDialogClosed() {
      // 销毁裁切器
      this.cropper.destroy();
      this.cropper = null;
      this.$emit("cancel");
      // 关闭对话框
      this.imgCropperShow = false;
    },
    onUpdatePhoto() {
      // 让确定按钮开始显示loading
      this.updatePhotoLoading = true;
      // 获取裁切的图片对象
      this.cropper.getCroppedCanvas().toBlob((blob) => {
        let type = "text/plain";
        let file = new File([blob], "headimg.png", {
          type,
          lastModified: new Date().getTime(),
        });
        // 裁剪完成 将文件通过自定义事件传出
        this.$emit("finish", { file });
        // 关闭对话框
        this.imgCropperShow = false;

        // 关闭确定按钮的loading
        this.updatePhotoLoading = false;
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.preview-image-wrap {
  .preview-image {
    display: block;
    max-width: 100%;
    height: 200px;
  }
}
</style>