Search code examples
htmlcssvue.jscarouselvuejs3

Vue3: display a div conditionally for child based on parent div's class


I'm new to Vue, and I'm working off of the active classes example in this Vue3 carousel plugin. I'd like to display the text and link divs only for the carousel__slide--active class, but as it is now, all carousel__items display their corresponding text and links. It seems like I should be able to do a v-if or v-bind to show image.text and image.link only for the child class carousel__slide--active, but I have not been able to get either one to work. Any advice would be much appreciated.

Relevant code:

<Slide v-for="(image) in stack.images" :key="image">
  <div class="carousel__item">
    <img
      :src="image.src"
      :alt="image.alt"
      :text="image.text"
      :link="image.link"
    />
    <!-- <div class="{ 'carousel__slide--active': true }"> -->
    <!-- <div v-bind:class="{ 'carousel__slide--active': isActive }"> -->
      <div class="overlay-shown">
        <div v-if="image.text" class="stack-text">{{ image.text }}
        </div>
        <div v-if="image.link" class="stack-text">
          <a v-bind:href="image.link">View Video</a>
        </div>
      </div>
    <!-- </div> -->
  </div>
</Slide>

<style>
.carousel__slide--active > .carousel__item {
  transform: scale(1);
  box-shadow: 8px 8px 5px -4px rgba(0, 0, 0, 0.5);
  z-index: 999 !important;
}

.overlay-shown {
  width: 600px;
  height: auto;
  background-color: #006eb7;
}
</style>

Solution

  • You could possibly use css to solve it too, but if you want to use the "vue-way" you will need to check against the current slide to ba able to determine whether to show the content or not.

    The documentation on the use (I'd say) is not very clear, but if you look into the source you'll see that the Carousel component does use the modelValue to bind the current index.

    template:

    <template>
      <Carousel v-model="currentSlide">
        <Slide v-for="(image, i) in stack.images" :key="image">
          <div class="carousel__item">
            <img
              :src="image.src"
              :alt="image.alt"
              :text="image.text"
              :link="image.link"
            />
            <div class="overlay-shown" v-if="currentSlide === i">
              <div v-if="image.text" class="stack-text">{{ image.text }}
              </div>
              <div v-if="image.link" class="stack-text">
                <a v-bind:href="image.link">View Video</a>
              </div>
            </div>
          </div>
        </Slide>
      </Carousel>
    </template>
    
    <script>
      // in data or with `ref` via setup
      data: () => ({
        currentSlide: 0,
      })
    </script>
    

    so you have the index (i in v-for="(image, i) in stack.images") and compare it to currentSlide