Menu Close

Useful Vue Data Grid Components

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at some data grid components that we can use to build data grids.

vue-handsontable-official

This is a Vue data grid that looks and feels like a spreadsheet. It’s the official Vue wrapper for Handsontable.

We can run:

npm install handsontable @handsontable/vue

to install it. Then we can use it as follows:

<template>
  <div id="app">
    <hot-table
      licenseKey="non-commercial-and-evaluation"
      :data="data"
      :colHeaders="true"
      :rowHeaders="true"
      width="600"
      height="300"
    ></hot-table>
  </div>
</template>
<script>
import { HotTable } from "@handsontable/vue";
export default {
  data() {
    return {
      data: [
        ["", "Mazda", "Honda", "Toyota", "Volvo"],
        ["2019", 10, 11, 12, 13],
        ["2020", 20, 11, 14, 13],
        ["2021", 30, 15, 12, 13]
      ]
    };
  },
  components: {
    HotTable
  }
};
</script>
<style lang="scss">
@import "~handsontable/dist/handsontable.full.css";
</style>

In the code above, we registered the HotTable component in our component. Then we have the data model, which we pass int the data prop of the hot-table component.

Also, we set colHeaders and rowHeaders to true so that we see the column and row headings. This should result in a data grid that looks like a spreadsheet, with letters as column headers and numbers as row headers.

Like a spreadsheet, we can also add context menus for the cells by adding the contextMenu object as follows:

<template>
  <div id="app">
    <hot-table
      licenseKey="non-commercial-and-evaluation"
      :data="data"
      :colHeaders="true"
      :rowHeaders="true"
      width="600"
      height="300"
      :contextMenu="contextMenu"
    ></hot-table>
  </div>
</template>
<script>
import { HotTable } from "@handsontable/vue";
import Handsontable from "handsontable";
export default {
  data() {
    return {
      data: [
        ["", "Tesla", "Mercedes", "Toyota", "Volvo"],
        ["2019", 10, 11, 12, 13],
        ["2020", 20, 11, 14, 13],
        ["2021", 30, 15, 12, 13]
      ],
      contextMenu: {
        items: {
          row_above: {
            name: "Insert row above this one"
          },
          row_below: {},
          separator: Handsontable.plugins.ContextMenu.SEPARATOR,
          clear_custom: {
            name: "Clear all cells",
            callback() {
              this.clear();
            }
          }
        }
      }
    };
  },
  components: {
    HotTable
  }
};
</script>
<style lang="scss">
@import "~handsontable/dist/handsontable.full.css";
</style>

We added the contextMenu object, which has the row_above property for adding a context menu entry for inserting a new row above the current one. Then we added the row_below property to add an Insert row below menu item, but set the value to an empty object so that we keep the default settings.

Then we added a clear_custom property to add an entry to clear all cells.

There’re many more options, including customizing the editor, changing how cells are rendered, integration with Vuex and more.

The full list of options are at https://handsontable.com/docs/7.4.0/tutorial-introduction.html.

It’s free for non-commercial and evaluation purpose, but it’s a paid library for commercial purposes.

vue-sorted-table

vue-sorted-table is another table component that automatically generates a table from data. It makes adding the column sorting feature easy. To install it, we run:

npm install --save vue-sorted-table

Then to use it, we write the following code:

main.js :

import Vue from "vue";
import App from "./App.vue";
import SortedTablePlugin from "vue-sorted-table";
Vue.use(SortedTablePlugin);
Vue.config.productionTip = false;
new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue :

<template>
  <div id="app">
    <sorted-table :values="values">
      <thead>
        <tr>
          <th scope="col" style="text-align: left; width: 10rem;">
            <sort-link name="id">ID</sort-link>
          </th>
          <th scope="col" style="text-align: left; width: 10rem;">
            <sort-link name="name">Name</sort-link>
          </th>
          <th scope="col" style="text-align: left; width: 10rem;">
            <sort-link name="hits">Age</sort-link>
          </th>
        </tr>
      </thead>
      <tbody slot="body" slot-scope="sort">
        <tr v-for="value in sort.values" :key="value.id">
          <td>{{ value.id }}</td>
          <td>{{ value.name }}</td>
          <td>{{ value.age }}</td>
        </tr>
      </tbody>
    </sorted-table>
  </div>
</template>
<script>
export default {
  name: "App",
  data: function() {
    return {
      values: [
        { name: "James", id: 2, age: 33 },
        { name: "Mary", id: 1, age: 42 },
        { name: "Alex", id: 3, age: 79 }
      ]
    };
  }
};
</script>

In the code above, we have the values array, which is used as the data for our sorted-table component. Then we add the table rows by using the regular HTML tr element.

In the table header, we add the sort-link component to each th element to let us sort each column individually.

We can also add icons for the up and down arrows used for the sort-link by passing in a second argument info Vue.use as follows:

Vue.use(SortedTablePlugin, {
  ascIcon: '<i class="material-icons">arrow_drop_up</i>',
  descIcon: '<i class="material-icons">arrow_drop_down</i>'
});

Also, the objects containing the values have to be a flat object. Other optional available include values , dir , sort , ascIcon , descIcon ,onSort . values is an array of objects containing the table values. dir is the sort direction, sort is the default sorting column, ascIcon and descIcon are the icons for the sort arrows, and onSort is a callback for custom sorting.

Conclusion

We can add tables easily with Vue Handsontable and vue-sorted-table . Vue Handsontable is more full-featured and works like a spreadsheet with its ability to edit cells and add/remove columns. vue-sorted-table is simpler. Its only purpose is to provide sorting on table columns.

Posted in vue