3

I've got an array as below:

return {
   items: [
      {active: true, text: 'text1'},
      {active: true, text: 'text2'},
      {active: true, text: 'text3'},
      {active: true, text: 'text4'},
      {active: true, text: 'text5'}
      ...
   ]
}

I want to iterate it in the DOM using v-for (easy) but I want to iterate them in two templates - first 3 elements of the array in template1 and the rest of elements in template2:

template1:

<template v-for="item in items">
   first 3 elements:
   {{item}}
</template>

template2:

<template v-for="item in items">
   the rest of elements: 
   {{item}}
</template>

How should I modify my v-for to make this work?

2 Answers 2

17

You could either explicitly create two computed properties, based on the original items array, or just use a slice, for example:

<template v-for="item in items.slice(0, 3)">

and

<template v-for="item in items.slice(3)">

N.B. In both the above cases, it is assumed that items is always defined and always an array. If you want to go with the inline approach but items could be undefined, then you could use (items || []).slice().

Going with the computed property approach you could define something like:

computed: {
    itemsHead() {
        return this.items ? this.items.slice(0, 3) : [];
    },
    itemsTail() {
        return this.items ? this.items.slice(3) : [];
    }
}

Then refer to itemsHead and itemsTail in your templates.

Sign up to request clarification or add additional context in comments.

5 Comments

return this.items would have to be return this.items.length in your ternary expression because !![] is true. Or did you want to check if this.items is undefined?
@connexo you are right. The same is with v-for="item in items.slice(0, 3)", but Tom answered correct, because my arrays will have at least 3 elements. You can improve the answer if you wish to :)
@connexo the only problem is when this.items is not an array. If it's an empty array then that's not a problem.
Then use Array.isArray(this.items) as that will also clarify the intention.
Yep, or check that a property slice exists and is a function, or if it's a prop then specify type: Array, but I'm not sure any of this is in scope :)
0

I just figured out another solution if you have a little more complex object e.g. if you have an outer loop and an inner loop where you only want to render something if a condition is true and you can't use a computed method as you are in an inner loop. Please correct me if that's not true regarding computed methods inside loops.

So here is my solution:

<div v-for="fooparent in fooparentarray">
<template v-for="foo in fooparent.foos">
<div v-if="foo.someproperty === 1">{{foo.someproperty}}</div>
</template>
</div>

As template is not rendered there will be nothing rendered for arrayelements that don't meet the condition. So a div is only rendered if the condition is met.

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.