What steps can be taken to make the carousel inconsistent when relying on the assigned id in props?

I recently developed a slider with slots, but encountered an issue. The code for this component revolves around the use of IDs for each slide as prop, making it unnecessarily complex. I am convinced that there is a more straightforward way to achieve the same functionality.

<template>
    <div class="slider">
        
        <slot class="image"></slot>
        <div class="arrow left" @click="prev"
        :class="{ 'invisible': !hasPrev() }">
        <svg width="80px" height="80px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M13.9783 5.31877L10.7683 8.52877L8.79828 10.4888C7.96828 11.3188 7.96828 12.6688 8.79828 13.4988L13.9783 18.6788C14.6583 19.3588 15.8183 18.8688 15.8183 17.9188V12.3088V6.07877C15.8183 5.11877 14.6583 4.63877 13.9783 5.31877Z" fill="#292D32"></path> </g></svg></div>
         <div class="arrow right" @click="next"
         :class="{ 'invisible': !hasNext() }"><svg width="80px" height="80px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M13.9783 5.31877L10.7683 8.52877L8.79828 10.4888C7.96828 11.3188 7.96828 12.6688 8.79828 13.4988L13.9783 18.6788C14.6583 19.3588 15.8183 18.8688 15.8183 17.9188V12.3088V6.07877C15.8183 5.11877 14.6583 4.63877 13.9783 5.31877Z" fill="#292D32"></path> </g></svg></div>
    </div>

</template>
<script>
import { ref } from "vue";
import { provide } from "vue";
export default {
  setup(props, { slots }) {
    const carouselIds = ref(slots.default().map((slide) => slide.props.id));
    const selectedId = ref(carouselIds.value[0]);
    provide("selectedId", selectedId);

    return {
        carouselIds,
        selectedId,
    };
  },
  data(){
    return{
        id:1
    }
  },
  methods:{
    hasNext() {
            return this.id  < this.carouselIds.length;
        },
        hasPrev() {
            return this.id - 1 >=  1
        },
        prev() {
            if (this.hasPrev()) {
                this.selectedId = this.id-=1
            }
        },
        next() {
            if (this.hasNext()) {
                this.selectedId = this.id+=1;
            }
        }
  },

};

</script>
<style scoped>
.invisible {
    visibility: hidden;
}
.slider{
    position: relative;

}
.arrow{
    cursor: pointer;
    display: block;
    position: absolute;
    top: 50%;
  transform: translateY(-50%);
}


.arrow.right{
    right: 0;
}
.arrow.left{
    left: 0;
}
</style>

This Carousel component hosts individual slides within its structure. It creates an array of IDs extracted from props defined in each slide component, allowing for navigation between slides based on their assigned IDs using "next" and "prev" buttons.

<template>
    <div class="slide" v-show="id == selectedId">

        <slot/>
    </div>
    
</template>
<script>
import { inject } from 'vue';
export default{
    props:['id'],
    setup(){
        const selectedId=inject('selectedId')

        return{
            selectedId,
        }
    },
    
  <Carousel>
            <Slide id="1">
<img src="https://www.freecodecamp.org/news/content/images/size/w2000/2022/08/Vue-Blog-Cover-2.png">
            </Slide>
            <Slide id="2">
<img src="https://community-cdn-digitalocean-com.global.ssl.fastly.net/snN3rbgKF7McfuiQAKcoLWMn'">
            </Slide >
        </Carousel>

I am exploring ways to automatically assign indices to elements in my array and create a new array based on these indices, eliminating the need for explicit IDs. This approach would simplify the process of navigating between slides without manually assigning IDs.

View my code in SFC playground

Answer №1

If you would like the Carousel to be in charge of displaying or hiding sliders based on the selectedId, you can utilize a render function to dynamically apply a css class to display each slider :

import { h } from 'vue'

export default {
  props: {
    selectedId: {
      type: Number,
      required: true
    }
  },
  render() {
    const slides = this.$slots.default()[0].children
    const renderedSlides = []
    
    slides.forEach((slide, index) => {
      renderedSlides.push(h('div', { class: this.selectedId === index ? '' : 'hidden'}, slide))
    })
    
    return renderedSlides
  }
}

I have adjusted your SFC playground as needed.

You could also opt to load slides into the dom only when the user is navigating, creating a form of "lazy loading" behavior :

  render() {
    const slide = this.$slots.default()[0].children[this.selectedId]
    
    return h('div', slide)
  }

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

Start flicker issue in Vue 3 transition

I have created a carousel of divs that slide in and out of view on the screen. However, I am facing an issue where during the start of each transition, when a new div is rendered (i.e., the value of carousel_2 changes), it appears without the transition-en ...

Utilizing React with Material UI, implement a Select component while disabling the scroll lock and ensuring the menu is positioned relative to

import React from "react"; import "./styles.css"; import Input from "@material-ui/core/Input"; import MenuItem from "@material-ui/core/MenuItem"; import FormControl from "@material-ui/core/FormControl"; import Select from "@material-ui/core/Select"; cons ...

The state value in React useContext remains unchanged when navigating between pages

Currently, I am delving into the useContext hook and experimenting with a shopping cart exercise in Next.js with app router. This exercise involves managing the cart's value globally. However, I encountered an issue when trying to pass the updated ca ...

Send a vanilla JavaScript ajaxForm submission by completing the form

I am currently in the process of integrating JavaScript from an iOS application into a web application. I have control over the code for both apps. My objective is to develop a JavaScript function that can receive input from a barcode scanner, populate a w ...

Tips for avoiding infinite re-render loop when updating state in React/Next.js

I currently have a unique Next.js application that showcases randomly selected YouTube videos. The state within the app is structured as follows (managed by Redux): const state = { entities: { videos: { 'vidId1': { ...

undefined reference to $

I'm currently working on a JavaScript project that involves using key events to display alphabets on the screen. However, I've encountered an error and need some assistance. <!DOCTYPE html> <html lang="en"> <head> <met ...

Experiencing difficulties with updating populated inputs that are connected to fetched data as they are not reflecting changes when modified

I am currently facing challenges with handling text fields in my web application. I need to retrieve data from the database, populate it in the appropriate fields, allow users to edit the information, and save any changes made. However, I have encountered ...

A dynamic JavaScript object that functions similarly to a multidimensional associative array in PHP

How can you efficiently update or add properties to an object in JavaScript? Unlike PHP's associative array, achieving this dynamically in JavaScript can be a bit tricky. For example: $test = []; foreach ($data as $key => $value) { ... $te ...

Challenges Encountered When Inputting Year in ReactJS Date Picker Component

I've encountered a problem with a date input component in my ReactJS project and need some assistance with resolving two issues: Problem 1: Year Input Length The first issue is that the year input field allows six digits, but I want to restrict it to ...

Mapping through multiple items in a loop using Javascript

Typescript also functions Consider an array structured like this const elementList = ['one', 'two', 'three', 'four', 'five'] Now, suppose I want to generate components that appear as follows <div&g ...

"Have you ever wondered how the router object in express.js is seamlessly integrated with app.use(), considering that it only accepts

I am curious about the process of how the router object in express.js is passed to app.use(), which typically only accepts callbacks. Since router is an object of express, I am trying to understand why app.use() does not throw an error even though it req ...

What is the best way to obtain the id of a selected row using JavaScript?

I'm attempting to utilize the JavaScript function below to extract a specific cell value from a jqgrid upon clicking. Within the following function, #datagrid refers to the table where the jqgrid is located. $("#datagrid").click(function ...

Retrieving JSON data from a form in a Node.js application

Situation : Here is the HTML code I am working with <form action="http://example.com/nodejs/endpoint" method="post" enctype="multipart/form-data"> <label> Select JSON file <input type="file" name="json"> ...

Setting up the karma ng-html2js preprocessor to locate my templates within a specific folder

Currently, I am facing an issue where I need to set the templateUrl: "partials/my-directive.html" However, I find that I have to use templateUrl: "app/partials/my-directive.html for it to be loaded by Karma. This is how my folder structure looks like (fo ...

Error encountered during the execution of the store method in Ajax CRUD operation

Greetings, I'm encountering an error in my AJAX code every time I try to execute the store function https://i.sstatic.net/SW86I.jpg Below is my controller: public function store_batch(Request $request) { $rules = array( 'batch_name& ...

Switch the dropdown menu to a button if it consists of only one option

I have been using a database within the Moodle Learning Management System that generates a bootstrap table. Here is an example of what it looks like: The last row in the table contains a dropdown menu. When viewing your own entry, you have the options to ...

Refreshing the Span Element using Ajax and php

Hello there, Stack Overflow community! I have a basic PHP script (countsomething.php) that retrieves a number and displays it using echo. How can I use AJAX to automatically update a simple span element on my HTML page? I've attempted to trigger th ...

Leaflet issue: ReferenceError - The variable L has not been defined

After saving the code for the first time, the map appeared perfectly on the screen. However, this was a one-time occurrence. I am puzzled by the current situation. The code seems flawless, but I am struggling to decipher the error messages in the console. ...

What is the most effective method to verify the visibility of an element hidden by v-show when using testing-library in Vue?

When working with Vue and the testing-library, checking for the presence of an element in the DOM is straightforward. For instance, if the v-if condition for the element is set to false: element = screen.queryByTestId("my-element") expect(element).toBeNul ...

Click on each item within the v-for loop to gather relevant information, and subsequently iterate through the collected data

Within a v-for loop, I have implemented a button that, when clicked, retrieves specific data. The objective is to display this data below or in place of the clicked button. <div v-for="(item, index) in items" :key="index"> <button @click="fetch ...