Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue: Displaying nested data in a table

I'm in the process of rewriting some older code, and using Vue as the replacement. It's all going great apart from changing one table that is templated using handlebars.

Using handlebars nested {{each}} I can work down through the nested data structure while displaying the relevant data in table rows: e.g. using handlebars: https://jsfiddle.net/6dsruo40/1/

I cant figure out how to do the same using Vue with v-for etc.

Fiddle with as mush as I have: https://jsfiddle.net/cj7go6bv/

I don't know how to work through the data structure while maintaining the <tr>s like in handlebars

This is the data structure I'm using, but it is flexible:

var data = [
  {
key: "Region 1",
values: [
  {
    key: "Sub region 1",
    values: [
      {
        site: "Site A",
        timestamp: 1507246300935,
        total: 3,
      },
      {
        site: "Site B",
        timestamp: 1507246300818,
        total: 0,
      },
      {
        site: "Site C",
        timestamp: 1507246300936,
        total: 0,
      }
    ],
  },
  {
    key: "Sub region 2",
    values: [
      {
        site: "Site A",
        timestamp: 1507246301442,
        total: 20,
      },
      {
        site: "Site B",
        timestamp: 1507246301788,
        total: 5,
      }
    ]
   },
  {
    key: "Sub region 3",
    values: [
      {
        site: "Site A",
        timestamp: 1507246302503,
        total: 66,
      },
      {
        site: "Site B",
        timestamp: 1507246302783,
        total: 2
      }
    ]
  }
]
   },
   {
key: "Region 2",
values: [
  {
    key: "Sub region 1",
    values: [
      {
        site: "Site A",
        timestamp: 1507246306789,
        total: 0,
      },
      {
        site: "Site B",
        timestamp: 1507246307439,
        total: 6,
      }
    ]
  },
  {
    key: "Sub region 2",
    values: [
      {
        site: "Site A",
        timestamp: 1507246308269,
        total: 10,
      },
      {
        site: "Site B",
        timestamp: 1507246308683,
        total: 30,
      }
    ]
  }
]
}
];

The Vue code I have is very modest so far:

Vue.component('project-table', {
  template: '#table-template',
  props: {
    data: Array
  }
});

var app = new Vue({
    el: '#table-container',
    data: {data: sites},
    });

And the template:

<div id="table-container">
  <project-table :data="data"></project-table>
</div>
    <script id="table-template" type="text/x-template">
        <table class="u-full-width">
            <thead>
                <tr>
                <th>Project location</th>
                <th>Total</th>
                <th>Timestamp</th>
            </tr>
        </thead>
        <tbody>
        <tr class="name-row" v-for="item in data">
            <th class="name" colspan="3">{{item.key}}</th>
        </tr>
        <tbody>
    </table>
</script>

What is the mechanism in Vue for displaying a table like is done in Handlebars? Thanks!

like image 481
K Groll Avatar asked Oct 06 '17 03:10

K Groll


1 Answers

Here is the relevant part of the template updated.

<tbody>
  <template v-for="item in data">
    <tr class="name-row" >
      <th class="name" colspan="3">{{item.key}}</th>
    </tr>
    <template v-for="subregion in item.values">
      <tr>
        <th class="group-name" colspan="4">{{subregion.key}}</th>
      </tr>
      <tr v-for="site in subregion.values">
        <td>{{site.site}}</td>
        <td>{{site.total}}</td>
        <td>
          <span>{{site.timestamp}}</span>
        </td>  
      </tr>
    </template>
  </template>
<tbody>

And the updated fiddle.

The main point is taking advantage of the template element to render more than one tr per iteration.

like image 162
Bert Avatar answered Sep 20 '22 12:09

Bert