【问题标题】:how to destroy cropper.js properly so that next crop will get new image?如何正确销毁cropper.js,以便下一次裁剪获得新图像?
【发布时间】:2019-12-18 02:08:03
【问题描述】:

我有一个 vue 应用程序表单,该表单具有通过 ant-design-vue 上传的图像上传器。我将此图像上传器链接到一个新组件,该组件使用cropper.js在上传后处理要裁剪的图像。第一次作物一切都很好,工作完美。但是当用户第二次需要更换照片并再次裁剪时,裁剪区域上的图像仍然使用第一张图像。第三次上传将裁剪第二个区域,下一次将收到相同的影响。

这是我的代码结构:

<template>
  <div>
    <a-row :gutter="16">
      <img ref="image" :src="initialImage">
    </a-row><br />
    <a-row :gutter="16">
      <a-button type="primary" style="float: right;" @click="crop">Crop</a-button>
      <a-button style="float: right; margin-right: 5px;" @click="cancel">Cancel</a-button>
    </a-row>
  </div>
</template>

这是脚本和样式:

<script>
import Cropper from 'cropperjs';

export default {
  name: 'PostCropper',
  props: {
    uploadedImage: String,
  },
  data() {
    return {
      cropper: {},
      updatedImage: {},
      initialImage: this.uploadedImage,
    };
  },
  methods: {
    crop() {
      this.$emit('update-image', this.updatedImage);
    },
    cancel() {
      this.$emit('cancel-upload');
    },
    cropImage() {
      this.cropper = new Cropper(this.$refs.image, {
        autoCropArea: 1,
        cropBoxResizable: false,
        zoomOnTouch: true,
        zoomable: true,
        scalable: false,
        aspectRatio: 1,
        resizable: false,
        crop: () => {
          const canvas = this.cropper.getCroppedCanvas();
          this.updatedImage = canvas.toDataURL('image/png');
        },
      });
    },
  },
  watch: {
    uploadedImage() {
      this.cropper.destroy();
      this.initialImage = this.uploadedImage;
      this.cropImage();
    },
  },
  mounted() {
    this.cropImage();
  },
};
</script>

<style lang="scss">

.cropper-crop-box .cropper-view-box {
    border-radius:50%;
  }
</style>

问题出现在这里:

          this.cropper = new Cropper(this.$refs.image, {
            autoCropArea: 1,
            cropBoxResizable: false,
            zoomOnTouch: true,
            zoomable: true,
            scalable: false,
            aspectRatio: 1,
            resizable: false,
            crop: () => {
              const canvas = this.cropper.getCroppedCanvas();
              this.updatedImage = canvas.toDataURL('image/png');
            },
          });

我已经销毁 this.cropper 但仍然裁剪相同的图像。我试图通过 console.log 预览 this.cropper、this.image、this.initialImage、this.uploadedImage 的每个值,但它们都没有问题。它将在 this.uploadedImage 上携带新值,使用 vue watch 进行更改。我不知道为什么只有上面的这个函数仍然带有相同的图像。有什么方法可以初始化 this.cropper,或者可以克服我的问题,比如重新渲染这个子组件?

【问题讨论】:

  • 我已经克服了这个问题,但是用 v-if 破坏了子组件。是正确的还是有其他正确的方法?但效果很好

标签: javascript vue.js antd cropperjs cropper


【解决方案1】:

您可以通过给它们一个键并更新键来刷新 Vue 元素。 例如,您在哪里导入 PostCropper 组件:

<PostCropper v-bind:key="refreshValue" />

然后在父元素的 data 属性中分配一个名为refreshValue 的属性并给它一个类似 1 的值。然后当你需要刷新组件时,你只需更改该值。 这可能需要您从PostCropper 组件向父组件发出一个事件,然后递增refreshValue

【讨论】:

  • 所以,我需要看密钥而不是uploadImage?还是不用看钥匙?
  • 我以前读过这个。我可以理解父组件需要做什么。但是我们应该如何处理子组件呢? @贾斯汀·费克斯。因为我试过了,但什么也没发生
  • &lt;PostCropper v-bind:key="refreshCropper" :uploadedImage="uploadedImage" v-on:update-image="updateImage" v-on:cancel-upload="showCropper=false; refreshCropper += 1;" /&gt; 这是增量函数:` updateImage(updatedImage) { this.latestImage = updatedImage; this.refreshCropper += 1; this.showCropper = false; },`
【解决方案2】:

我有另一种方法可以销毁父组件中的子组件,而不是销毁变量。使用 v-if 方法销毁导入的组件,效果很好。

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2019-11-07
    • 2018-12-12
    • 2013-01-10
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多