0

Hello I'm doing a dropdown in my website and I'm really new in Vue. I'm using conditional rendering for display some cards. Something like: Cars, Motos, Bikes. When i click on Cars there is a dropdown and i get a list of cars, same on others.

                        <h2 class="text-center my-font text-light"><button v-on:click="toggle = !toggle" class="badge badge-danger menu-label-size w-50">Cars</button></h2> 
                        <div v-if="toggle" class="row">
                          <div class="col-12">
                            <div class="cards-item text-center ">
                              <div v-for="item in cars" ::key="item.id" class="card" style="width: 10rem;">
                                  <img :src="'./images/cars/img' + item.img + '.png'" class="card-img-top img-fluid" alt="item.name">
                                  <div class="card-body d-flex flex-column justify-content-end">
                                    <h4 class="card-title my-font">{{ item.name }}</h4>
                                    <p class="badge-danger font-weight-bold">{{ item.price }}</p>
                                  </div>
                                </div>
                            </div>
                          </div>
                        </div>

                        <h2 class="text-center my-font text-light"><button v-on:click="toggle = !toggle" class="badge badge-danger menu-label-size w-50">Motos</button></h2> 
                        <div v-if="toggle" class="row">
                          <div class="col-12">
                            <div class="cards-item text-center">
                              <div v-for="item in motos" ::key="item.id" class="card" style="width: 10rem;">
                                  <img :src="'./images/motos/img' + item.img + '.png'" class="card-img-top img-fluid" alt="item.name">
                                  <div class="card-body d-flex flex-column justify-content-end">
                                    <h4 class="card-title my-font">{{ item.name }}</h4>
                                    <p class="badge-danger font-weight-bold">{{ item.price }}</p>
                                  </div>
                                </div>
                            </div>
                          </div>
                        </div>

                        <h2 class="text-center my-font text-light"><button v-on:click="toggle = !toggle" class="badge badge-danger menu-label-size w-50">Bikes</button></h2> 
                        <div v-if="toggle" class="row">
                          <div class="col-12">
                            <div class="cards-item text-center">
                              <div v-for="item in bikes" ::key="item.id" class="card" style="width: 10rem;">
                                  <img :src="'./images/bikes/img' + item.img + '.png'" class="card-img-top img-fluid" alt="item.name">
                                  <div class="card-body d-flex flex-column justify-content-end">
                                    <h4 class="card-title my-font">{{ item.name }}</h4>
                                    <p class="badge-danger font-weight-bold">{{ item.price }}</p>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>

My script:

const app = new Vue({
el: '#app',
data: {
    show: false,
    cars: [{data}],
    motos: [{data}],
    bikes: [{data}],
},
})

But when i click on Motos it only closes Cars. How to make it dynamic? Like if i press Motos then it opens and Cars closes, same for Bikes

1
  • 1
    I would use this algorithm: create a variable called activeSelection = null; when you click on e.g. cars it will assign cars to activeSelection variable. and create if statement check to close / open lists this way: activeSelection === 'cars' - for cars. Use similar approach for other types. To save some bytes, you can create constants with numbers e.g. cars variable will be 0, motos 1, and use these constants to assign activeSelection variable to existing constants and do a check using the same constants. Commented Sep 17, 2022 at 16:01

1 Answer 1

1

You can merge your vehicles data in mounted hook, then loop thru items:

const app = new Vue({
  el: '#demo',
  data: () => ({
    items: [],
    expanded: null,
    cars: [{img: '', name: 'car1', price: 5}, {img: '', name: 'car2', price: 6}, {img: '', name: 'car3', price: 8}],
    motors: [{img: '', name: 'motor1', price: 5}, {img: '', name: 'motor2', price: 6}, {img: '', name: 'motor3', price: 8}],
    bikes: [{img: '', name: 'bike1', price: 5}, {img: '', name: 'bike2', price: 6}, {img: '', name: 'bike3', price: 8}]
  }),
  methods: {
    expand(idx) {
      this.expanded = this.expanded === idx ?  null : idx
    }
  },
  mounted() {
    const car = {title: 'Cars', products: this.cars}
    const motor = {title: 'Motors', products: this.motors}
    const bike = {title: 'Bikes', products: this.bikes}
    this.items = [car, motor, bike]
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<div id="demo" class="d-flex">
  <div v-for="(group, index) in items" :key="index">
    <h2 class="text-center my-font text-light">
      <button @click="expand(group)" class="badge badge-danger menu-label-">{{ group.title }}</button>
    </h2>
    <div class="row">
      <div class="col-12">
        <div class="cards-item text-center">
          <div v-if="expanded === group">
            <div v-for="(item, idx) in group.products" :key="idx" class="card" style="width: 10rem;">
              <img :src="'./images/motos/img' + item.img + '.png'" class="card-img-top img-fluid" :alt="item.name">
              <div class="card-body d-flex flex-column justify-content-end">
                <h4 class="card-title my-font">{{ item.name }}</h4>
                <p class="badge-danger font-weight-bold">{{ item.price }}</p>
              </div>
            </div>
           </div>
        </div>
      </div>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you this is the behaviour i was looking for.. but i can't adapt it to my code, when i put data function i get error. I have static data for cars,motos,bikes and i loop them to show in html. I edited the whole code of my question for be more specific
@shaddark hey mate, check again, I updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.