Reputation: 8366
I'm hoping to find a way to iterate over an #each block a set amount of times in Svelte 3. In Vue I would do something like this:
<li v-for="i in 3"><!-- somecontent --></li>
But as I understand Svelte handles loops much differently using the .length property of the array being #eached. Is there some way to pull off something like this in Svelte?
{#each 3 as i}
<li><!-- somecontent --></li>
{/if}
Upvotes: 90
Views: 64687
Reputation: 3180
An #each
tag can loop anything with a length property, so:
{#each {length: 3} as _, i}
<li>{i + 1}</li>
{/each}
will also work, if you prefer.
Also since Svelte 5 you can drop the as
{#each { length: 8 }, rank}
<div>{rank}</div>
{/each}
Upvotes: 198
Reputation: 1821
I'm just going to throw this method out there for anyone who would like to consider an alternative to arrays...
Generators are supported by over 97% of browsers globally, according to Can I Use. Instead of creating an Array, we can define a generator function that yields the given number of times.
Javascript:
function* range(start, end) {
for (let i = start; i < end; i++) yield i;
}
... or Typescript:
function* range(start: number, end: number): Generator<number> {
for (let i = start; i < end; i++) yield i;
}
Then use it in your Svelte block:
{#each range(1, 3) as i}
<li><!-- --></li>
{/each}
The usage is identical to the method described in @Dmitry-Kokhanevich's answer, so I just copied the Svelte code block from theirs for this example.
Obviously, you might want to adjust the comparison operator to be <=
instead of <
if you want to include the end number, or reverse the operation entirely if you are using the numbers and want to count down instead of up. This method allows for a lot of flexibility.
For example, you can simplify it's usage slightly if you just want to use it to repeat a loop a certain number of times without caring what the index number actually is:
function* repeat(count: number): Generator<number> {
for (let i = 0; i < count; i++) yield i;
}
Then, use it like this:
{#each repeat(4) as i}
<li><!-- --></li>
{/each}
I think that makes the code a little more self-documenting and it is extremely close to the syntax requested by the original asker.
Upvotes: 2
Reputation: 11
You can also do it with helper:
/* code */
export function range(from, to) {
const result = [];
let i = from;
while (i <= to) {
result.push(i);
i += 1;
}
return result;
}
<!-- template -->
{#each range(1, 3) as i}
<li><!-- --></li>
{/each}
Upvotes: 1
Reputation: 205
You can use clean variable from the script section (mmm... for a pagination):
// script
export let numOfPages = 10
const pagesArray = Array.from({length: numOfPages}, (x, i) => i+1) // [1,2,3,4,5,6,7,8,9,10]
// template
{#each pagesArray as page}
<li>{page}</li>
{/each}
Upvotes: 1
Reputation: 1179
i Use like this for travelling from a
to b
in Svelte
{#each Array.from(Array(b+1).keys()).slice(a) as i }
<h1>{i}</h1>
{/each}
example (1 to 100):
{#each Array.from(Array(100+1).keys()).slice(1) as i }
<h1>{i}</h1>
{/each}
Upvotes: 3
Reputation: 74146
You can use {#each ...}
, like:
{#each Array(3) as _, i}
<li>{i + 1}</li>
{/each}
Upvotes: 131