无法在我的主要 vue 组件中使用 cropperjs 获得最终裁剪版本
Cannot get the final cropped version with cropperjs in my main vue component
在我的 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 store 传递数据,但由于我是使用 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>
在 reader 完成后,在 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);
}
...
在我的 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 store 传递数据,但由于我是使用 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>
在 reader 完成后,在 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);
}
...