Modifying attributes for individual components in Vue.js classes

Recently, I integrated a reusable component called "LightBox" into my website, which displays images in higher resolution. The LightBox functionality is linked to each element having a thumbnail. However, I encountered an issue. There are multiple elements where I need to modify the properties of the class "thumbnail", but I am unsure how to achieve this. I attempted using v-bind, but unfortunately, it didn't yield the desired outcome.

Below is a snippet of my code:

<template>
    <div>
        <a href="" @click.prevent="show">
            <img class="thumbnail" :src="images[thumbnailIndex]" loading="lazy">
        </a>
        <div class="lightbox" v-if="visible" @click="hide">
            <div class="flex">
                <div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
                    <svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
                        viewBox="0 0 537.66 537.66" xml:space="preserve"  stroke="#ffff">

                        [...] (SVG path continuation)

                        </svg>
                 
                </div>
                <div class="lightbox-image" @click.stop="">
                    <img :src="images[index]" loading="lazy">
                </div>
                <div class="cursor right" @click.stop="next" :class="{ 'invisible': !hasNext() }">
                    <svg class="size" fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
                        viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">

                        [...] (SVG path continuation)

                    </svg>
                </div>


            </div>


        </div>
    </div>


</template>
<script>
export default {
    props: {
        thumbnailIndex: {
            type: Array,
            required: true,
        },
        images: {
            type: Array,
            default: () => [],
        },

    },
    data() {
        return {
            visible: false,
            index: 1,
        };
    },
    methods: {
        Index(){
            let thumbnailIndex = images.findIndex(element => element === thumbnail);
        },
        show() {
            this.visible = true;
            this.index=this.thumbnailIndex
           
        },
        hide() {
            this.visible = false;
            this.index = 0;
        },
        hasNext() {
            return this.index + 1 < this.images.length;
        },
        hasPrev() {
            return this.index - 1 >= 0
        },
        prev() {
            if (this.hasPrev()) {
                this.index -= 1;
            }
        },
        next() {
            if (this.hasNext()) {
                this.index += 1
            }
        }
    }
}

</script>
<style>
.thumbnail {
    width: 29vh;
}
.lightbox {
    position: fixed;
    z-index: 500;
    display: flex;
    justify-content: center;
    align-content: center;
    background: rgba(0, 0, 0, 0.8);
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
}
.lightbox-image img {
    width: auto;
    height: auto;
    max-width:50%;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.cursor {
    cursor: pointer;
    display: block;
    position: absolute;
    z-index: 1000;
    top: 50%;
    visibility: visible;
}
.cursor.right {
    right: 10%;
}
.cursor.left {
    left: 10%;
}
.invisible {
    visibility: hidden;
}
@media screen and (max-width: 1024px) {
    .thumbnail{
        width: 100%;
    }
    .lightbox-image img{
        max-width: 80%;
        max-height: 80%;;
    }
    .cursor{
        top: 70%;
    }
}
</style>

This is an example of how I attempted to modify classes for individual thumbnails:

<LightBox :thumbnail-index="0" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="1" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="2" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="3" :images="images" :style="{width: "25vh"}"></LightBox>

Answer №1

If I got your point correctly, please review the code snippet below: (include necessary styles and bind it)

const app = Vue.createApp({
    data() {
      return {
        images: ['https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502', 'https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502'],
      };
    },
  });
  app.component("lightBox", {
    template: `
    <div>
      <a href="" @click.prevent="show">
        <img :style="styles" :src="images[thumbnailIndex]" loading="lazy">
      </a>
      <div class="lightbox" v-if="visible" @click="hide">
        <div class="flex">
          <div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
            <svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 537.66 537.66" xml:space="preserve"  stroke="#ffff">
              <g id="SVGRepo_bgCarrier" stroke-width="0" />
              <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
              <g id="SVGRepo_iconCarrier">
                <g>
                  <g>
                    <path d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
                  </g>
                </g>
              </g>
            </svg>
          </div>
          <div class="lightbox-image" @click.stop="">
...
.lightbox {
    position: fixed;
    z-index: 500;
    display: flex;
    justify-content: center;
    align-content: center;
    background: rgba(0, 0, 0, 0.8);
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;

}
.lightbox-image img {
    width: auto;
    height: auto;
    max-width:50%;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.cursor {
    cursor: pointer;
    display: block;
    position: absolute;
    z-index: 1000;
    top: 50%;
    visibility: visible;
}
...
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo" style="display: flex; flex-wrap: wrap">
    <light-box :thumbnail-index="0" :images="images" :styles="{width: '25vh'}"></light-box>
    <light-box :thumbnail-index="1" :images="images" :styles="{width: '30vh'}"></light-box>
    <light-box :thumbnail-index="2" :images="images" :styles="{width: '45vh'}"></light-box>
    <light-box :thumbnail-index="3" :images="images" :styles="{width: '25vh'}"></light-box>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing Pinia setup stores with custom getters, setters, and actions for improved reusability

If we think about a Pinia setup store that has a basic set of state, getters, and actions in place: export const useBaseStore = defineStore('base-store', () => { const name = ref<string>(''); const age = ref<number>(1 ...

Explore Youtube to find the most popular video IDs

Is it possible for me to use a string to search YouTube and retrieve the id for the top video in the search results? I want to be able to play that video directly on my website. All I have is the URL for the search: youtube_url/results?search_query=thevid ...

What could be causing my form not to Submit when attempting submission without utilizing the submit button?

Here is the code for my validation: $(function () { function validateForm() { // Code to validate form inputs } $('#myform').submit(validateForm); }); After this, I want to submit the form when a certain action occurs: < ...

Retrieving JSON data from a PHP file through a standalone JavaScript script

I am in need of creating a JavaScript file that will assign values to two variables within a PHP file. The PHP file should then construct a JSON structure and display some data. My goal is to have a form written in JavaScript with two input fields that wi ...

What is the best way to center a div vertically within a bootstrap 5 carousel across all screen sizes?

Looking to center the text div within a Bootstrap 5 carousel both vertically on large screens and small (mobile) screens. To view the site, visit... Below is the HTML for the div. The targeted div has the CSS class #hero .carousel-container { display ...

How can I define margins for a specific div in print media using CSS?

Hello everyone, I'm currently experiencing an issue with my print media CSS. On the HTML page, there are two main divs - one for the body and one for the footer. <div class="main-template-body" id="main-template-body"> //content </div> ...

The custom server was functioning properly, but as soon as I altered the file directory, an error occurred on Next.js

After creating "create-next-app," I successfully set up the folder structure as follows: +client2 --.next --node_modules --public --... --server.js However, when I move my "server.js" file to a different location: +client2 --.next --no ...

Show a div pulsating while simultaneously animating another div

After coming across this query on Stack Overflow about adding a class without jQuery if hovering over another class I encountered an issue with a div element that displays upon hovering over a span, which was functioning correctly. However, I also have a ...

Tips for preventing the use of nested functions while working with AJAX?

Consecutively making asynchronous calls can be messy. Is there a cleaner alternative? The issue with the current approach is its lack of clarity: ajaxOne(function() { // do something ajaxTwo(function() { // do something ajaxThree() }); }); ...

javascript path as the first argument and callback as the last argument

Currently, I am in the process of creating a wrapper function for expressjs's app.get method. In these methods such as get, you can provide the path, some options, and then the callback. However, it is possible to omit the options and still have it w ...

Add the text received from the Ajax request to an array specifically designed for AmCharts

Hello, I'm new to JavaScript and seeking assistance. My goal is to create a chart with real-time data from my MCU, but I'm unsure about pushing a string into an array. Currently, the Array (chart.dataProvider) in this code remains undefined. var ...

Avoiding text from overflowing a DIV when the parent DIV's width is specified as a percentage

After extensively searching through over 20 similar posts, I have not been able to find a solution that works for my specific issue. The layout of some content I'm working with resembles the example provided here: Check out the Fiddle Example In th ...

Harnessing the power of flexbox for data visualization

Trying to use flexbox to display data from a dataset in my code. Here is the code snippet: <div ng-app="myapp" ng-controller="FirstCtrl"> <div ng-repeat="name in names" class="graph-wrapper"> <div class="aside-1 content"> ...

Ways to retrieve parameters in getStaticPaths function?

I'm currently working on a Next.js app with Contentful as the CMS. The file structure relevant to my question is: pages -[category] -[slug].js My goal is to access the category value when a user visits category/slug. Currently, I have the category ...

Error message: "The use of Vue 3 refs in the render function is

I am facing an issue with my Vue component wherein the root element is set as ref="divRef". Strangely, when I try to access divRef.value inside the onMounted function, it returns undefined. Any assistance on this matter would be greatly appreci ...

Ways to avoid automatic error correction when running npm lint?

Utilizing the Vue CLI, I developed a Vue3 app with a Prettier/Eslint configuration. Upon making changes to the main.ts file as shown below: import { createApp } from "vue"; import App from "./App.vue"; import router from "./router& ...

Ways to resolve the error message "TypeError: 'setOption' is not a function on type 'MutableRefObject' in React"

CODE export default function EChart({ option, config, resize }) { let chart = useRef(null) let [chartEl, setChartEl] = useState(chart) useEffect(() => { if (resize) { chartEl.resize() } if (!chartEl.cu ...

A guide to building a dynamic form slider that showcases variable output fields with Javascript

I'm interested in creating a Slider Form that shows different output fields when sliding, using Javascript. Something like this: https://i.sstatic.net/3Isl4.png Could anyone provide suggestions on how to achieve this or share any links related to so ...

Attempting to get a webGL game downloaded from Unity to automatically enter fullscreen mode

Can someone help me with my Unity webGL game issue? I downloaded it from the internet, but I'm not sure what version of Unity was used to create it. When the game starts playing, it displays in a small canvas along with other elements like the Unity ...

Tips for creating a dashed border line that animates in a clockwise direction when hovering

I currently have a dashed border around my div element: .dash_border{ border: dashed; stroke: 2px; margin:20px; } My goal is to make the dashed lines move clockwise when my pointer hovers over the div element and stop moving ...