V-for inside v-for?

I’m creating a calendar layout using v-for. 7 columns each containing rows with time stamps.

Basically a v-for inside a v-for.

I created the first column and using v-for to generate rows of time stamps from an array.

How do I generate 7 columns each containing the same rows?

Do I create 2 x new Vue? or put two data: inside the same new Vue?
Do I use containing

s ?

Could someone show me an example of how to do this?
Much appreciated thanks!

Please provide code related to your issue. Without it, it’s hard for us to help. You can refer to our guide on asking for help for more information. Thanks!

example:

<template>
  <table>
    <tr class="row" v-for="(cols, rowIndex) of rows" :key="rowIndex">
      <td class="col" v-for="(cell, colIndex) of cols" :key="colIndex">
        {{ cell }}
      </td>
    </tr>
  </table>
</template>

<script>

export default {
  data() {
    return {
      rows: [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
      ],
    }
  },
}
</script>
1 Like
<div class="cal-columns" >
    <div class="logo">Calendar</div>
    <div id="calGenerator" >
        <div>M</div>
        <div v-for="calHour in calHours" >
            {{ calHour + ":00" }}
        </div>
    </div>
</div>


var calendar = new Vue ({
el: '#calGenerator',
data: {
	calDays: ['M', 'T', 'O', 'T', 'F', 'L', 'S'],
	calHours: ['09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21']
	}
})

I had the v-for working just fine, but the nested v-for is causing me problems :slight_smile: NEWBIE alert :wink:

<template>
  <div class="cal-columns">
    <div class="logo">Calendar</div>
    <div v-for="(calDay, index) of calDays" :key="index">
      <div>{{ calDay }}</div>
      <div v-for="(calHour, index) of calHours" :key="index">
        {{ calHour + ":00" }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      calDays: ['M', 'T', 'O', 'T', 'F', 'L', 'S'],
      calHours: ['09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21']
    }
  }
}
</script>

NEWBIE alert can be caused by using both v-for and id="calgenerator on the same element

1 Like

Interesting, I don’t yet understand the export feature, so I’m posting this link for information:

If this is my root Vue instance, should I replace export default with var calendar = new Vue ?

Because I can’t get it working.

yes! root Vue instance use new Vue()

1 Like

Vuejs.org shows how to put the v-for inside the <template> tag: <template v-for=""> in your code you placed the parent v-for inside the <template>

no id="" ? Is your <template> + <script> both meant to live in the .js file?

MAJOR NEWBIE alert

If you’re using single file components, then yes.

Thanks James! But I haven’t learned how to use SFC yet. It’s what I am the most eager to learn about actually.

I can’t find an example of nested v-for on vuejs.org where a vertical v-for generates vertical instances while another v-for multiplies that horizontally.

The example given in this thread doesn’t seem to work in the ways I have tried to implement it.

But so far I have still not figured out how to do this. A little surprising that after a week of searching I can’t find an example of this. I would have thought this was a very basic and often used thing.

I’m probably doing something wrong, but I got the v-for working pretty easy but I can’t get the “parent v-for” working. It just renders the whole thing blank.

Thought: perhaps I should v-for loop on an array of objects containing arrays of items?

Maybe it’s in the way you’re describing things? The example given seems to do as requested. Limited in its use, but it does display calendar columns: https://jsfiddle.net/jamesbrndwgn/jo5f8uxz/3/

1 Like

Thanks James! This is great.

I was wrecking my head trying to describe what I wanted in a way that made sense, I probably did badly :slight_smile: but you were able to crack the code and understand what I wanted.

You declared data as a function, which seems to be what’s different from what I was trying, and you didn’t use template as someone suggested. Always multiple ways of doing something.

In fact, the reason I use <template> + <script> in this forum is just for syntax highlighting.
Switch to progressive:

<div id="cal-app">

	<div class="cal-columns">
		<div class="col" v-for="(calDay, index) of calDays" :key="index">
			<div class="cell headline">{{ calDay }}</div>
			<div class="cell" v-for="(calHour, index) of calHours" :key="index">
				{{ calHour + ":00" }}
			</div>
		</div>
	</div>

	<table class="cal-table">
		<tr v-for="(calDay, index) of calDays" :key="index">
			<th>{{ calDay }}</th>
			<td v-for="(calHour, index) of calHours" :key="index">
				{{ calHour + ":00" }}
			</td>
		</tr>
	</table>

	<table class="cal-table">
		<thead>
			<tr>
				<th v-for="(calDay, index) of calDays" :key="index">
					{{ calDay }}
				</th>
			</tr>
		</thead>
		<tbody>
			<tr v-for="(calHour, index) of calHours" :key="index">
				<td v-for="(calDay, index) of calDays" :key="index">
					{{ calHour + ":00" }}
				</td>
			</tr>
		</tbody>
	</table>

</div>

<script>
	const calApp = new Vue({
		el: "#cal-app",
		data() {
			return {
				calDays: ["M", "T", "O", "T", "F", "L", "S"],
				calHours: ["09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21"]
			};
		}
	});
</script>

<style>
	.cal-columns {
		display: flex;
		margin: 1em auto;
		border: 1px solid #777;
		width: max-content;
		padding: 1em;
		text-align: center;
	}

	.cell {
		padding: 1em;
	}

	.cell.headline {
		font-weight: bold;
	}

	.cal-table {
		margin: 1em auto;
		padding: 1em;
		border: 1px solid #777;
	}

	.cal-table td,
	.cal-table th {
		padding: 1em;
	}
</style>
1 Like

Ok thanks. I saw a solution with v-for on vuejs.org so I thought there was perhaps some benefit I did not understand.

I notice you both use “(calDay, index) of calDays” instead of just “calDay of calDays”. I was thinking that the :key=“index” would provide the identifier for each render. So I’m curious if there’s something to learn here?