I want to render a custom component that displays a row inside a table.
I have the following code:
// js file Vue.component('message-row', { data: function () { return { msg: 'Hello' } }, template: '<tr><td>{{ msg }}</td></tr>' }); new Vue({ el: '#app' }); // html file <div id="app"> <table><message-row></message-row></table> </div>
The problem is that the row ends up rendered outside the table! Like this:
<div id="app"> <tr><td>Hello</td></tr> <table></table> </div>
You can check it out in this JSFiddle https://jsfiddle.net/eciii/7v6yrf3x/
I’m not sure if this is a bug or I’m just missing something really obvious here…
Advertisement
Answer
See Vue.js’s documentation about DOM Template Parsing Caveats:
Some HTML elements, such as
<ul>
,<ol>
,<table>
and<select>
have restrictions on what elements can appear inside them, and some elements such as<li>
,<tr>
, and<option>
can only appear inside certain other elements.This will lead to issues when using components with elements that have such restrictions. For example:
<table> <blog-post-row></blog-post-row> </table>The custom component
<blog-post-row>
will be hoisted out as invalid content, causing errors in the eventual rendered output. Fortunately, theis
special attribute offers a workaround:<table> <tr is="blog-post-row"></tr> </table>
You need to add the component using the is
attribute as follows.
<table><tr is="message-row"></tr></table>