When I load a vue component inside a @foreach tag it gets rendered first, outside of its parent component.
//view
<div class="contenido" style="padding-top:5%">
<table class="table">
<thead class="thead-dark">
<tr>
<th class="col-md-8">Nombre descripción general</th>
<th class="col-md-2">Actualizar</th>
<th class="col-md-2">Consultar</th>
</tr>
</thead>
<tbody>
@foreach($descs as $desc)
<tab-descgen desc-nombre = "{{ $desc -> nombre }}" desc-id = "{{ $desc -> id }}"></tab-descgen>
@endforeach
</tbody>
</table>
//vue component
<template>
<tr >
<td>{{ this.descNombre }}</td>
<td><i style="font-size:30px;" class="fa fa-edit float-center"></i>
</td>
<td><i style="font-size:30px;" class="fa fa-arrow-circle-right
float-center"></i></td>
</tr>
</template>
<script>
export default {
props:['descNombre', 'descId'],
When this gets rendered the table rows inside the vue component will be rendered above the header, and I don't quite understand why. I want to know if I'm missing something.
Even ignoring all the server-side stuff, this won't work:
<tbody>
<tab-descgen></tab-descgen>
</tbody>
It'd be fine in a single-file component but if this markup makes it to the browser (as it will in your case) it'll rip the tab-descgen
out of the table before Vue gets anywhere near it.
You'd need to use is
to work around it:
<tbody>
<tr is="tab-descgen"></tr>
</tbody>
It's explained here in the docs:
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
In short, only tr
elements are allowed as direct children of tbody
, anything else gets pulled out. The workaround is to use a tr
and then let Vue know what you really wanted using is
.
Since Vue v3.4.0 Slam Dunk, we have a breaking change
v-is directive has been removed. It was deprecated in 3.3. Use the is attribute with vue: prefix instead.
More details for :is
are available here.
But TLDR, the new syntax is
<tbody>
<tr is="vue:tab-descgen"></tr>
</tbody>
This is the reason as of why this happens in Vue, mostly an HTML placement restriction.