Reputation: 231
I have got a left menu, that can show contents depending of the id of the selected menu.
But i got === 0
and === 1
in the v-if
and I would like to avoid to put numbers manually there.
<template>
<v-card elevation="2" class="experiences-container">
<v-layout row wrap>
<v-flex md3 sm12 xs12 class="relative">
<div class="settings-list"
:class="switchSetting ? 'open' : ''">
<v-list>
<v-list-tile
v-for="(item, index) in menu"
:key="index"
:class="['experience-item', index === idSelectedSetting ? 'active' : '']"
@click="updateSelectedSetting(index)"
>
<v-list-tile-content>
<v-list-tile-title>{{ item.name }}</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action v-if="index == idSelectedSetting ? true : false">
<v-icon>chevron_right</v-icon>
</v-list-tile-action>
</v-list-tile>
</v-list>
</div>
</v-flex>
<v-flex md9 sm12 xs12>
<UserPasswordEdition class="setting-details"
v-if="idSelectedSetting === 0"
:class="switchSetting ? 'close' : ''"
/>
<div
class="setting-details"
:class="switchSetting ? 'close' : ''"
v-if="idSelectedSetting === 1">
<div class="WIP">Autre menu</div>
</div>
</v-flex>
</v-layout>
</v-card>
</template>
--
data() {
return {
menu: [
{ name: 'Mot de passe' },
{ name: 'Autre menu' }
],
idSelectedSetting: 0,
switchSetting: false,
};
},
methods: {
updateSelectedSetting(id) {
this.idSelectedSetting = id;
this.closeSwitchSetting();
},
openSwitchSetting() {
this.switchSetting = true;
},
closeSwitchSetting() {
this.switchSetting = false;
}
}
--
I just wanna change the v-if here:
<UserPasswordEdition class="setting-details"
v-if="idSelectedSetting === 0"
:class="switchSetting ? 'close' : ''"
/>
<div
class="setting-details"
:class="switchSetting ? 'close' : ''"
v-if="idSelectedSetting === 1">
<div class="WIP">Autre menu</div>
</div>
I tried a v-for
but I couldn't make it, or I don't know how to use it in this situation because it shows both content on each menu and I don't want that.
Thanks!
Upvotes: 0
Views: 1207
Reputation: 14171
You can create an array with all your options. You'll probably need to use :is to render individual components.
You should also add an index
on your data and compare it with a selectedIndex
when rendering.
data() {
return {
selectedIndex: 0, //default value goes here
itemsToShow: [
{
id: 0,
component: 'UserPasswordEdition',
},
{
id: 1,
component: 'OtherComponent'
}
]
}
}
And then update your template
<template>
...
<v-flex md9 sm12 xs12>
<component v-for="option in itemsToShow"
:key="option.id"
:is="option['component']
v-if="selectedIndex === option.id"
/>
</v-flex>
</template>
Note: this works if you need to pass the same props to all components, otherwise your rendering logic will grow a little more complex.
Edit: added this after @Jer got a warning about not using v-for
and v-if
on the same directive.
You can also use a computed property to filter your array
computed: {
filteredItemsToShow() {
return this.itemsToShow.filter(item => item.id === this.selectedIndex)
}
}
And then use filteredItemsToShow
when rendering
<template>
...
<v-flex md9 sm12 xs12>
<component v-for="option in filteredItemsToShow"
:key="option.id"
:is="option['component']
/>
</v-flex>
</template>
Notice the removal of v-if
as it is baked into the computed property.
Upvotes: 1
Reputation: 1434
You can extract your condition to computed property. Example:
<template>
...
<v-flex md9 sm12 xs12>
<UserPasswordEdition class="setting-details"
v-if="!isSelectedSetting"
:class="switchSetting ? 'close' : ''"
/>
<div
class="setting-details"
:class="switchSetting ? 'close' : ''"
v-if="isSelectedSetting"
>
<div class="WIP">Autre menu</div>
</div>
</v-flex>
</template>
<script>
export default {
data() {
return {
menu: [
{ name: 'Mot de passe' },
{ name: 'Autre menu' }
],
idSelectedSetting: 0,
switchSetting: false,
};
},
computed: {
isSelectedSetting() {
return this.idSelectedSetting === 1
}
}
}
</script>
Upvotes: 0