Immutable mode in Vue Grid component
11 Jun 202424 minutes to read
The immutable mode optimizes the Grid re-rendering performance by using the object reference and deep compare
concept. When performing the Grid actions, it will only re-render the modified or newly added rows and prevent the re-rendering of the unchanged rows.
To enable this feature, you have to set the enableImmutableMode
property as true.
This feature uses the primary key value for data comparison. So, you need to provide the
isPrimaryKey
column.
<template>
<div id="app">
<table>
<tbody>
<tr>
<td>
<span id="immutableDelete"></span>
</td>
</tr>
<tr>
<td>
<span id="normalDelete"></span>
</td>
</tr>
<tr>
<td>
<div>
<ejs-button cssClass="e-info" v-on:click="addTopEvent">Add 5 rows at top</ejs-button>
<ejs-button cssClass="e-info" v-on:click="addBottomEvent">Add 5 rows at bottom</ejs-button>
<ejs-button cssClass="e-info" v-on:click="deleteEvent">Delete 5 rows</ejs-button>
<ejs-button cssClass="e-info" v-on:click="sortEvent">Sort Order ID</ejs-button>
<ejs-button cssClass="e-info" v-on:click="pageEvent">Paging</ejs-button>
</div>
</td>
</tr>
<tr>
<td>
<span><b>Immutable Grid</b></span>
<ejs-grid ref="immutablegrid" :dataSource="data" height="250" :enableImmutableMode="true" :allowPaging="true"
:pageSettings="pageSettings" :beforeDataBound="immutableBeforeDataBound" :dataBound="immutableDataBound">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width="120" isPrimaryKey="true"
textAlign="Right"></e-column>
<e-column field="ProductName" headerText="Product Name" width="160"></e-column>
<e-column field="ProductID" headerText="Product ID" width="120" textAlign="Right"></e-column>
<e-column field="CustomerID" headerText="Customer ID" width="120"></e-column>
<e-column field="CustomerName" headerText="Customer Name" width="160"></e-column>
</e-columns>
</ejs-grid>
</td>
</tr>
<tr>
<td>
<span><b>Normal Grid</b></span>
<ejs-grid ref="nomalgrid" :dataSource="data" height="250" :allowPaging="true" :pageSettings="pageSettings"
:beforeDataBound="beforeDataBound" :dataBound="dataBound">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width="120" isPrimaryKey="true"
textAlign="Right"></e-column>
<e-column field="ProductName" headerText="Product Name" width="160"></e-column>
<e-column field="ProductID" headerText="Product ID" width="120" textAlign="Right"></e-column>
<e-column field="CustomerID" headerText="Customer ID" width="120"></e-column>
<e-column field="CustomerName" headerText="Customer Name" width="160"></e-column>
</e-columns>
</ejs-grid>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { provide, ref } from "vue";
import { GridComponent as EjsGrid, ColumnDirective as EColumn, ColumnsDirective as EColumns, Page } from "@syncfusion/ej2-vue-grids";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
import { data } from "./datasource.js";
const immutablegrid = ref(null);
const nomalgrid = ref(null);
const pageSettings = { pageSize: 50 };
const immutableStart = 0;
const normalStart = 0;
const primaryKey = 0;
const immutableInit = true;
const init = true;
provide('grid', [Page]);
const addTopEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = nomalgrid.value;
let addedRecords = [
{
OrderID: ++primaryKey,
ProductName: "Chai",
ProductID: "Sasquatch Ale",
CustomerID: "QUEDE",
CustomerName: "Yoshi Tannamuri",
},
{
OrderID: ++primaryKey,
ProductName: "Georg Pipps",
ProductID: "Valkoinen suklaa",
CustomerID: "RATTC",
CustomerName: "Martín Sommer",
},
{
OrderID: ++primaryKey,
ProductName: "Yoshi Tannamuri",
ProductID: "Gula Malacca",
CustomerID: "COMMI",
CustomerName: "Ann Devon",
},
{
OrderID: ++primaryKey,
ProductName: "Palle Ibsen",
ProductID: "Rogede sild",
CustomerID: "RATTC",
CustomerName: "Paula Wilson",
},
{
OrderID: ++primaryKey,
ProductName: "Francisco Chang",
ProductID: "Mascarpone Fabioli",
CustomerID: "ROMEY",
CustomerName: "Jose Pavarotti",
},
];
let aData = addedRecords.concat(immutableInstance.dataSource);
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
}
const addBottomEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = nomalgrid.value;
let addedRecords = [
{
OrderID: ++primaryKey,
ProductName: "Chai",
ProductID: "Sasquatch Ale",
CustomerID: "QUEDE",
CustomerName: "Yoshi Tannamuri",
},
{
OrderID: ++primaryKey,
ProductName: "Georg Pipps",
ProductID: "Valkoinen suklaa",
CustomerID: "RATTC",
CustomerName: "Martín Sommer",
},
{
OrderID: ++primaryKey,
ProductName: "Yoshi Tannamuri",
ProductID: "Gula Malacca",
CustomerID: "COMMI",
CustomerName: "Ann Devon",
},
{
OrderID: ++primaryKey,
ProductName: "Palle Ibsen",
ProductID: "Rogede sild",
CustomerID: "RATTC",
CustomerName: "Paula Wilson",
},
{
OrderID: ++primaryKey,
ProductName: "Francisco Chang",
ProductID: "Mascarpone Fabioli",
CustomerID: "ROMEY",
CustomerName: "Jose Pavarotti",
},
];
let aData = immutableInstance.dataSource.concat(addedRecords);
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
}
const deleteEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = nomalgrid.value;
immutableInstance.dataSource.splice(0, 5);
instance.setProperties({ dataSource: immutableInstance.dataSource });
immutableInstance.setProperties({
dataSource: immutableInstance.dataSource,
});
}
const sortEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = nomalgrid.value;
let aData = immutableInstance.dataSource.reverse();
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
}
const pageEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = nomalgrid.value;
let totalPage =
immutableInstance.dataSource.length /
immutableInstance.pageSettings.pageSize;
let page = Math.floor(Math.random() * totalPage) + 1;
instance.setProperties({ pageSettings: { currentPage: page } });
immutableInstance.setProperties({ pageSettings: { currentPage: page } });
}
const immutableBeforeDataBound = function () {
immutableStart = new Date().getTime();
}
const immutableDataBound = function () {
let val = immutableInit ? '' : new Date().getTime() - immutableStart;
document.getElementById("immutableDelete").innerHTML =
"Immutable rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
immutableStart = 0; immutableInit = false;
}
const beforeDataBound = function () {
normalStart = new Date().getTime();
}
const dataBound = function () {
let val = init ? '' : new Date().getTime() - normalStart;
document.getElementById("normalDelete").innerHTML =
"Normal rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
normalStart = 0; init = false;
}
</script>
<style>
.e-grid {
pointer-events: none;
}
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
<template>
<div id="app">
<table>
<tbody>
<tr>
<td>
<span id="immutableDelete"></span>
</td>
</tr>
<tr>
<td>
<span id="normalDelete"></span>
</td>
</tr>
<tr>
<td>
<div>
<ejs-button cssClass="e-info" v-on:click="addTopEvent"
>Add 5 rows at top</ejs-button
>
<ejs-button cssClass="e-info" v-on:click="addBottomEvent"
>Add 5 rows at bottom</ejs-button
>
<ejs-button cssClass="e-info" v-on:click="deleteEvent"
>Delete 5 rows</ejs-button
>
<ejs-button cssClass="e-info" v-on:click="sortEvent"
>Sort Order ID</ejs-button
>
<ejs-button cssClass="e-info" v-on:click="pageEvent"
>Paging</ejs-button
>
</div>
</td>
</tr>
<tr>
<td>
<span><b>Immutable Grid</b></span>
<ejs-grid
ref="immutablegrid"
:dataSource="data"
height="250"
:enableImmutableMode="true"
:allowPaging="true"
:pageSettings="pageSettings"
:beforeDataBound="immutableBeforeDataBound"
:dataBound="immutableDataBound"
>
<e-columns>
<e-column
field="OrderID"
headerText="Order ID"
width="120"
isPrimaryKey="true"
textAlign="Right"
></e-column>
<e-column
field="ProductName"
headerText="Product Name"
width="160"
></e-column>
<e-column
field="ProductID"
headerText="Product ID"
width="120"
textAlign="Right"
></e-column>
<e-column
field="CustomerID"
headerText="Customer ID"
width="120"
></e-column>
<e-column
field="CustomerName"
headerText="Customer Name"
width="160"
></e-column>
</e-columns>
</ejs-grid>
</td>
</tr>
<tr>
<td>
<span><b>Normal Grid</b></span>
<ejs-grid
ref="nomalgrid"
:dataSource="data"
height="250"
:allowPaging="true"
:pageSettings="pageSettings"
:beforeDataBound="beforeDataBound"
:dataBound="dataBound"
>
<e-columns>
<e-column
field="OrderID"
headerText="Order ID"
width="120"
isPrimaryKey="true"
textAlign="Right"
></e-column>
<e-column
field="ProductName"
headerText="Product Name"
width="160"
></e-column>
<e-column
field="ProductID"
headerText="Product ID"
width="120"
textAlign="Right"
></e-column>
<e-column
field="CustomerID"
headerText="Customer ID"
width="120"
></e-column>
<e-column
field="CustomerName"
headerText="Customer Name"
width="160"
></e-column>
</e-columns>
</ejs-grid>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import { GridComponent, ColumnsDirective, Page } from "@syncfusion/ej2-vue-grids";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
import { data } from "./datasource.js";
export default {
name: "App",
components: {
"ejs-button":ButtonComponent,
"ejs-button":ButtonComponent,
"ejs-grid":GridComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective
},
data() {
return {
data: data,
pageSettings: { pageSize: 50 },
immutableStart: 0,
normalStart: 0,
primaryKey: 0,
immutableInit: true,
init: true
};
},
provide: {
grid: [Page],
},
methods: {
addTopEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let addedRecords = [
{ OrderID: ++this.primaryKey,
ProductName: "Chai",
ProductID: "Sasquatch Ale",
CustomerID: "QUEDE",
CustomerName: "Yoshi Tannamuri",
},
{
OrderID: ++this.primaryKey,
ProductName: "Georg Pipps",
ProductID: "Valkoinen suklaa",
CustomerID: "RATTC",
CustomerName: "Martín Sommer",
},
{
OrderID: ++this.primaryKey,
ProductName: "Yoshi Tannamuri",
ProductID: "Gula Malacca",
CustomerID: "COMMI",
CustomerName: "Ann Devon",
},
{
OrderID: ++this.primaryKey,
ProductName: "Palle Ibsen",
ProductID: "Rogede sild",
CustomerID: "RATTC",
CustomerName: "Paula Wilson",
},
{
OrderID: ++this.primaryKey,
ProductName: "Francisco Chang",
ProductID: "Mascarpone Fabioli",
CustomerID: "ROMEY",
CustomerName: "Jose Pavarotti",
},
];
let aData = addedRecords.concat(immutableInstance.dataSource);
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
},
addBottomEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let addedRecords = [
{
OrderID: ++this.primaryKey,
ProductName: "Chai",
ProductID: "Sasquatch Ale",
CustomerID: "QUEDE",
CustomerName: "Yoshi Tannamuri",
},
{
OrderID: ++this.primaryKey,
ProductName: "Georg Pipps",
ProductID: "Valkoinen suklaa",
CustomerID: "RATTC",
CustomerName: "Martín Sommer",
},
{
OrderID: ++this.primaryKey,
ProductName: "Yoshi Tannamuri",
ProductID: "Gula Malacca",
CustomerID: "COMMI",
CustomerName: "Ann Devon",
},
{
OrderID: ++this.primaryKey,
ProductName: "Palle Ibsen",
ProductID: "Rogede sild",
CustomerID: "RATTC",
CustomerName: "Paula Wilson",
},
{
OrderID: ++this.primaryKey,
ProductName: "Francisco Chang",
ProductID: "Mascarpone Fabioli",
CustomerID: "ROMEY",
CustomerName: "Jose Pavarotti",
},
];
let aData = immutableInstance.dataSource.concat(addedRecords);
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
},
deleteEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
immutableInstance.dataSource.splice(0, 5);
instance.setProperties({ dataSource: immutableInstance.dataSource });
immutableInstance.setProperties({
dataSource: immutableInstance.dataSource,
});
},
sortEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let aData = immutableInstance.dataSource.reverse();
instance.setProperties({ dataSource: aData });
immutableInstance.setProperties({ dataSource: aData });
},
pageEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let totalPage =
immutableInstance.dataSource.length /
immutableInstance.pageSettings.pageSize;
let page = Math.floor(Math.random() * totalPage) + 1;
instance.setProperties({ pageSettings: { currentPage: page } });
immutableInstance.setProperties({ pageSettings: { currentPage: page } });
},
immutableBeforeDataBound: function () {
this.immutableStart = new Date().getTime();
},
immutableDataBound: function () {
let val = this.immutableInit ? '' : new Date().getTime() - this.immutableStart;
document.getElementById("immutableDelete").innerHTML =
"Immutable rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
this.immutableStart = 0; this.immutableInit = false;
},
beforeDataBound: function () {
this.normalStart = new Date().getTime();
},
dataBound: function () {
let val = this.init ? '' : new Date().getTime() - this.normalStart;
document.getElementById("normalDelete").innerHTML =
"Normal rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
this.normalStart = 0; this.init = false;
},
},
};
</script>
<style>
.e-grid {
pointer-events: none;
}
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
Limitations
The following features are not supported in the immutable mode:
- Frozen rows and columns
- Row Template
- Detail Template
- Hierarchy Grid
- Column reorder
- Virtual scroll
- Infinite scroll
- Grouping