无法在我的主要Vue组件中使用cropperjs获得最终的裁剪版本

问题描述

在laravel-vue应用程序中,我使用cropperjs创建了ImageCropper组件。然后在我的父vue组件中,我根据用户上传文件的更改事件来动态创建ImageCropper组件。我将图像url作为道具从主组件发送到子组件。 ImageCropper可以完美创建,并且裁剪机制也可以完美运行。唯一的问题是,我只能跟踪裁剪后的图像以及ImageCropper组件中的图像上的更改,而不能跟踪或更新主组件中的数据,因此我需要从该主组件中提交数据库中的数据。我的代码如下:

这是ImageCropper组件:

<template>
    <div class="card">
        <img ref="image" :src="imageSource" style="width: 100%;">
        <img ref="destinationImage" :src="destination" class="img-fluid">

    </div>
</template>
<script>
    import Cropper from 'cropperjs';
    export default {
        name: 'ImageCropper',props: {
            imageSource: String,},data() {
            return {
                cropper: {},destination: {},image: {},}
        },mounted() {
            this.image = this.$refs.image;

            this.cropper = new Cropper(this.image,{
                zoomable: false,scalable: false,aspectRatio: 16 / 9,viewmode: 1,background: false,crop: () => {
                    const canvas = this.cropper.getCroppedCanvas();
                    this.destination = canvas.toDataURL("image/png");

                },});

        },}

</script>

在此组件中,我可以通过“ this.destination”跟踪最终图像和更新。 这是我的主要组件:

<template>
    <div>
        <div>
            <input @change="changePhoto($event)" name="photo" type="file">
        </div>
        <div ref="imageCropperArea"></div>
    </div>
</template>
<script>
    import ImageCropper from './../../ImageCropper.vue';
    export default {
        name: "New",data() {
            return {
                temp_photo: '',final_photo: '',components: {
            ImageCropper
        },methods: {
            createImageCropping(event) {
                var ComponentClass = Vue.extend(ImageCropper)
                var instance = new ComponentClass({
                    propsData: {
                        imageSource: this.form.temp_photo
                    }
                })
                instance.$mount()
                this.$refs.imageCropperArea.appendChild(instance.$el)

            },changePhoto(event) {
                let file = event.target.files[0];


                let reader = new FileReader();
                reader.onload = event => {
                    this.form.temp_photo = event.target.result
                    this.createImageCropping(event)

                };
                reader.readAsDataURL(file);


            },}

    }

</script>

我需要做的就是随着裁剪的进行更新我的“ final_photo”变量。我一直在研究vuex,以便在更改时使用vue存储传递数据,但是由于我是使用vuex的新手,因此无法在ImageCropper组件中配置vuex。我可以从主组件访问store.js,但不能从ImageComponent访问。也不确定这是否是实现我的目标的正确途径。

解决方法

您可以发出事件以将任何数据发送回父组件。有关更多信息,请参见Custom Events

对于您而言,您可以执行以下操作:

...
  mounted () {
    ...
    this.cropper = new Cropper(this.image,{
      ...
      crop: () => {
        const canvas = this.cropper.getCroppedCanvas()
        this.$emit('crop',canvas.toDataURL('image/png'))
      }
    })
  }
...

...
  createImageCropping (event) {
    ...
    instance.$on('crop',dataUrl => {
      // now you can dispatch an action to update state of store
    })
    ...
  }
...

我不确定为什么要创建像这样的ImageCropper实例,但是大多数情况下您不需要这样做。您可以只使用组件或动态组件。进一步了解Dynamic & Async Components

因此您可以执行以下操作:

<template>
  <div>
    ...
    <image-cropper
      v-if='!!imageSource'
      :image-source="imageSource"
      @crop="dispatchSomeAction"/>
  </div>
</template>

在阅读器完成后,您可以使用changePhoto方法设置imageSource

...
  changePhoto (event) {
    const file = event.target.files[0]
    const reader = new FileReader()
    reader.onload = event => {
      this.imageSource = event.target.result
    }
    reader.readAsDataURL(file);
  }
...