Skip to content

HotColumn is a Vue 3 component that lets you define column settings declaratively as child components of HotTable.

Find out which Vue 3 versions are supported

Declare column settings

To declare column-specific settings, pass the settings as <HotColumn/> properties, either separately or wrapped as a settings property, exactly as you would for <HotTable/>.

Vue
<script setup lang="ts">
import { ref } from 'vue';
import { HotTable, HotColumn } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry';
import type { GridSettings } from 'handsontable/settings';
registerAllModules();
const hotSettings = ref<GridSettings>({
data: [
['A1', 'B1'],
['A2', 'B2'],
['A3', 'B3'],
['A4', 'B4'],
['A5', 'B5'],
['A6', 'B6'],
['A7', 'B7'],
['A8', 'B8'],
['A9', 'B9'],
['A10', 'B10'],
],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
const secondColumnSettings = ref<GridSettings>({
title: 'Second column header',
});
</script>
<template>
<div id="example1">
<HotTable :settings="hotSettings">
<HotColumn title="First column header" />
<HotColumn :settings="secondColumnSettings" read-only="true" />
</HotTable>
</div>
</template>

Array of objects

To work with an array of objects for the <HotColumn/> component, you need to provide precise information about the data structure for the columns. To do this, refer to the data for a column in properties as data.

Vue
<script setup lang="ts">
import { ref } from 'vue';
import { HotTable, HotColumn } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry';
import type { GridSettings } from 'handsontable/settings';
registerAllModules();
type ProductRow = {
id: number;
name: string;
payment: { price: number; currency: string };
};
const hotData = ref<ProductRow[]>([
{ id: 1, name: 'Table tennis racket', payment: { price: 13, currency: 'PLN' } },
{ id: 2, name: 'Outdoor game ball', payment: { price: 14, currency: 'USD' } },
{ id: 3, name: 'Mountain bike', payment: { price: 300, currency: 'USD' } }
]);
const secondColumnSettings = ref<GridSettings>({
title: 'Second column header'
});
const settings = ref<GridSettings>({
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation'
});
</script>
<template>
<div id="example2">
<HotTable :data="hotData" :settings="settings">
<HotColumn title="ID" data="id" />
<HotColumn :settings="secondColumnSettings" read-only="true" data="name" />
<HotColumn title="Price" data="payment.price" />
<HotColumn title="Currency" data="payment.currency" />
</HotTable>
</div>
</template>

Declare a custom editor as a component

You can declare a custom editor by creating a class that extends TextEditor and passing it to a <HotColumn/> via the editor prop. The editor’s input element uses a placeholder attribute to display a hint when the cell value is empty.

Vue
<script setup lang="ts">
import { ref } from 'vue';
import { HotTable, HotColumn } from '@handsontable/vue3';
import { TextEditor } from 'handsontable/editors/textEditor';
import { registerAllModules } from 'handsontable/registry';
import type { GridSettings } from 'handsontable/settings';
registerAllModules();
class CustomEditor extends TextEditor {
createElements() {
super.createElements();
this.TEXTAREA = document.createElement('input');
this.TEXTAREA.setAttribute('placeholder', 'Custom placeholder');
this.TEXTAREA.setAttribute('data-hot-input', true);
this.textareaStyle = this.TEXTAREA.style;
this.TEXTAREA_PARENT.innerText = '';
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
}
}
const customEditor = CustomEditor;
const hotData = ref<string[][]>([
['A1', 'B1'],
['A2', 'B2'],
['A3', 'B3'],
['A4', 'B4'],
['A5', 'B5'],
]);
const settings = ref<GridSettings>({
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
</script>
<template>
<div id="example3">
<HotTable :data="hotData" :settings="settings">
<HotColumn title="Column A" :editor="customEditor" />
<HotColumn title="Column B" :read-only="true" />
</HotTable>
</div>
</template>

Declare a custom renderer

You can declare a custom renderer by creating a function that matches the BaseRenderer signature and passing it to a <HotColumn/> via the renderer prop. The renderer receives the cell’s td element and the cell value, and must return the modified td.

Vue
<script setup lang="ts">
import { ref } from 'vue';
import { HotTable, HotColumn } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry';
import type { GridSettings } from 'handsontable/settings';
import type { BaseRenderer } from 'handsontable/renderers';
registerAllModules();
const scoreRenderer: BaseRenderer = (_instance, td, _row, _col, _prop, value) => {
const score = Number(value);
td.innerHTML = String(value ?? '');
td.style.color = score >= 80 ? '#2d7d46' : score < 50 ? '#c0392b' : '';
td.style.fontWeight = score >= 80 ? 'bold' : '';
return td;
};
const hotData = ref([
['Ana García', 92],
['James Okafor', 45],
['Li Wei', 73],
['Sara Müller', 88],
['Tom Nakamura', 31],
]);
const settings = ref<GridSettings>({
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
</script>
<template>
<div id="example4">
<HotTable :data="hotData" :settings="settings">
<HotColumn title="Employee" :read-only="true" />
<HotColumn title="Score" type="numeric" :renderer="scoreRenderer" />
</HotTable>
</div>
</template>

Result

Using HotColumn child components, each column reads its settings declaratively from Vue props rather than from a flat columns array, keeping your template in sync with your column configuration.