Codinga
Codinga

Reputation: 620

Using v-for and v-if in the same element

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

Answers (6)

RJ Jaictin
RJ Jaictin

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

Umair Arshad
Umair Arshad

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

enter image description here

Upvotes: 1

Hassan Tariq
Hassan Tariq

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

zachzurn
zachzurn

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

omarjebari
omarjebari

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

Kirill Matrosov
Kirill Matrosov

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

Related Questions