How can I add loading ONLY to the clicked button in vuejs?

Using index of item in list.

You can register a new variable in your data for example indexClicked .

data () {
    return {
        // Some predefined value, 0 isn't good because index can be 0.
        indexClicked: undefined // Some predefined value
    }
}

And when you click at button you can send index value:

<td>
<v-btn class="primary"
       :loading="loading && indexClicked === index" 
       :disabled="loading && indexClicked === index" 
       @click="fetchGetReportDetailed(item, index)">
       {{ $t('message.printButton') }}
</v-btn>
</td>

And in your fetchGetReportDetailed(item, index) method you need to assign index to this.indexClicked like:

fetchGetReportDetailed (item, index) {
    // Your code
    this.indexClicked = index;
}

This should work. But if you need more information please provide more code.

Note if you have a problem with multiple conditions in :disable you can create a method which will return true or false depends on condition loading && this.indexClicked === index.

Good luck!


You're using a single data property for all rows, so in mounted hook add a property called loading to each row like :

mounted(){
   this.getReportInfo=this.getReportInfo.map(rep=>{
               rep.loading=false;
             return rep;
         });
}

and the template do:

   <tr v-for="(item,index) in getReportInfo" :key="index">
                            <td>{{ item.id }}</td>
                            <td>{{ item.periodFrom }}</td>
                            <td>{{ item.periodTo }}</td>
                            <td><v-btn  class="primary" :loading="item.loading" :disabled="loading"  @click="fetchGetReportDetailed(item,index)" >{{ $t('message.printButton')}}</v-btn></td>
                        </tr>

in fetchGetReportDetailed method :

fetchGetReportDetailed(item,index){

....

this.getReportInfo[index].loading=true;
this.$set(this.getReportInfo,index,this.getReportInfo[index])
}

You could separate the tr that is displaying the data into its own state-full component and call the function from within the component.

This way the state of loading for each item in the array will be local to its own component.