HotColumn component
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/>.
<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.
<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.
<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.
<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.