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.