1

I have this accordion and a collapse (as a component because I need to loop it). Here's the code:

accordion.vue

<div class="accordion col-lg-8 mx-auto" role="tablist">
    <b-card no-body class="mb-1 py-2" v-for="each in questions" :key="each.id">
        <Collapses v-bind:each="each"/>
    </b-card>
</div>

Collapses.vue

<div>
    <b-button @click="isActive = !isActive" role="tab" block v-b-toggle="'accordion-'+each.id">{{ each.question }}
     <i class="float-right fa" :class="{ 'fa-plus': !isActive, 'fa-minus': isActive }"></i>
     </b-button>

     <b-collapse v-bind:id="'accordion-'+each.id" visible accordion="my-accordion" role="tabpanel">
         <b-card-body>
              <b-card-text>{{ each.answer }}</b-card-text>
         </b-card-body>
      </b-collapse>
</div>

<script>

export default {
    props: ["each"],
    data() {
        return {
            isActive: false
        }
    }
}
</script>

The accordion works fine except the icons. The accordion only shows one (expanded) collapse at a time. Whenever I click another collapse, the previous collapse closes, but the icon doesn't change (because I did not click it). How do I automatically change the icon whenever the collapse closes?

tony19
  • 125,647
  • 18
  • 229
  • 307

2 Answers2

0

The b-collapse events include show and hide, which is emitted when the component state changes. Thus, you could use a v-on directive (or @ for shortand) to bind an event listener in the template that sets the isActive flag accordingly:

<b-collapse @hide="isActive = false" @show="isActive = true">

Then you could remove the button-click handler as it's already taken care of by the event binding above.

demo

tony19
  • 125,647
  • 18
  • 229
  • 307
-1

Your data is defined like method, try to do it in more clear way:

{
    data: () => ({
        isActive: false
    })
}
Asimple
  • 650
  • 3
  • 8
  • The syntax in the question is the correct one since the OP is using SFC files. – kissu Feb 17 '21 at 10:07
  • @kissu that syntax may cause context problems, which can follow such bugs – Asimple Feb 17 '21 at 10:20
  • IMO, following strictly the official docs syntax is better than having a more fancy way and losing `this` at the same time. I've tried it and experienced some ugly issues with it. Ofc it depends on what you're trying to do, but here it's the usual way of handling some data, nothing too fancy. https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function – kissu Feb 17 '21 at 10:24
  • @kissu There is difference between function and method. Function will have it's own context, but method will use object context.. – Asimple Feb 17 '21 at 10:26
  • Not sure why you recommend using the method syntax still. – kissu Feb 17 '21 at 10:29
  • @kissu I recommend to define data as Function, accordingly to VueJs doc. `data() {}` is method and it's not same to `data: function () {}`, also `() => {}` is just arrow function, it can be used to define data. – Asimple Feb 17 '21 at 10:33
  • It's just sugar syntax, it's exactly the same. Check this answer and leave him a like btw: https://stackoverflow.com/a/48981021/8816585 – kissu Feb 17 '21 at 10:40
  • Man, he can use `data: function() {}`, but not `data() {}`. It's not sugar. You can just google difference, at least. Anyway, i'm off – Asimple Feb 17 '21 at 10:45