Reputation: 6276
I'm trying to toggle classes for multiple elements in Vuejs 2.0
, I have the following set of buttons which has a class of btn-primary
. Clicking a button shows a sub-group of that particular element. This is my code:
<button class="btn btn-primary btn-xs" v-on:click.prevent="getTags('investor')">Investor</button>
<button class="btn btn-primary btn-xs" v-on:click.prevent="getTags('research')">Research</button>
<button class="btn btn-primary btn-xs" v-on:click.prevent="getTags('company')">Company</button>
This shows the following element:
<div v-if="tag.investor">
<button class="btn btn-primary btn-xs" v-on:click.prevent="selectTags('Investor - Mutual Funds')">Mutual Fund</button>
<button class="btn btn-primary btn-xs" v-on:click.prevent="selectTags('Investor - Insurance')">Insurance</button>
<button class="btn btn-primary btn-xs" v-on:click.prevent="selectTags('Investor - FII')">FII</button>
</div>
<div v-if="tag.research">
<button class="btn btn-primary btn-xs" v-on:click.prevent="selectTags('Research - Tier I')">Research - Tier I</button>
<button class="btn btn-primary btn-xs" v-on:click.prevent="selectTags('Research - Tier II')">Research - Tier II</button>
</div>
I have the following in data()
:
tag: {
investor: false,
research: false,
company: false,
others: false,
},
And in methods
:
getTags: function (tag) {
this.tag.investor = this.tag.research = this.tag.company = this.tag.others = false
if(tag == 'investor')
{
this.tag.investor = true
}
if(tag == 'research')
{
this.tag.research = true
}
if(tag == 'company')
{
this.tag.company = true
}
if(tag == 'others')
{
this.tag.others = true
}
},
I want to have a class of btn-warning
and remove btn-primary
once any child element is being selected. Any ideas how to implement this, I don't want to have individual data elements and toggle class.
Upvotes: 1
Views: 7339
Reputation: 82459
I'd like to suggest a data driven approach for your Vue. Consider this data structure:
const tags = {
Investor:[
{display:"Mutual Fund", value:"Investor - Mutual Funds"},
{display:"Insurance", value:"Investor - Insurance"},
{display:"FII", value:"Investor - FII"},
],
Research:[
{display:"Research - Tier I", value:"Research - Tier I"},
{display:"Research - Tier II", value:"Research - Tier II"},
]
}
If you use that, then you can clean up your template considerably and handle any additional tags that you add to your data structure.
<div id="app">
<button v-for="(obj, key) in tags"
:key="key"
@click="currentTag = key"
class="btn btn-xs btn-primary">
{{key}}
</button>
<div>
<button v-for="tag in tags[currentTag]"
:key="tag"
class="btn btn-xs"
:class="tagClass(tag)"
@click="selectTags(tag.value)">
{{tag.display}}
</button>
</div>
</div>
Your Vue also looks a lot cleaner.
new Vue({
el:"#app",
data:{
currentTag: null,
tags,
selectedTags:[]
},
methods:{
selectTags(tag){
const index = this.selectedTags.findIndex(t => t == tag)
if (index >= 0)
this.selectedTags.splice(index, 1)
else
this.selectedTags.push(tag)
},
tagClass(tag){
const isSelected = this.selectedTags.includes(tag.value)
return {
'btn-warning': isSelected,
'btn-primary': !isSelected
}
}
}
})
Here is an example.
Upvotes: 9
Reputation: 38952
You can use the v-bind:class
directive.
<button
class="btn btn-xs"
v-bind:class="{ 'btn-warning': tag.research, 'btn-primary': !tag.research }"
v-on:click.prevent="selectTags('Research - Tier I')"
>
Research - Tier I
</button>
Upvotes: 3