5

How should we handle a v-for combined with a v-if in this exemple:

Here my data.json:

[
  {
    image: 'foo.jpg'
  },
  {
    image: 'foobar.jpg',
    video: 'bar.mp4'
  },
  {
    image: 'barfoo.jpg'
  }
]

In my vue template, I'd like to render something like this:

<div v-for="(item, key, index) in data" : key="index">
   <img :src="item.image">
   <video v-if="!!item.video" :src="item.video"></video>
</div >

But as the documentation say, we should avoid v-if with v-for and instead use a computed value. But there I need to render the image even if the json entry doesn't have a video.

That's not a big deal, I've find a solution but I'd like to know the best way to handle this.

1 Answer 1

7

I think that you are misunderstanding the documentation. In this instance, it makes sense to use both v-for and v-if because you are always going to render at least the <img> and you might render the <video>. The documentation is trying to show that you should pre-filter a list of items if the v-if and v-for are on the exact same element.

The example the docs are showing are trying to get you to cut a list that would show only only 2 of the 3 total elements down to just 2 elements and letting the computed prop tell you when there are more. Otherwise you have to iterate through the entire list every time you need to re-render.

Consider this difference:

// An array of 1000 items but only 1 has a video element
const data = [0...999];

data.push({
  image: "some.jpg",
  video: "some.mp4"
});
<!--
We always render 1000 items but only some will have video 
-->
<div 
v-for="(item, key, index) in data" 
:key="index">
  <img :src="item.image">
  <video v-if="!!item.video" :src="item.video"></video>
</div>


<!-- 
We have to visit 1000 elements but 
only 1 will actually end up rendering
-->
<div 
v-if="!!item.video" 
v-for="(item, key, index) in data" 
:key="index">
  <img :src="item.image">
  <video :src="item.video"></video>
</div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.