AlyssaAlex
AlyssaAlex

Reputation: 716

How can I show and hide a div based on what's clicked in another div in Vue js?

I have 2 divs, one that shows the names of the products(Product 1, Product 2... etc) and the other that shows the product articles(Product 1: Article 1, Product 2: Article 1, Product 2: Article 2... ). I would like to have a functionality where I click Product 1 and then Product 1's articles should appear. When I click another product, let's say Product 2 then Product 1's articles should be hidden and Product 2's articles are shown.

Like this:

CASE 1: When Product 1 is clicked

Product 1

Product 1's articles <--- Show div when page is loaded.

  1. Product 1: Article 1
  2. Product 1: Article 2

Product 2

Product 3

Product 4


CASE 2: When Product 2 is clicked

Product 1 <--- Hide div

Product 2

Product 2's articles <--- Show div

  1. Product 2: Article 1
  2. Product 2: Article 2

Product 3

Product 4

I have tried using the accordion by Boostrap Vue but this did not suit my needs in other requirements. This is what I have so far:

<div class="container">
    <div
      v-for="(product, productIndex) in productsandarticles"
      :key="productIndex"
    >
      <div class="articlelistingdesktop">
        <div class="productlisting">                             <--- Product Names Div
          {{ product[0].productNames['en'] }}
        </div>
        <div class="articlelisting">                             <--- Product Articles Div
          <h4>{{ product[0].productNames['en'] }} 's articles</h4>
          <div
            v-for="(productInner, productInnerIndex) in product"
            :key="productInnerIndex"
          >
            <nuxt-link :to="'/' + productInner.title_slug"> .    <--- Link to the articles
              {{ productInnerIndex + 1 }}. {{ productInner.title['en'] }}
            </nuxt-link>
          </div>
      </div>
    </div>
  </div>
</div>

All my data is coming from a JSON file and currently, my code shows all product names and their respective articles. I am trying to also avoid using jquery for my project. I would appreciate if someone could help.

Thanks!

Upvotes: 3

Views: 681

Answers (1)

Michal Lev&#253;
Michal Lev&#253;

Reputation: 37763

Just use reactive property to track index of "active" product...

In your component:

data() {
  return {
    activeProductIndex: null
  }
}
<div class="container">
    <div
      v-for="(product, productIndex) in productsandarticles"
      :key="productIndex"
    >
      <div class="articlelistingdesktop">
        <div class="productlisting" @click="activeProductIndex = productIndex">                
          {{ product[0].productNames['en'] }}
        </div>
        <div class="articlelisting" v-if="activeProductIndex === productIndex">
          <h4>{{ product[0].productNames['en'] }} 's articles</h4>
          <div
            v-for="(productInner, productInnerIndex) in product"
            :key="productInnerIndex"
          >
            <nuxt-link :to="'/' + productInner.title_slug"> .    <--- Link to the articles
              {{ productInnerIndex + 1 }}. {{ productInner.title['en'] }}
            </nuxt-link>
          </div>
      </div>
    </div>
  </div>
</div>

Changes in template explained:

<div class="productlisting" @click="activeProductIndex = productIndex"> - using click event to assign current product index into activeProductIndex variable

<div class="articlelisting" v-if="activeProductIndex === productIndex"> - render article listing only if product is "active"

Upvotes: 1

Related Questions