When using a VueJS template and trying to inject a component inside of a table
,
such as a tr
, the rendered component is hoisted outside of the parent element.
This problem has bitten me repeatedly, again and again.
You write this:
<table>
<my-component v-for=...>
</table>
And it renders like this:
<tr>...<tr>
<table>
</table>
In a nutshell, there are DOM Parsing Caveats
and elements like table
have restrictions on what elements can appear inside them. (FYI: ul
, ol
, select
have this issue as well).
The solution is to use VueJS's is attribute:
<table>
<tr is="my-component" v-for=...>
</table>
This causes the template parsing to be happy, as table
(or even a nested tbody
) will be getting a "true" tr
element, but
its content will be rendered by the named component.
UPDATE: In VueJS 3 the v-is
tag now evaluates as a Javascript expression!
This means you need to pass it a string, as in <tr v-is="'my-component'">
. See workarounds.