Implementing the VueJS Datagrid

If you are building an VueJS application then you have the choice between A) using the plain JavaScript version of ag-Grid or B) using the ag-Grid VueJS Component from the ag-grid-vue project. If you use the ag-Grid VueJS Component, then the grid's properties, events and API will all tie in with the VueJS ecosystem. This will make your VueJS coding easier.

Please use the github project ag-grid-vue for feedback or issue reporting around ag-Grid's support for VueJS.

ag-Grid VueJS Features

Every feature of ag-Grid is available when using the ag-Grid VueJS Component. The VueJS Component wraps the functionality of ag-Grid, it doesn't duplicate, so there will be no difference between core ag-Grid and VueJS ag-Grid when it comes to features.

VueJS Full Example

This page goes through the ag-grid-vue-example on Github.

The example project includes a number of separate grids on a page, with each section demonstrating a different feature set:

  • A feature rich grid example, demonstrating many of ag-Grid's features using VueJS as a wrapper Vue
  • A Simple Example, using CellRenderers created from VueJS Components Vue
  • A Richer Example, using CellRenderers created from VueJS Components, with child components, and two-way binding (parent to child components events) Vue
  • A Cell Editor example - one with a popup editor, and another with a numeric editor. Each demonstrates different editor related features Vue
  • A Floating Row Renderer Example Vue
  • A Full Width Renderer Example Vue
  • A Group Row Inner Renderer Example Vue
  • A Filter Example, with the filter written as a VueJS Component Vue
  • A Master/Detail Example, with both the Master and the Detail elements being VueJS Components

Dependencies

In your package.json file, specify dependency on ag-grid AND ag-grid-vue. The ag-grid package contains the core ag-grid engine and the ag-grid-vue contains the VueJS component.

"dependencies": {
    ...
    "ag-grid": "8.0.x",
    "ag-grid-vue": "8.0.x"

    // only needed if you're using enterprise features
    "ag-grid-enterprise": "8.0.x",
}
The major and minor versions should match. Every time a new major or minor version of ag-Grid is released, the component will also be released. However for patch versions, the component will not be released.

You will then be able to access ag-Grid inside your application:

import {AgGridVue} from 'ag-grid-vue';

Which you can then use as a component within your application:

export default {
    data () {
        return {
            gridOptions: null,
            ..other data
        }
    },
    components: {
        'ag-grid-vue': AgGridVue,
        ..other components
    },
    ... the rest of your application component
}

You will need to include the CSS for ag-Grid, either directly inside your html page, or as part of creating your bundle if bundling. The following shows referencing the css from your web page:

<link href="node_modules/ag-grid/dist/styles/ag-grid.css" rel="stylesheet" />
<link href="node_modules/ag-grid/dist/styles/theme-fresh.css" rel="stylesheet" />

If you're using the style-loader you can also import the CSS dependencies into your final bundle:

import "../node_modules/ag-grid/dist/styles/ag-grid.css"
import "../node_modules/ag-grid/dist/styles/theme-fresh.css"

// only needed if you're using enterprise features
import "ag-grid-enterprise/main";

Importing of the CSS should be done before you use the ag-Grid Vue Component.

Configuring ag-Grid in VueJS

You can configure the grid in the following ways through VueJS:

  • Events: All data out of the grid comes through events. These use VueJS event bindings eg :modelUpdated="onModelUpdated". As you interact with the grid, the different events are fixed and output text to the console (open the dev tools to see the console).
  • Properties: All the data is provided to the grid as VueJS bindings. These are bound onto the ag-Grid properties bypassing the elements attributes. The values for the bindings come from the parent controller.
  • Attributes: When the property is just a simple string value, then no binding is necessary, just the value is placed as an attribute eg rowHeight="22".If the attribute is a boolean and a value is not provided, it is taken as false.
  • Changing Properties: When a property changes value, VueJS automatically passes the new value onto the grid. This is used in the following locations in the "feature rich grid example' above:
    a) The 'quickFilter' on the top right updates the quick filter of the grid. b) The 'Show Tool Panel' checkbox has it's value bound to the 'showToolPanel' property of the grid. c) The 'Refresh Data' generates new data for the grid and updates the rowData property.

Notice that the grid has it's properties marked as immutable. Hence for object properties, the object reference must change for the grid to take impact. For example, rowData must be a new list of data for the grid to be informed to redraw.

Defining VueJS Components for use in ag-Grid

VueJS components can be provided to ag-Grid in the following ways (the section after documents how to then reference these components in your column definitions):

Simple, Inline Components

components: {
    'CubeComponent': {
        template: '{{ valueCubed() }}',
        methods: {
            valueCubed() {
                return this.params.value * this.params.value * this.params.value;
            }
        }
    },
    ParamsComponent: {
        template: 'Field: {{params.colDef.field}}, Value: {{params.value}}',
        methods: {
            valueCubed() {
                return this.params.value * this.params.value * this.params.value;
            }
        }
    }
}

Note here that we can define the property name either quoted or not - but note that in order to reference these components in your column definitions you'll need to provide them as case-sensitive strings (see referencing components below).

Simple, Locally Declared Components

let SquareComponent = Vue.extend({
    template: '{{ valueSquared() }}',
    methods: {
        valueSquared() {
            return this.params.value * this.params.value;
        }
    }
});

External .js Components

// SquareComponent.js
export default Vue.extend({
    template: '{{ valueSquared() }}',
    methods: {
        valueSquared() {
            return this.params.value * this.params.value;
        }
    }
});
    
// MyGridApp.vue (your Component holding the ag-Grid component)
import SquareComponent from './SquareComponent'

More Complex, External Single File Components (.vue)

<template>
    <span class="currency">{{ params.value | currency('EUR') }}</span>
</template>

<script>
    import Vue from "vue";

    export default Vue.extend({
        filters: {
            currency(value, symbol) {
                let result = value;
                if (!isNaN(value)) {
                    result = value.toFixed(2);
                }
                return symbol ? symbol + result : result;
            }
        }
    });
</script>

<style scoped>
    .currency {
        color: blue;
    }
</style>

You can then use these components as editors, renderers or filters. Which method you choose depends on preference as well as the complexity of your component - for simple components inline is easiest, for more complex ones external .vue components will be more manageable.

Additionally, if you define your components as Single File Components (.vue) then you'll be able to leverage scoped CSS, which won't otherwise be possible.

Providing VueJS Components to ag-Grid

Having defined your component, you can then reference them in your column definitions.

For inline components (ie defined in the components property) you can reference components by either case-sensitive property name, for example:

// defined as a quoted string above: 'CubeComponent'
{
    headerName: "Cube",
    field: "value",
    cellRendererFramework: 'CubeComponent',
    colId: "cube",
    width: 125
},
// defined as a value above: ParamsComponent
{
    headerName: "Row Params",
    field: "row",
    cellRendererFramework: 'ParamsComponent',
    colId: "params",
    width: 245
},

In both cases we need to define the component to be used in the cell as a case-senstive string.

For components defined outside of the application component you can pass them by reference. For example:

// import or create our component outside of our app
import CurrencyComponent from './CurrencyComponent.vue'
let SquareComponent = Vue.extend({...rest of the component

// reference the component by reference
this.columnDefs = [
    {headerName: "Row", field: "row", width: 140},
    {
        headerName: "Square",
        field: "value",
        cellRendererFramework: SquareComponent,
        editable: true,
        colId: "square",
        width: 125
    },
    {
        headerName: "Currency (Filter)",
        field: "currency",
        cellRendererFramework: CurrencyComponent,
        colId: "params",
        width: 150
    }

Please see the relevant sections on cellRenderers, cellEditors and filters for configuring and using VueJS Components in ag-Grid.

The rich-grid example has ag-Grid configured through the template in the following ways:

<ag-grid-vue style="width: 100%; height: 350px;" class="ag-fresh"
    // these are attributes, not bound, give explicit values here
    rowHeight="22"
    rowSelection="multiple"

    // these are boolean values
    // (leaving them out will default them to false)
    :enableColResize="true"
    :enableSorting="true"

    // these are bound properties
    :gridOptions="gridOptions"
    :columnDefs="columnDefs"

    // this is a callback
    :isScrollLag="myIsScrollLagFunction"

    // these are registering event callbacks
    :modelUpdated="onModelUpdated"
    :cellClicked="onCellClicked"
</ag-grid-vue>

The above is all you need to get started using ag-Grid in a VueJS application. Now would be a good time to try it in a simple app and get some data displaying and practice with some of the grid settings before moving onto the advanced features of cellRendering and custom filtering.

Child to Parent Communication

There are a variety of ways to manage component communication in Angular (shared service, local variables etc), but you often need a simple way to let a "parent" component know that something has happened on a "child" component. In this case the simplest route is to use the gridOptions.context to hold a reference to the parent, which the child can then access.

// in the parent component - the component that hosts ag-grid-angular and specifies which angular components to use in the grid
beforeMount() {
    this.gridOptions = {
        context: {
            componentParent: this
        }
    };
    this.createRowData();
    this.createColumnDefs();
},

// in the child component - the Vue components created dynamically in the grid
// the parent component can then be accessed as follows:
this.params.context.componentParent

Note that although we've used componentParent as the property name here it can be anything - the main point is that you can use the context mechanism to share information between the components.

The "A Simple Example, using CellRenderers created from VueJS Components" above illustrates this in the Child/Parent column:

Building & Bundling

There are many ways to build and/or bundle an VueJS Application. We provide fully working examples using a simplified Webpack build as part of the ag-grid-vue-example on GitHub.

ag-Grid VueJS Examples

Example: Rich Grid without Components

The example below shows a rich configuration of ag-Grid, with no VueJS Components.

Cell Rendering & Cell Editing using VueJS

It is possible to build cellRenderers, cellEditors and filters using VueJS. Doing each of these is explained in the section on each.

Although it is possible to use VueJS for your customisations of ag-Grid, it is not necessary. The grid will happily work with both VueJS and non-VueJS portions (eg cellRenderers in VueJS or normal JavaScript). If you do use VueJS, be aware that you are adding an extra layer of indirection into ag-Grid. ag-Grid's internal framework is already highly tuned to work incredibly fast and does not require VueJS or anything else to make it faster. If you are looking for a lightning fast grid, even if you are using VueJS and the ag-grid-vue component, consider using plain ag-Grid Components (as explained on the pages for rendering etc) inside ag-Grid instead of creating VueJS counterparts.

Next Steps...

Now you can go to interfacing to learn about accessing all the features of the grid.