Answer the question
In order to leave comments, you need to log in
How to create a set of blocks for loading images on vue?
It is necessary to create fields for loading images with preview loading on vuejs. Earlier in this project, a component was created for loading one image and without the function of removing this image from the field. Now it has become necessary to create a set of blocks appearing one after another when loading an image into the previous block. And additionally, deleting the image if it was uploaded is not what you need. The entire source code is presented below, shortened, leaving only the necessary. I tried to implement it myself but ran into problems.
1) if the variable in which the images will be stored is an array, then when deleting the elements are shifted and a jamb occurs with the display of new ones
2) the jamb is also observed periodically with the removal of the block
Those. now everything works in the direction of loading images, but there is no
fiddle to demonstrate the work in the opposite direction
Code for clarity and suddenly if the fidl is lost
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<set-imgs
:name="'instagram-gig-'"
:images="images"
:max-amount="3"
:count-per-row="3"/>
</div>
Vue.component('input-img', {
template: `
<div class="card-input-img" :style="{'padding-top': height}">
<i
class="card-input-img__icon material-icons card-input-img__size_sm"
:class="{'card-input-img__icon_remove': (hasRemove && img.src)}"
v-text="(hasRemove && img.src) ? 'x' : '+'"
@click="removeImg"/>
<img
v-if="img.src || background" :src="img.src || background"
class="card-input-img__image card-input-img__image_size_cover">
<input
type="file"
:name="name"
accept="image/*"
@change="fileChangeHandler">
</div>`,
props: {
name: {
type: String,
required: true
},
height: {
type: String,
default: '100%'
},
img: {
type: Object,
default: null
},
background: {
type: String
},
hasRemove: {
type: Boolean,
default: true
}
},
data() {
return {
newImg: {
file: null,
src: null
},
firstUpload: true,
}
},
created() {
this.newImg = this.img
},
methods: {
fileChangeHandler(e) {
this.newImg.file = e.target.files[0];
if( this.newImg.file ) {
let reader = new FileReader();
reader.onloadend = () => {
const image = new Image();
image.onload = () => {
this.newImg.src = image.src;
this.$emit('update:img', this.newImg);
if(this.firstUpload) {
this.$emit('first-uploaded', this.newImg);
this.firstUpload = false;
}
}
image.src = reader.result;
}
reader.readAsDataURL(this.newImg.file);
}
},
removeImg() {
document.querySelector(`[type="file"][name="${this.name}"]`).value = null;
this.$emit('remove');
this.newImg = {
file: null,
src: null
};
this.firstUpload = true;
}
}
});
Vue.component('set-imgs', {
template: `
<div class="grid grid_col_3 grid_gap_s">
<input-img
v-for="(image, i) in images"
:key="i"
:name="name + i"
:background="image.src"
:img.sync="image"
@update:img="image = $event"
@first-uploaded="addFieldNextImage"
@remove="removeElem(i)" />
</div>`,
props: {
name: {
type: String,
required: true
},
img: Object,
maxAmount: {
type: Number,
default: 3,
},
countPerRow: {
type: Number,
default: 3,
},
images: {
type: Array,
default: () => [{file: null, src: null}]
}
},
methods: {
addFieldNextImage() {
if(this.images.length < this.maxAmount) {
this.images.push({ file: null, src: null });
}
},
removeElem(i) {
this.images.splice(i, 1);
},
}
});
new Vue({
el: '#app',
data() {
return {
images: [{file: null, src: null}],
}
},
});
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question