Skip to content
Advertisement

Is this a valid way of using v-if and v-for in order to preserve order?

I know that v-if should not be used to filter elements from a list and a computed prop should be used instead, but what if I need to render a different thing depending on a prop from that list ?

Example: I have a list of objects, I loop through it with `v-for’ and depending on a prop in that object I render one of 2 components.

myList: [
  {
    name: 'James',
    occupation: 'sailor'
  },
  {
    name: 'Marco',
    occupation: 'baker'
  },
]

<div v-for="(person, index) in myList" :key="index">
  <ComponentOne :name="person.name" v-if="person.occumation == sailor">
  <ComponentTwo :name="person.name" v-if="person.occumation == baker">
</div>

Is this a valid case since every object inside the list needs to be shown ? I know I can use computed props and 2 loops but that way I lose the order of the objects, in My scenario I need to show a different component depending on that “occupation” prop and keep them in order.

Is this A valid use of v-if v-for since I’m not using them both on the same element ?

The broader question I guess is: Is it fine to use v-if inside v-for, the guidelines only specify not using them on the same element ?

Advertisement

Answer

I think better way is to use Dynamic Components. You can keep track of component with occumation and use it in v-for.

data() {
  return {
    myList: [
       {
         name: 'James',
         occupation: 'sailor'
       },
       {
         name: 'Marco',
         occupation: 'baker'
       }
     ],
     componentMapper: {
       sailor: 'ComponentOne',
       baker: 'ComponentTwo'
     }
  }
}

<div v-for="(person, index) in myList" :key="index">
  <component :is="componentMapper[person.occumation]" v-bind="{ name: person.name }">
</div>

Don’t forget to register ComponentOne && ComponentTwo components

Advertisement