1

In a nutshell I'm trying to do something like this in VueJS (v2.5.17):

<table>
  <my-multi-row-entry v-for="t in things" :thing="t" :key="t.id"/>
</table>

The catch is that each thing is represented by two <TR>...</TR> entries. (I'm porting someone else's code; the table data in the first row spans to the second, etc., so for now I'd like to keep what they have.)

The obvious solution doesn't work, because VueJS needs to emit only one root element into the DOM.

MyMultiRowEntry.vue (not valid code, but shown for illustration)

<template>
  <tr><td rowspan="2">{{ thing.foo }}</td><td>...</td><td>{{ thing.bar }}</td></tr>
  <tr><td>{{ thing.xyzzy }}</td></tr>
</template>

<script>
  export default {
    props: {
      thing: {
         type: Object,
         required: true
      }
    }
  };
</script>

Paths I've explored already:

  • Vue does not have fragments (that I'm aware of), like <React.Fragment>, so I can't make a logical wrapper.

  • HTML itself does not like a <div> wrapping table roles.

  • The actual template content is more complex than this simple example, so it's not static content ...there's other Vue binding and such going on, which prohibits other trickery.

  • The only other similar answer was taking a different approach and bumped into other problems.

What's the best way to accomplish the above's intent?

3
  • 1
    The proper element to group rows is <tbody>. In fact, it is required. As in, if you don't provide one, the browser automatically adds one for you. But it's really meant as a grouping mechanism for <tr>s and the implementation goes to reasons such as pagination when printing tables and so on. So that's what you should use, since a vue element requires the template to have a single child (at render). Commented Feb 3, 2019 at 23:10
  • 1
    Do note that you can't have both <tr>s and <tbody> elements as immediate children of the same <table>. <tr>s are valid <table> children only if no <tbody> is present (because, as I pointed above, all <tr>s are wrapped into one <tbody> automatically. But if you have one or more <tbody>s, <tr>s are no longer valid children of <table>. Docs here. Commented Feb 3, 2019 at 23:19
  • @AndreiGheorghiu -- thank you -- that solved the problem and explained what was going on. Elegant solution. Commented Feb 4, 2019 at 0:30

1 Answer 1

7

In this particular example what I would do is just simply wrap multiple tr's into tbody container, as follow:

MyMultiRowEntry.vue

<template>
  <tbody>
      <tr><td rowspan="2">{{ thing.foo }}</td><td>...</td><td>{{ thing.bar }}</td></tr>
      <tr><td>{{ thing.xyzzy }}</td></tr>
  </tbody>
</template>
Sign up to request clarification or add additional context in comments.

1 Comment

Worked perfectly! Thank you!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.