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...
See Vue.js's documentation about DOM Template Parsing Caveats (Vue3):
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>