Home > Software design >  Vue.js switch between pictures upon clicking on an image
Vue.js switch between pictures upon clicking on an image

Time:09-03

Hello I am relatively new to Vue and I need some help with some logic to implement.

I have a json file containing information regarding polaroids I took (id, name, image name, etc.), see a snippet below:

[
{
    "id": "PRD1",
    "image": "polaroid_1.jpeg",
    "name": "Natale - 2020",
    "description": "blah blah blah"
},

{
    "id": "PRD2",
    "image": "polaroid_2.jpeg",
    "name": "A love that never was - 2021",
    "description": "Before the first ever heartbreak of my life (the worst so far)."
},
...    
]

The way the images are rendered are using a v-for within a component I created. Below is the full HTML code:

<template>
<div >
    <div  v-for="polaroid in polaroids" :key="polaroid">
        <img  :src="getImgUrl(polaroid.image)"/>
        <div > 
            <div >
                {{ polaroid.name }}
            </div>
            <div >
                {{ polaroid.description }}
            </div>
        </div>
    </div>
</div>

These images are correctly rendered one by one in a grid within my Vue app. What I am struggling to understand, is how to implement the logic that upon clicking on one of the images, or multiple ones, these individual clicked images are substituted by another image (one representing the back of them saved in the assets folder under polaroid_0.jpeg), and display the polaroid.name and polaroid.description belonging to those specifically clicked images.

Does any one have any ideas?

CodePudding user response:

If I understand right, I think you just want to use a v-if and v-else to display either the current image or the "back" image using a boolean property you'll need to add to each polaroid object. A click event listener can handle changing the boolean back and forth. The information-wrapper's display can be tied to the same boolean if you only want it displayed when the back image is shown.

<template>
<div >
    <div  v-for="polaroid in polaroids" :key="polaroid">
        <img v-if="polaroid.show" @click="polaroid.show = false"  :src="getImgUrl(polaroid.image)"/>
        <img v-else @click="polaroid.show = true"  :src="getImgUrl('polaroid_0.jpeg')"/>
        <div v-if="!polaroid.show" > 
            <div >
                {{ polaroid.name }}
            </div>
            <div >
                {{ polaroid.description }}
            </div>
        </div>
    </div>
</div>

new boolean added to each polaroid object:

{
    "id": "PRD1",
    "image": "polaroid_1.jpeg",
    "name": "Natale - 2020",
    "description": "blah blah blah",
    "show": true
}

CodePudding user response:

There a multiple ways of doing what you desire, I would suggest

  1. Track if an image is clicked or not (for example by Adding a boolean field to each of your polaroids and whenever you click an image, you toggle that field)

  2. Your :src should be dynamic, this could either be done in the getImgUrl() or by having another field for the image to display when selected

For example, polaroids become :

[
{
    "id": "PRD1",
    "image": "polaroid_1.jpeg",
    "name": "Natale - 2020",
    "description": "blah blah blah",
    "show" : false,
    "clickedImage" : "polaroid_1.jpeg"
},

{
    "id": "PRD2",
    "image": "polaroid_2.jpeg",
    "name": "A love that never was - 2021",
    "description": "Before the first ever heartbreak of my life (the worst so far).",
    "show" : false,
    "clickedImage" : "polaroid_1.jpeg"
},
...    
]

Your template may become :

<template>
<div >
    <div  v-for="polaroid in polaroids" :key="polaroid" @click="toggleImg(polaroid.id)">
        <img  :src="getImgUrl(polaroid)"/>
        <div > 
            <div >
                {{ polaroid.name }}
            </div>
            <div >
                {{ polaroid.description }}
            </div>
        </div>
    </div>
</div>

and in your code,

function getImgUrl(polaroid) {
  cont img = polaroid.show ? polaroid.clickedImg : polaroid.img;
  // Your current code
} 

These are just examples, but the general approach is my first two points

  • Related