Vuex in Vue 3
Use the Vuex state management pattern to maintain the data and configuration options of your Vue 3 data grid.
Example - Vuex store dump
The following example implements the @handsontable/vue3 component with a readOnly toggle switch and the Vuex state manager.
Find out which Vue 3 versions are supported
Vuex store dump:
import { createStore } from 'vuex';import { defineComponent } from 'vue';import { HotTable } from '@handsontable/vue3';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const store = createStore({ state() { return { hotData: null, hotSettings: { readOnly: false, autoWrapRow: true, autoWrapCol: true, } }; }, mutations: { updateData(state, hotData) { state.hotData = hotData; }, updateSettings(state, updateObj) { state.hotSettings[updateObj.prop] = updateObj.value; } }});
const ExampleComponent = defineComponent({ data() { return { hotSettings: { data: [ ['A1', 'B1', 'C1', 'D1'], ['A2', 'B2', 'C2', 'D2'], ['A3', 'B3', 'C3', 'D3'], ['A4', 'B4', 'C4', 'D4'], ], colHeaders: true, rowHeaders: true, readOnly: true, height: 'auto', autoWrapRow: true, autoWrapCol: true, afterChange: () => { if (this.hotRef) { store.commit('updateData', this.hotRef.getSourceData()); } }, licenseKey: 'non-commercial-and-evaluation' }, hotRef: null }; }, mounted() { this.hotRef = this.$refs.wrapper.hotInstance; store.subscribe(() => this.updateVuexPreview()); store.commit('updateData', this.hotRef.getSourceData()); }, methods: { toggleReadOnly(event) { this.hotSettings.readOnly = event.target.checked; store.commit('updateSettings', { prop: 'readOnly', value: this.hotSettings.readOnly }); }, updateVuexPreview() { // This method serves only as a renderer for the Vuex's state dump. const previewTable = document.querySelector('#vuex-preview pre'); let newInnerHtml = '<div>';
for (const [key, value] of Object.entries(store.state)) { newInnerHtml += '<div><div class="table-container">';
if (key === 'hotData' && Array.isArray(value)) { newInnerHtml += '<strong>hotData:</strong> <br><table><tbody>';
for (const row of value) { newInnerHtml += '<tr>';
for (const cell of row) { newInnerHtml += `<td>${cell}</td>`; }
newInnerHtml += '</tr>'; } newInnerHtml += '</tbody></table>';
} else if (key === 'hotSettings') { newInnerHtml += '<strong>hotSettings:</strong> <ul>';
for (const settingsKey of Object.keys(value)) { newInnerHtml += `<li>${settingsKey}: ${store.state.hotSettings[settingsKey]}</li>`; }
newInnerHtml += '</ul>'; }
newInnerHtml += '</div></div>'; } newInnerHtml += '</div>';
previewTable.innerHTML = newInnerHtml; } }, components: { HotTable, }});
export default ExampleComponent;<div id="example1"> <div class="example-controls-container"> <div class="controls"> <label><input v-on:click="toggleReadOnly" checked id="readOnlyCheck" type="checkbox" /> Toggle <code>readOnly</code> for the entire table</label> </div> </div> <hot-table ref="wrapper" :settings="hotSettings"></hot-table> <div id="vuex-preview"> <strong>Vuex store dump:</strong> <pre></pre> </div></div>#vuex-preview { margin-top: 0.75rem;}
#vuex-preview strong { display: block; margin-bottom: 0.375rem; color: var(--sl-color-gray-2); font-family: var(--sl-font); font-size: var(--sl-text-xs);}
#vuex-preview pre { height: 168px; padding: 0.5rem 0.75rem; overflow-y: auto; font-size: var(--sl-text-xs); font-family: var(--sl-font-mono); line-height: 1.6; border: 1px solid var(--sl-color-gray-5); background: var(--sl-color-gray-7); color: var(--sl-color-gray-2); margin: 0; border-radius: 0;}
#vuex-preview pre .table-container { margin-bottom: 0.375rem;}
#vuex-preview pre table { border-collapse: collapse; margin: 0.25rem 0; font-size: var(--sl-text-xs);}
#vuex-preview pre td { padding: 0.125rem 0.5rem 0.125rem 0; color: var(--sl-color-gray-2); border: none;}
#vuex-preview pre ul { margin: 0.125rem 0 0; padding-left: 1.25rem; list-style: disc;}
#vuex-preview pre li { padding: 0.0625rem 0; color: var(--sl-color-gray-2);}