Skip to content
Advertisement

Vuejs doesn’t render components inside HTML table elements

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, the is 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>

See https://jsfiddle.net/7v6yrf3x/1/.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement