Reputation: 465
I want to render a table, and as I would need to work on the cell, I define them through a component.
Below is the example in the fiddle:
Vue.component('table-cell', {
props: {
'r': 0,
'c': 0
},
template: '<td style="border: 1px solid black; width:2em;">{{ c }}</td>'
});
var app = new Vue({
el: '#app',
data: {
rows: 3,
cols: 3,
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<tbody>
<tr v-for="r in rows">
<table-cell v-for="c in cols" v-bind:key="c">
</tr>
</tbody>
</table>
</div>
But the generated code is not what I expected :
<div id="app">
<td></td>
<td></td>
<td></td>
<table>
<tbody>
<tr></tr>
<tr></tr>
<tr></tr>
</tbody>
</table>
</div>
For a reason I do not understand, my td
elements are generated outside the tr
ones, and everything seems to work as if my two loops were not nested. When I change the <table-cell>
with simple <td>
(not using a component), it works as expected.
Upvotes: 3
Views: 390
Reputation: 15165
You ran into an HTML parsing edge case which is described in the Vue docs under HTML Template Parsing Caveats. The workaround is to use the is
attribute on custom components inside of table
s. Here's a fixed working example of your code:
Vue.component('table-cell', {
props: {
r: Number,
c: Number,
},
template: '<td>{{r}}, {{c}}</td>',
})
var app = new Vue({
el: '#app',
data: {
rows: 3,
cols: 3,
},
})
td {
border: 1px solid black;
padding: 5px 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<tbody>
<tr v-for="r in rows" :key="r">
<td is="table-cell" v-for="c in cols" :key="c" :r="r" :c="c">
</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 3