Reputation: 23
Very new to Vue and js on that matter really, most likely I have missed a basic fundamental issue but I am trying to toggle the class of individually clicked images within my array without all of the images toggling class at the same time.
template :
<div class="collage-banner">
<img
v-for="image in images"
@click="imgSelected()"
:alt="image.alt"
class="collage"
:class="image.class"
:src="image.url"
:key="image"
/>
js :
export default {
data() {
return {
images: [
{ url: img1, class: "img-1", alt: "collage img" },
{ url: img2, class: "img-2", alt: "collage img" },
{ url: img3, class: "img-3", alt: "collage img" },
{ url: img4, class: "img-4", alt: "collage img" },
{ url: img5, class: "img-5", alt: "collage img" },
{ url: img6, class: "img-6", alt: "collage img" },
{ url: img7, class: "img-7", alt: "collage img" },
{ url: img8, class: "img-8", alt: "collage img" }
]
}
},
methods: {
imgSelected() {
if (this.images[0].url === img1) {
this.images[0].class = 'collage-click'
} else if (this.images[0].url === img2) {
this.images[0].class = 'img-1'
}
if (this.images[1].url === img2) {
this.images[1].class = 'collage-click'
} else if (this.images[1].url === img1) {
this.images[1].class = 'img-2'
}
}
}
}
Let me know if further info is needed, I more than likely have gone about this the entirely wrong way! Thanks in advance!
Upvotes: 2
Views: 544
Reputation: 4684
A better approach would be having a flag called clicked
in the images array and toggling class based on that Boolean.
data() {
return {
images: [
{ url: img1, class: "img-1", clicked: false, alt: "collage img" },
{ url: img2, class: "img-2",clicked: false, alt: "collage img" },
{ url: img3, class: "img-3",clicked: false, alt: "collage img" },
{ url: img4, class: "img-4", clicked: false, alt: "collage img" },
]
}
},
methods: {
imgSelected (index) { // add index param
// use index to get relevant image from array
this.images[index].clicked = !this.images[index].clicked;
}
}
and in template
<img
v-for="(image, index) in images" << updated
@click="imgSelected(index)" << updated
:alt="image.alt"
:class="['collage', {`${image.class}`: !image.clicked, 'collage-click': image.clicked}]"
:src="image.url"
:key="image"
/>
Note: if you want the collage
to always be applied then you can have it in the array.
If you don't want the collage class at all and jus wanna toggle between img1
and collage-click
, you could jus have an object like
:class="{`${image.class}`: !image.clicked, 'collage-click': image.clicked}"
Upvotes: 0
Reputation: 917
You can pass the image index into your imgSelected
method, and use this to update class for that image.
For example:
Template:
<img
v-for="(image, index) in images" << updated
@click="imgSelected(index)" << updated
:alt="image.alt"
class="collage"
:class="image.class"
:src="image.url"
:key="image"
/>
Script:
methods: {
imgSelected (index) { // add index param
// use index to get relevant image from array
this.images[index].class = 'collage-click'
}
}
If you want to remove class from selected images e.g. user clicks image 1, then image 2, you'd have to also loop through your images and reset the class before updating on latest clicked image.
E.g.
methods: {
imgSelected (index) {
// reset all image classes
for (const i in this.images) {
this.images[i].class = `img${i + 1}` // reset image class e.g. img2 (need to add 1 to index since it will start at 0)
}
// use index to get relevant image from array
this.images[index].class = 'collage-click'
}
}
Upvotes: 1