Reputation: 620
Hello i'm using vuejs and i need your help to get the best practice to do this: langs : is an object of languages :
langs: {'1':'fr', '2':'en', '3':'ar'},
has_lang : equal to 1 for the case which i need enter a value for each lang and equal to 0 for case which i need only enter one value for all languages
What i do now :
<md-layout md-gutter>
<md-input-container v-if="has_langs" v-for="lang in langs">
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="attValues"></md-input>
</md-input-container>
<md-input-container v-if="has_langs == 0">
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="inputa"></md-input>
</md-input-container>
</md-layout>
What i need is not duplicate the input * two times this input * :
<md-input-container>
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="inputa"></md-input>
</md-input-container>
There is a way to set v-for and v-if in the same element or something else that can do this?
Upvotes: 2
Views: 25027
Reputation: 91
You can wrap the element with v-for
with a <template v-if="..."></template>
element like this:
<md-layout md-gutter>
<template v-if="has_langs">
<md-input-container v-for="lang in langs">
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="attValues"></md-input>
</md-input-container>
</template>
<template v-if="has_langs == 0">
<md-input-container>
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="inputa"></md-input>
</md-input-container>
</template>
</md-layout>
Upvotes: 0
Reputation: 61
According to the official Vue documentation, you should not use v-if
with v-for
on the same element. Have a look on the link.
https://vuejs.org/guide/essentials/conditional.html
Upvotes: 1
Reputation: 59
Besides the option to create an additional filtered computed (effectively eliminating the need to use v-for and v-if on the same element), you also have a template level way of dealing with such edge-cases: the tag.
The tag allows you to use arbitrary template logic without actually rendering an extra element. Just remember that, because it doesn't render any element, you have to place the keys from the v-for on the actual elements, like this:
<template v-for="(guide, index) in guides"> <article v-if="isGuideVisible(guide)"
:key="index"
class="post-item post-guide"
:class="[guide.categories.toString().replace(/,/g, ' ')]"><header>
<h1 v-text="guide.title.rendered" /></header>
Upvotes: 0
Reputation: 2201
You could do the v-if
with a v-else
on the md-layout
the component level and get the result you want.
<md-layout v-if="has_langs" md-gutter>
<md-input-container v-for="lang in langs">
...
</md-input-container>
</md-layout>
<md-layout v-else md-gutter>
<md-input-container>
...
</md-input-container>
</md-layout>
Upvotes: 0
Reputation: 5499
You can't really use v-if and v-for on the same element. Best to put the v-if on a parent element.
Upvotes: 0
Reputation: 6000
You can move all checks for has_langs and langs to code.
computed: {
__langs(){
return this.has_langs === 1? this.langs : {'0': 'Params for all'};
}
},
methods: {
manipulateWithLangs(){
if (this.has_langs === 1){
//do
} else {
// do something else
}
}
}
<md-layout md-gutter>
<md-input-container v-for="lang in __langs">
<label>@{{ attribute.attribute }} @{{ lang }}</label>
<md-input v-model="attValues"></md-input>
</md-input-container>
</md-layout>
Upvotes: 0