#javascript #vue.js #cropperjs
#javascript #vue.js #cropperjs
Вопрос:
В моем приложении laravel-vue я создал компонент ImageCropper с помощью cropperjs. А затем в моем родительском компоненте 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, не смог настроить vuex в компоненте ImageCropper. Я мог бы получить доступ к store.js из главного компонента, но не из ImageComponent. Также не был уверен, что это правильный путь для достижения моей цели здесь.
Ответ №1:
Вы можете создать событие для отправки любых данных обратно в родительский компонент. Дополнительные сведения см. в разделе Пользовательские события.
В вашем случае вы можете сделать что-то вроде:
...
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 таким образом, но в основном вам это не нужно. Вы можете просто использовать компонент или динамический компонент. Подробнее о динамических и асинхронных компонентах.
Итак, вы можете сделать что-то вроде:
<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);
}
...
Комментарии:
1. Большое спасибо, приятель @ User 28. На самом деле это первый раз, когда я работаю с vuex и кратко работаю над этим в vue. Ваши советы очень помогли