I’m looking to add a ‘blank’ element at certain indexes when I loop through an array in Vue.js
<template v-for="(item, index) in content"> <div v-if="index == 1" :key="index" class="Empty"/> </div> <div :key="index" class="Content"/> </div> </template> props: { content: { type: Array, default: () => [], }, emptyIndexes: { type: Array, default: () => [], }, },
Above is a simplified version of my code that will render an ’empty’ div at index 1, but I’m looking to do this for multiple indexes that are being passed as an array to a prop dynamically ’emptyIndexes’ (eg. [0, 3, 7, 8]). The numbers given in the array will vary.
Any help with this would be most appreciated.
Advertisement
Answer
You need to check if the emptyIndexes
array includes the given index for each iteration:
<template v-for="(item, index) in content"> <div v-if="emptyIndexes.includes(index)" :key="index" class="Empty"/> </div> <div :key="index" class="Content"/> </div> </template> props: { content: { type: Array, default: () => [], }, emptyIndexes: { type: Array, default: () => [], }, },
You should note if you have a huge amount of content
and/or a very large emptyIndexes
, this approach could become quite slow due to its computational complexity (each re-render and iteration causes an iteration searching over emptyIndexes
.
Instead, you should either an ES6 map with the key being the the index and the value being true.
You can then check like this:
v-if="emptyIndexes.has(index)"
Which would be an O(1) operation as you are just checking if the item exists in the map instead of looping over an entire array of numbers.
You could watch emptyIndexes
, and each time it changes, generate a map from it.
Alternatively, if emptyIndexes
does not change frequently, you can generate the map when you would normally generate emptyIndexes
.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
This note on code efficiency should be taken with caution: It’s not advisable to prematurely optimise if it introduces unnecessary complexity and isn’t currently necessary.
I’m just including the explanation as a loop inside a loop can be quite expensive if the arrays are large or the list re-renders frequently. For most use cases, using .includes
would be advisable as it’s much simpler to understand at a glance.