Having trouble getting help?
Contact Support
Contact Support
Immutable mode in Vue Treegrid component
11 Jun 202423 minutes to read
The immutable mode optimizes the TreeGrid re-rendering performance by using the object reference and deep compare
concept. When performing the TreeGrid 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">
<div id='container'>
<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 row at top</ejs-button>
<ejs-button cssClass="e-info" v-on:click="addBottomEvent">Add row 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 Task ID</ejs-button>
<ejs-button cssClass="e-info" v-on:click="pageEvent">Paging</ejs-button>
</div>
</td>
</tr>
<tr>
<td>
<span><b>Immutable TreeGrid</b></span>
<ejs-treegrid ref="immutablegrid" :dataSource='data' childMapping='subtasks' :treeColumnIndex='1' height=350 :allowPaging='true' :pageSettings='pageSettings' :editSettings='editSettings' :selectionSettings='selectionOptions' :enableImmutableMode='true' :beforeDataBound="immutableBeforeDataBound" :dataBound="immutableDataBound">
<e-columns>
<e-column field='taskID' :isPrimaryKey='true' headerText='Task ID' width='90' textAlign='Right'></e-column>
<e-column field='taskName' headerText='Task Name' width='200'></e-column>
<e-column field='startDate' headerText='Start Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='endDate' headerText='End Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='duration' headerText='Duration' width='90' textAlign='Right'></e-column>
<e-column field='priority' headerText='Priority' width='90' textAlign='Right'></e-column>
<e-column field='approved' headerText='Approved' width='90' textAlign='Right'></e-column>
</e-columns>
</ejs-treegrid>
</td>
<td>
<span><b>Normal TreeGrid</b></span>
<ejs-treegrid ref="nomalgrid" :dataSource='data' childMapping='subtasks' :treeColumnIndex='1' height=350 :allowPaging='true' :pageSettings='pageSettings' :editSettings='editSettings' :selectionSettings='selectionOptions' :enableImmutableMode='true' :beforeDataBound="beforeDataBound" :dataBound="dataBound">
<e-columns>
<e-column field='taskID' :isPrimaryKey='true' headerText='Task ID' width='90' textAlign='Right'></e-column>
<e-column field='taskName' headerText='Task Name' width='200'></e-column>
<e-column field='startDate' headerText='Start Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='endDate' headerText='End Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='duration' headerText='Duration' width='90' textAlign='Right'></e-column>
<e-column field='priority' headerText='Priority' width='90' textAlign='Right'></e-column>
<e-column field='approved' headerText='Approved' width='90' textAlign='Right'></e-column>
</e-columns>
</ejs-treegrid>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script setup>
import { provide, ref } from "vue";
import { TreeGridComponent as EjsTreegrid, Page, Edit, ColumnDirective as EColumn,
ColumnsDirective as EColumns
} from "@syncfusion/ej2-vue-treegrid";
import { sampleData, sampleData2, dataSource1 } from "./datasource.js";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
if(sampleData2.length == 0){
dataSource1();
}
const normalgrid = ref(null);
const immutablegrid = ref(null);
const data = sampleData2;
const pageSettings = { pageSize: 50 };
const selectionOptions = { type: 'Multiple' };
const editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' };
let immutableStart = 0;
let normalStart = 0;
let immutableInit = true;
let init = true;
const addTopEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = normalgrid.value;
immutableInstance.addRecord(sampleData[0], 0, "Top");
instance.addRecord(sampleData[0], 0, "Top");
};
const addBottomEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = normalgrid.value;
immutableInstance.addRecord(sampleData[0], 0, "Bottom");
instance.addRecord(sampleData[0], 0, "Bottom");
};
const deleteEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = normalgrid.value;
immutableInstance.selectRows([0, 2, 4]);
instance.selectRows([0, 2, 4]);
immutableInstance.deleteRecord();
instance.deleteRecord();
};
const sortEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = normalgrid.value;
let aData = immutableInstance.dataSource.reverse();
immutableInstance.setProperties({ dataSource: aData });
instance.setProperties({ dataSource: aData });
};
const pageEvent = function () {
let immutableInstance = immutablegrid.value;
let instance = normalgrid.value;
let page = instance.ej2Instances.pageSettings.currentPage + 1;
immutableInstance.goToPage(page);
instance.goToPage(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;
};
provide('treegrid', [Page, Edit]);
</script>
<style>
.e-treegrid {
pointer-events: none;
}
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
<template>
<div id="app">
<div id='container'>
<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 row at top</ejs-button>
<ejs-button cssClass="e-info" v-on:click="addBottomEvent">Add row 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 Task ID</ejs-button>
<ejs-button cssClass="e-info" v-on:click="pageEvent">Paging</ejs-button>
</div>
</td>
</tr>
<tr>
<td>
<span><b>Immutable TreeGrid</b></span>
<ejs-treegrid ref="immutablegrid" :dataSource='data' childMapping='subtasks' :treeColumnIndex='1' height=350 :allowPaging='true' :pageSettings='pageSettings' :editSettings='editSettings' :selectionSettings='selectionOptions' :enableImmutableMode='true' :beforeDataBound="immutableBeforeDataBound" :dataBound="immutableDataBound">
<e-columns>
<e-column field='taskID' :isPrimaryKey='true' headerText='Task ID' width='90' textAlign='Right'></e-column>
<e-column field='taskName' headerText='Task Name' width='200'></e-column>
<e-column field='startDate' headerText='Start Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='endDate' headerText='End Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='duration' headerText='Duration' width='90' textAlign='Right'></e-column>
<e-column field='priority' headerText='Priority' width='90' textAlign='Right'></e-column>
<e-column field='approved' headerText='Approved' width='90' textAlign='Right'></e-column>
</e-columns>
</ejs-treegrid>
</td>
<td>
<span><b>Normal TreeGrid</b></span>
<ejs-treegrid ref="nomalgrid" :dataSource='data' childMapping='subtasks' :treeColumnIndex='1' height=350 :allowPaging='true' :pageSettings='pageSettings' :editSettings='editSettings' :selectionSettings='selectionOptions' :enableImmutableMode='true' :beforeDataBound="beforeDataBound" :dataBound="dataBound">
<e-columns>
<e-column field='taskID' :isPrimaryKey='true' headerText='Task ID' width='90' textAlign='Right'></e-column>
<e-column field='taskName' headerText='Task Name' width='200'></e-column>
<e-column field='startDate' headerText='Start Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='endDate' headerText='End Date' textAlign='Right' width='90' format='yMd' type='date'></e-column>
<e-column field='duration' headerText='Duration' width='90' textAlign='Right'></e-column>
<e-column field='priority' headerText='Priority' width='90' textAlign='Right'></e-column>
<e-column field='approved' headerText='Approved' width='90' textAlign='Right'></e-column>
</e-columns>
</ejs-treegrid>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import { TreeGridComponent, Page, Edit, ColumnDirective, ColumnsDirective } from "@syncfusion/ej2-vue-treegrid";
import { sampleData, sampleData2, dataSource1 } from "./datasource.js";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
if(sampleData2.length == 0){
dataSource1();
}
export default {
name: "App",
components: {
"ejs-button":ButtonComponent,
"ejs-treegrid":TreeGridComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
},
data() {
return {
data: sampleData2,
pageSettings: { pageSize: 50 },
selectionOptions: { type: 'Multiple' },
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
immutableStart: 0,
normalStart: 0,
immutableInit: true,
init: true
};
},
provide: {
treegrid: [Page, Edit],
},
methods: {
addTopEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
immutableInstance.addRecord(sampleData[0], 0, "Top");
instance.addRecord(sampleData[0], 0, "Top");
},
addBottomEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
immutableInstance.addRecord(sampleData[0], 0, "Bottom");
instance.addRecord(sampleData[0], 0, "Bottom");
},
deleteEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
immutableInstance.selectRows([0, 2, 4]);
instance.selectRows([0, 2, 4]);
immutableInstance.deleteRecord();
instance.deleteRecord();
},
sortEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let aData = immutableInstance.dataSource.reverse();
immutableInstance.setProperties({ dataSource: aData });
instance.setProperties({ dataSource: aData });
},
pageEvent: function () {
let immutableInstance = this.$refs.immutablegrid;
let instance = this.$refs.nomalgrid;
let page = instance.ej2Instances.pageSettings.currentPage + 1;
immutableInstance.goToPage(page);
instance.goToPage(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-treegrid {
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
- Column reorder
- Virtualization