When you want to loop without using wrappers, use a <template>:
<tr v-for="( block , index ) in listRenderBlock" :key="index">
<template v-for="(section , i ) in block.sections">
<td :key="`b_${index}_${i}`">
<p>
{{ block.name }}
</p>
</td>
<td :key="`s_${index}_${i}`">
<p>
{{ section.name }}
</p>
</td>
</template>
</tr>
Note: <div>'s are invalid children of <tr>.
See it working:
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
data: () => ({
listRenderBlock: [{
name: 'B-1',
sections: [
{ name: 'S-1' },
{ name: 'S-2' }
]
}, {
name: 'B-2',
sections: [
{ name: 'S-1' },
{ name: 'S-2' }
]
}]
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<table id="app">
<tr v-for="(block, index) in listRenderBlock" :key="index">
<template v-for="(section, i) in block.sections">
<td :key="`b_${index}_${i}`">
<p v-text="block.name" />
</td>
<td :key="`s_${index}_${i}`">
<p v-text="section.name" />
</td>
</template>
</tr>
</table>
Another note: <template>'s can't be :key-ed, as they don't end up being DOM elements. So you have to come up with your own :key-ing system, applied to the actual DOM elements. In your case, I made keys out of index + i, prefixed by either b for block <td>'s or s for section <td>'s. It doesn't really matter how the keys look like, as long as they're unique. (They are not displayed anywhere, they're just used by Vue to update the DOM elements when your model/data changes).