[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6BX99FG4JWZ1F3PXR4SERR2":3,"skill-same:01M6BX99FG4JWZ1F3PXR4SERR2":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":40,"repositoryHtmlUrl":41,"repositoryHomepageUrl":42,"ownerHtmlUrl":43,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":44,"install":45,"resources":58},"01M6BX99FG4JWZ1F3PXR4SERR2","stk-table-vue",null,"High-performance virtual scrolling table component for Vue 3 \u002F Vue 2.7. Provides usage guidance for StkTable component including virtual scroll, fixed columns, tree table, area selection, cell highlighting, custom cells, sorting, merge cells, and column resize. Use when the project uses stk-table-vue, StkTable component, or when the user mentions virtual table, sticky table, or high-performance data grid.","ja-plus\u002Fstk-table-vue","ja-plus","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F46619883?v=4","01M6BX84ZPSSX7M4VPPSDRPJ83","JA+","01M6BX853AT6WNFRQ121RV8W52",196,"MIT","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fstk-table-vue\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31],"vue","table","stk table vue","performance","component","merge","data","virtual","2026-11-10 10:12:30",false,"---\nname: stk-table-vue\ndescription: >\n  High-performance virtual scrolling table component for Vue 3 \u002F Vue 2.7.\n  Provides usage guidance for StkTable component including virtual scroll,\n  fixed columns, tree table, area selection, cell highlighting, custom cells,\n  sorting, merge cells, and column resize.\n  Use when the project uses stk-table-vue, StkTable component, or when the\n  user mentions virtual table, sticky table, or high-performance data grid.\n---\n\n# Stk Table Vue\n\nHigh-performance virtual scrolling table component based on Vue 3 \u002F Vue 2.7. Smooth performance with tens of thousands of rows. Designed for real-time data display with built-in highlighting and animation effects.\n\n- Vue 3 & Vue 2.7 support\n- Virtual scrolling (X & Y axis)\n- CSS `sticky` based fixed columns & fixed header\n- Multi-level header with horizontal virtual scroll\n- Tree table & expandable rows\n- Area selection with keyboard navigation\n- Cell highlighting with Animation API\n- Built-in custom cells: Filter, Editable, Checkbox, Number, Change\n- Column resize, header drag, row drag\n- Merge cells (virtual mode, huge rowspan\u002Fcolspan supported)\n- Sortable & filterable\n- Theme support (dark \u002F light)\n- CSS variables for easy customization\n- Based on native `\u003Ctable>` element\n- Zero third-party runtime dependencies\n\nOfficial docs: https:\u002F\u002Fja-plus.github.io\u002Fstk-table-vue\u002F\n\n## Installation\n\n```bash\nnpm install stk-table-vue\n```\n\n## Basic Usage\n\n```vue\n\u003Cscript setup>\nimport { StkTable } from 'stk-table-vue'\nimport { ref } from 'vue'\n\nconst tableRef = ref()\nconst columns = [\n  { title: 'Name', dataIndex: 'name' },\n  { title: 'Age', dataIndex: 'age' },\n  { title: 'Address', dataIndex: 'address' },\n]\nconst dataSource = [\n  { id: 1, name: 'John', age: 32, address: 'New York' },\n  { id: 2, name: 'Jim', age: 42, address: 'London' },\n]\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CStkTable\n    ref=\"tableRef\"\n    row-key=\"id\"\n    :columns=\"columns\"\n    :data-source=\"dataSource\"\n  \u002F>\n\u003C\u002Ftemplate>\n```\n\n## Column Configuration (StkTableColumn)\n\n```ts\ntype StkTableColumn\u003CT> = {\n  dataIndex: string       \u002F\u002F Required. Field name from row data\n  key?: any               \u002F\u002F Column unique key. Default: dataIndex\n  title?: string          \u002F\u002F Header text\n  type?: 'seq' | 'expand' | 'dragRow' | 'tree-node'  \u002F\u002F Special column types\n  width?: string | number \u002F\u002F Column width. Required for virtualX\n  minWidth?: string | number\n  maxWidth?: string | number\n  fixed?: 'left' | 'right' | null  \u002F\u002F Fixed column position\n  hidden?: boolean        \u002F\u002F Hide column\n  align?: 'right' | 'left' | 'center'\n  headerAlign?: 'right' | 'left' | 'center'\n  sorter?: boolean | ((data: T[], option: { order: Order; column: any }) => T[])\n  sortField?: string      \u002F\u002F Sort by different field\n  sortType?: 'number' | 'string'\n  sortConfig?: object     \u002F\u002F Per-column sort config\n  className?: string      \u002F\u002F td class\n  headerClassName?: string \u002F\u002F th class\n  customCell?: Component   \u002F\u002F Custom td render. Props: { row, col, cellValue, rowIndex, colIndex }\n  customHeaderCell?: Component \u002F\u002F Custom th render. Props: { col, rowIndex, colIndex }\n  customFooterCell?: Component \u002F\u002F Custom tfoot td render\n  children?: StkTableColumn[] \u002F\u002F Multi-level header\n  mergeCells?: (param: { row, col, rowIndex, colIndex }) => { rowspan?: number; colspan?: number } | undefined\n}\n```\n\n**Important**: `columns` is shallow-watched. When pushing\u002Fsplicing, update the reference:\n```ts\ncolumns.value = columns.value.slice()\n```\n\n## Key Props\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `columns` | `StkTableColumn[]` | Column config array. Shallow watch. |\n| `dataSource` | `any[]` | Data source. Shallow watch. |\n| `rowKey` | `string \\| ((row) => key)` | Row unique key field. Required. |\n| `virtual` | `boolean` | Enable vertical virtual scroll |\n| `virtualX` | `boolean` | Enable horizontal virtual scroll (columns must have width) |\n| `rowHeight` | `number` | Row height (or estimated height when autoRowHeight) |\n| `autoRowHeight` | `boolean \\| { expectedHeight? }` | Variable row height mode |\n| `stripe` | `boolean` | Zebra stripes |\n| `bordered` | `boolean \\| 'h' \\| 'v' \\| 'body-v' \\| 'body-h'` | Cell borders |\n| `theme` | `'light' \\| 'dark'` | Theme |\n| `width` | `string` | Table width |\n| `headless` | `boolean` | Hide header |\n| `rowHover` | `boolean` | Highlight row on hover |\n| `rowActive` | `boolean \\| { enabled?, disabled?, revokable? }` | Row selection highlight |\n| `cellHover` | `boolean` | Highlight cell on hover |\n| `cellActive` | `boolean` | Selected cell highlight |\n| `showOverflow` | `boolean` | Show ellipsis for overflow content |\n| `showHeaderOverflow` | `boolean` | Show ellipsis for header overflow |\n| `noDataFull` | `boolean` | Empty state fills height |\n| `sortRemote` | `boolean` | Server-side sorting (don't sort data locally) |\n| `sortConfig` | `SortConfig` | Sort configuration |\n| `colResizable` | `boolean \\| { disabled? }` | Column width resizable (requires v-model:columns) |\n| `headerDrag` | `boolean \\| { mode?, disabled? }` | Header draggable. mode: 'insert'(default) \\| 'swap' \\| 'none' |\n| `areaSelection` | `boolean \\| { enabled?, keyboard?, ctrl?, shift?, formatCellForClipboard? }` | Cell range selection |\n| `treeConfig` | `{ defaultExpandAll?, defaultExpandKeys?, defaultExpandLevel? }` | Tree table config |\n| `expandConfig` | `{ height? }` | Expand row config |\n| `dragRowConfig` | `{ mode?: 'insert' \\| 'swap' \\| 'none' }` | Row drag config |\n| `highlightConfig` | `{ duration?, fps? }` | Highlight animation config |\n| `seqConfig` | `{ startIndex? }` | Sequence column config (for pagination) |\n| `autoResize` | `boolean \\| (() => void)` | Auto recalculate virtual viewport. Default: true |\n| `fixedColShadow` | `boolean` | Show fixed column shadow |\n| `scrollbar` | `boolean \\| ScrollbarOptions` | Custom scrollbar |\n| `smoothScroll` | `boolean` | Smooth scrolling |\n| `scrollRowByRow` | `boolean \\| 'scrollbar'` | Integer row scrolling |\n| `footerData` | `DT[]` | Footer summary rows |\n| `emptyCellText` | `string \\| (option) => string` | Text for empty cells |\n| `rowClassName` | `(row, i) => string` | Row className callback |\n| `colKey` | `string` | Column unique key field. Default: 'dataIndex' |\n\n## Expose Methods\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `scrollTo` | `(top?, left?) \\| (options: ScrollToOptions)` | Scroll to position. Options: `{ top?, left?, behavior? }` where each axis accepts pixel or `{ index?, key?, px? }` |\n| `setHighlightDimRow` | `(rowKeys: UniqKey[], option?)` | Highlight row with fade animation. option: `{ method?, className?, keyframe?, duration? }` |\n| `setHighlightDimCell` | `(rowKey, colKey, option?)` | Highlight cell with fade animation |\n| `setCurrentRow` | `(rowKeyOrRow?, option?)` | Select a row. option: `{ silent?, deep? }` |\n| `setSelectedCell` | `(row?, col?, option?)` | Select a cell (cellActive=true). option: `{ silent? }` |\n| `setSorter` | `(colKey, order, option?)` | Set sort state. order: 'asc'\\|'desc'\\|null. option: `{ sort?, silent?, force?, sortOption? }` |\n| `resetSorter` | `()` | Reset sort state |\n| `setTreeExpand` | `(row, option?)` | Expand\u002Fcollapse tree node. option: `{ expand?, all?, level?, parents? }` |\n| `setRowExpand` | `(rowKeyOrRow, expand?, data?)` | Expand\u002Fcollapse row. data: `{ col?, silent? }` |\n| `getTableData` | `()` | Get sorted table data array |\n| `getRowIndex` | `(rowKeyOrRow) => number` | Get row index (-1 if not found) |\n| `getColumnIndex` | `(colKeyOrCol) => number` | Get column index (-1 if not found) |\n| `initVirtualScroll` | `(height?)` | Recalculate virtual viewport |\n| `initVirtualScrollX` | `()` | Recalculate horizontal virtual viewport |\n| `initVirtualScrollY` | `(height?)` | Recalculate vertical virtual viewport |\n| `setAutoHeight` | `(rowKey, height?)` | Set variable row height |\n| `clearAllAutoHeight` | `()` | Clear all variable row heights |\n| `clearMergeCellsCache` | `()` | Clear merge cells cache (needed after in-place data mutation) |\n| `setAreaSelection` | `(ranges, option?)` | Set selection ranges. option: `{ silent?, scrollToView? }` |\n| `getSelectedArea` | `()` | Get selected area: `{ rows, cols, ranges }` |\n| `clearSelectedArea` | `()` | Clear selection |\n| `copySelectedArea` | `() => string` | Copy selection as TSV text |\n| `setFilter` | `(status \\| null, option?)` | Set filter. option: `{ remote?, silent? }` |\n| `getSortColumns` | `()` | Get sort columns: `{ key, order }[]` |\n\n### scrollTo Usage\n\n```ts\n\u002F\u002F Pixel coordinates\ntableRef.value.scrollTo(100, 200)        \u002F\u002F top=100, left=200\ntableRef.value.scrollTo(null, 200)       \u002F\u002F only change left\n\n\u002F\u002F Options overload (omitted axis = no change)\ntableRef.value.scrollTo({ top: 100, left: 200 })\ntableRef.value.scrollTo({ top: { index: 5 } })                    \u002F\u002F scroll to 5th row\ntableRef.value.scrollTo({ top: { key: 'row-42' } })               \u002F\u002F scroll to row by key\ntableRef.value.scrollTo({ top: { index: 5, px: 10 } })            \u002F\u002F row + offset\ntableRef.value.scrollTo({ left: { key: 'name' }, behavior: 'smooth' }) \u002F\u002F smooth scroll to column\n```\n\n## Events\n\n| Event | Callback Signature | Description |\n|-------|-------------------|-------------|\n| `sort-change` | `(col, order, data, sortConfig)` | Sort changed |\n| `row-click` | `(ev, row, { rowIndex })` | Row click |\n| `row-dblclick` | `(ev, row, { rowIndex })` | Row double click |\n| `current-change` | `(ev, row \\| undefined, { select })` | Row selection changed |\n| `cell-click` | `(ev, row, col, { rowIndex })` | Cell click |\n| `cell-selected` | `(ev, { select, row, col })` | Cell selection changed |\n| `header-cell-click` | `(ev, col)` | Header cell click |\n| `row-menu` | `(ev, row, { rowIndex })` | Row right click |\n| `header-row-menu` | `(ev)` | Header right click |\n| `scroll` | `(ev, { startIndex, endIndex })` | Table scroll |\n| `scroll-x` | `(ev)` | Horizontal scroll |\n| `col-order-change` | `(dragStartKey, targetColKey)` | Column drag reorder |\n| `col-resize` | `(col)` | Column width changed |\n| `row-order-change` | `(dragStartKey, targetRowKey)` | Row drag reorder |\n| `toggle-row-expand` | `({ expanded, row, col })` | Row expand\u002Fcollapse |\n| `toggle-tree-expand` | `({ expanded, row, col })` | Tree expand\u002Fcollapse |\n| `area-selection-change` | `(ranges)` | Selection changed |\n| `filter-change` | `(status)` | Filter changed |\n| `update:columns` | `(cols)` | v-model:columns update (col resize) |\n\n## Slots\n\n| Slot | Props | Description |\n|------|-------|-------------|\n| `tableHeader` | `{ col }` | Custom header (prefer customHeaderCell for single column) |\n| `empty` | -- | Empty data state |\n| `expand` | `{ col, row }` | Expand row content |\n| `customBottom` | -- | Table bottom area (use IntersectionObserver for infinite scroll) |\n\n## Custom Cells\n\nUse `customCell` to render custom cell content:\n\n```vue\n\u003Cscript setup>\nimport { defineComponent, h } from 'vue'\n\n\u002F\u002F Functional component (simplest)\nconst columns = [{\n  dataIndex: 'name',\n  customCell: (props) => h('span', { style: { color: 'red' } }, props.cellValue)\n}]\n\n\u002F\u002F Or use defineComponent for reactive cells\nconst columns2 = [{\n  dataIndex: 'status',\n  customCell: defineComponent({\n    setup(props) {\n      \u002F\u002F props: { row, col, cellValue, rowIndex, colIndex, expanded?, treeExpanded? }\n      return () => h('span', props.cellValue > 0 ? 'Active' : 'Inactive')\n    }\n  })\n}]\n\u003C\u002Fscript>\n```\n\n## Built-in Custom Cells\n\n```ts\nimport { createFilterCell } from 'stk-table-vue'\nimport { createEditableCell } from 'stk-table-vue'\nimport { createCheckboxCell } from 'stk-table-vue'\nimport { createNumberCell } from 'stk-table-vue'\nimport { createChangeCell } from 'stk-table-vue'\nimport { formatNumber } from 'stk-table-vue'\n```\n\n## Common Patterns\n\nFor detailed code examples, see [examples.md](.\u002Fexamples.md):\n- Virtual scroll with large data\n- Fixed columns & header\n- Sorting (single\u002Fmulti\u002Fremote)\n- Tree table\n- Expand rows\n- Cell highlighting\n- Area selection + keyboard navigation\n- Column resize + drag\n- Merge cells\n- Variable row height\n\n## Additional Resources\n\n- Full API reference: [api-reference.md](.\u002Fapi-reference.md)\n- Official documentation: https:\u002F\u002Fja-plus.github.io\u002Fstk-table-vue\u002F\n- GitHub: https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\n- Online Demo: https:\u002F\u002Fstackblitz.com\u002Fedit\u002Fvitejs-vite-ad91hh?file=src%2FDemo%2Findex.vue\n","# Stk Table Vue\n\nHigh-performance virtual scrolling table component based on Vue 3 \u002F Vue 2.7. Smooth performance with tens of thousands of rows. Designed for real-time data display with built-in highlighting and animation effects.\n\n- Vue 3 & Vue 2.7 support\n- Virtual scrolling (X & Y axis)\n- CSS `sticky` based fixed columns & fixed header\n- Multi-level header with horizontal virtual scroll\n- Tree table & expandable rows\n- Area selection with keyboard navigation\n- Cell highlighting with Animation API\n- Built-in custom cells: Filter, Editable, Checkbox, Number, Change\n- Column resize, header drag, row drag\n- Merge cells (virtual mode, huge rowspan\u002Fcolspan supported)\n- Sortable & filterable\n- Theme support (dark \u002F light)\n- CSS variables for easy customization\n- Based on native `\u003Ctable>` element\n- Zero third-party runtime dependencies\n\nOfficial docs: https:\u002F\u002Fja-plus.github.io\u002Fstk-table-vue\u002F\n\n## Installation\n\n```bash\nnpm install stk-table-vue\n```\n\n## Basic Usage\n\n```vue\n\u003Cscript setup>\nimport { StkTable } from 'stk-table-vue'\nimport { ref } from 'vue'\n\nconst tableRef = ref()\nconst columns = [\n  { title: 'Name', dataIndex: 'name' },\n  { title: 'Age', dataIndex: 'age' },\n  { title: 'Address', dataIndex: 'address' },\n]\nconst dataSource = [\n  { id: 1, name: 'John', age: 32, address: 'New York' },\n  { id: 2, name: 'Jim', age: 42, address: 'London' },\n]\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CStkTable\n    ref=\"tableRef\"\n    row-key=\"id\"\n    :columns=\"columns\"\n    :data-source=\"dataSource\"\n  \u002F>\n\u003C\u002Ftemplate>\n```\n\n## Column Configuration (StkTableColumn)\n\n```ts\ntype StkTableColumn\u003CT> = {\n  dataIndex: string       \u002F\u002F Required. Field name from row data\n  key?: any               \u002F\u002F Column unique key. Default: dataIndex\n  title?: string          \u002F\u002F Header text\n  type?: 'seq' | 'expand' | 'dragRow' | 'tree-node'  \u002F\u002F Special column types\n  width?: string | number \u002F\u002F Column width. Required for virtualX\n  minWidth?: string | number\n  maxWidth?: string | number\n  fixed?: 'left' | 'right' | null  \u002F\u002F Fixed column position\n  hidden?: boolean        \u002F\u002F Hide column\n  align?: 'right' | 'left' | 'center'\n  headerAlign?: 'right' | 'left' | 'center'\n  sorter?: boolean | ((data: T[], option: { order: Order; column: any }) => T[])\n  sortField?: string      \u002F\u002F Sort by different field\n  sortType?: 'number' | 'string'\n  sortConfig?: object     \u002F\u002F Per-column sort config\n  className?: string      \u002F\u002F td class\n  headerClassName?: string \u002F\u002F th class\n  customCell?: Component   \u002F\u002F Custom td render. Props: { row, col, cellValue, rowIndex, colIndex }\n  customHeaderCell?: Component \u002F\u002F Custom th render. Props: { col, rowIndex, colIndex }\n  customFooterCell?: Component \u002F\u002F Custom tfoot td render\n  children?: StkTableColumn[] \u002F\u002F Multi-level header\n  mergeCells?: (param: { row, col, rowIndex, colIndex }) => { rowspan?: number; colspan?: number } | undefined\n}\n```\n\n**Important**: `columns` is shallow-watched. When pushing\u002Fsplicing, update the reference:\n```ts\ncolumns.value = columns.value.slice()\n```\n\n## Key Props\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `columns` | `StkTableColumn[]` | Column config array. Shallow watch. |\n| `dataSource` | `any[]` | Data source. Shallow watch. |\n| `rowKey` | `string \\| ((row) => key)` | Row unique key field. Required. |\n| `virtual` | `boolean` | Enable vertical virtual scroll |\n| `virtualX` | `boolean` | Enable horizontal virtual scroll (columns must have width) |\n| `rowHeight` | `number` | Row height (or estimated height when autoRowHeight) |\n| `autoRowHeight` | `boolean \\| { expectedHeight? }` | Variable row height mode |\n| `stripe` | `boolean` | Zebra stripes |\n| `bordered` | `boolean \\| 'h' \\| 'v' \\| 'body-v' \\| 'body-h'` | Cell borders |\n| `theme` | `'light' \\| 'dark'` | Theme |\n| `width` | `string` | Table width |\n| `headless` | `boolean` | Hide header |\n| `rowHover` | `boolean` | Highlight row on hover |\n| `rowActive` | `boolean \\| { enabled?, disabled?, revokable? }` | Row selection highlight |\n| `cellHover` | `boolean` | Highlight cell on hover |\n| `cellActive` | `boolean` | Selected cell highlight |\n| `showOverflow` | `boolean` | Show ellipsis for overflow content |\n| `showHeaderOverflow` | `boolean` | Show ellipsis for header overflow |\n| `noDataFull` | `boolean` | Empty state fills height |\n| `sortRemote` | `boolean` | Server-side sorting (don't sort data locally) |\n| `sortConfig` | `SortConfig` | Sort configuration |\n| `colResizable` | `boolean \\| { disabled? }` | Column width resizable (requires v-model:columns) |\n| `headerDrag` | `boolean \\| { mode?, disabled? }` | Header draggable. mode: 'insert'(default) \\| 'swap' \\| 'none' |\n| `areaSelection` | `boolean \\| { enabled?, keyboard?, ctrl?, shift?, formatCellForClipboard? }` | Cell range selection |\n| `treeConfig` | `{ defaultExpandAll?, defaultExpandKeys?, defaultExpandLevel? }` | Tree table config |\n| `expandConfig` | `{ height? }` | Expand row config |\n| `dragRowConfig` | `{ mode?: 'insert' \\| 'swap' \\| 'none' }` | Row drag config |\n| `highlightConfig` | `{ duration?, fps? }` | Highlight animation config |\n| `seqConfig` | `{ startIndex? }` | Sequence column config (for pagination) |\n| `autoResize` | `boolean \\| (() => void)` | Auto recalculate virtual viewport. Default: true |\n| `fixedColShadow` | `boolean` | Show fixed column shadow |\n| `scrollbar` | `boolean \\| ScrollbarOptions` | Custom scrollbar |\n| `smoothScroll` | `boolean` | Smooth scrolling |\n| `scrollRowByRow` | `boolean \\| 'scrollbar'` | Integer row scrolling |\n| `footerData` | `DT[]` | Footer summary rows |\n| `emptyCellText` | `string \\| (option) => string` | Text for empty cells |\n| `rowClassName` | `(row, i) => string` | Row className callback |\n| `colKey` | `string` | Column unique key field. Default: 'dataIndex' |\n\n## Expose Methods\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `scrollTo` | `(top?, left?) \\| (options: ScrollToOptions)` | Scroll to position. Options: `{ top?, left?, behavior? }` where each axis accepts pixel or `{ index?, key?, px? }` |\n| `setHighlightDimRow` | `(rowKeys: UniqKey[], option?)` | Highlight row with fade animation. option: `{ method?, className?, keyframe?, duration? }` |\n| `setHighlightDimCell` | `(rowKey, colKey, option?)` | Highlight cell with fade animation |\n| `setCurrentRow` | `(rowKeyOrRow?, option?)` | Select a row. option: `{ silent?, deep? }` |\n| `setSelectedCell` | `(row?, col?, option?)` | Select a cell (cellActive=true). option: `{ silent? }` |\n| `setSorter` | `(colKey, order, option?)` | Set sort state. order: 'asc'\\|'desc'\\|null. option: `{ sort?, silent?, force?, sortOption? }` |\n| `resetSorter` | `()` | Reset sort state |\n| `setTreeExpand` | `(row, option?)` | Expand\u002Fcollapse tree node. option: `{ expand?, all?, level?, parents? }` |\n| `setRowExpand` | `(rowKeyOrRow, expand?, data?)` | Expand\u002Fcollapse row. data: `{ col?, silent? }` |\n| `getTableData` | `()` | Get sorted table data array |\n| `getRowIndex` | `(rowKeyOrRow) => number` | Get row index (-1 if not found) |\n| `getColumnIndex` | `(colKeyOrCol) => number` | Get column index (-1 if not found) |\n| `initVirtualScroll` | `(height?)` | Recalculate virtual viewport |\n| `initVirtualScrollX` | `()` | Recalculate horizontal virtual viewport |\n| `initVirtualScrollY` | `(height?)` | Recalculate vertical virtual viewport |\n| `setAutoHeight` | `(rowKey, height?)` | Set variable row height |\n| `clearAllAutoHeight` | `()` | Clear all variable row heights |\n| `clearMergeCellsCache` | `()` | Clear merge cells cache (needed after in-place data mutation) |\n| `setAreaSelection` | `(ranges, option?)` | Set selection ranges. option: `{ silent?, scrollToView? }` |\n| `getSelectedArea` | `()` | Get selected area: `{ rows, cols, ranges }` |\n| `clearSelectedArea` | `()` | Clear selection |\n| `copySelectedArea` | `() => string` | Copy selection as TSV text |\n| `setFilter` | `(status \\| null, option?)` | Set filter. option: `{ remote?, silent? }` |\n| `getSortColumns` | `()` | Get sort columns: `{ key, order }[]` |\n\n### scrollTo Usage\n\n```ts\n\u002F\u002F Pixel coordinates\ntableRef.value.scrollTo(100, 200)        \u002F\u002F top=100, left=200\ntableRef.value.scrollTo(null, 200)       \u002F\u002F only change left\n\n\u002F\u002F Options overload (omitted axis = no change)\ntableRef.value.scrollTo({ top: 100, left: 200 })\ntableRef.value.scrollTo({ top: { index: 5 } })                    \u002F\u002F scroll to 5th row\ntableRef.value.scrollTo({ top: { key: 'row-42' } })               \u002F\u002F scroll to row by key\ntableRef.value.scrollTo({ top: { index: 5, px: 10 } })            \u002F\u002F row + offset\ntableRef.value.scrollTo({ left: { key: 'name' }, behavior: 'smooth' }) \u002F\u002F smooth scroll to column\n```\n\n## Events\n\n| Event | Callback Signature | Description |\n|-------|-------------------|-------------|\n| `sort-change` | `(col, order, data, sortConfig)` | Sort changed |\n| `row-click` | `(ev, row, { rowIndex })` | Row click |\n| `row-dblclick` | `(ev, row, { rowIndex })` | Row double click |\n| `current-change` | `(ev, row \\| undefined, { select })` | Row selection changed |\n| `cell-click` | `(ev, row, col, { rowIndex })` | Cell click |\n| `cell-selected` | `(ev, { select, row, col })` | Cell selection changed |\n| `header-cell-click` | `(ev, col)` | Header cell click |\n| `row-menu` | `(ev, row, { rowIndex })` | Row right click |\n| `header-row-menu` | `(ev)` | Header right click |\n| `scroll` | `(ev, { startIndex, endIndex })` | Table scroll |\n| `scroll-x` | `(ev)` | Horizontal scroll |\n| `col-order-change` | `(dragStartKey, targetColKey)` | Column drag reorder |\n| `col-resize` | `(col)` | Column width changed |\n| `row-order-change` | `(dragStartKey, targetRowKey)` | Row drag reorder |\n| `toggle-row-expand` | `({ expanded, row, col })` | Row expand\u002Fcollapse |\n| `toggle-tree-expand` | `({ expanded, row, col })` | Tree expand\u002Fcollapse |\n| `area-selection-change` | `(ranges)` | Selection changed |\n| `filter-change` | `(status)` | Filter changed |\n| `update:columns` | `(cols)` | v-model:columns update (col resize) |\n\n## Slots\n\n| Slot | Props | Description |\n|------|-------|-------------|\n| `tableHeader` | `{ col }` | Custom header (prefer customHeaderCell for single column) |\n| `empty` | -- | Empty data state |\n| `expand` | `{ col, row }` | Expand row content |\n| `customBottom` | -- | Table bottom area (use IntersectionObserver for infinite scroll) |\n\n## Custom Cells\n\nUse `customCell` to render custom cell content:\n\n```vue\n\u003Cscript setup>\nimport { defineComponent, h } from 'vue'\n\n\u002F\u002F Functional component (simplest)\nconst columns = [{\n  dataIndex: 'name',\n  customCell: (props) => h('span', { style: { color: 'red' } }, props.cellValue)\n}]\n\n\u002F\u002F Or use defineComponent for reactive cells\nconst columns2 = [{\n  dataIndex: 'status',\n  customCell: defineComponent({\n    setup(props) {\n      \u002F\u002F props: { row, col, cellValue, rowIndex, colIndex, expanded?, treeExpanded? }\n      return () => h('span', props.cellValue > 0 ? 'Active' : 'Inactive')\n    }\n  })\n}]\n\u003C\u002Fscript>\n```\n\n## Built-in Custom Cells\n\n```ts\nimport { createFilterCell } from 'stk-table-vue'\nimport { createEditableCell } from 'stk-table-vue'\nimport { createCheckboxCell } from 'stk-table-vue'\nimport { createNumberCell } from 'stk-table-vue'\nimport { createChangeCell } from 'stk-table-vue'\nimport { formatNumber } from 'stk-table-vue'\n```\n\n## Common Patterns\n\nFor detailed code examples, see [examples.md](.\u002Fexamples.md):\n- Virtual scroll with large data\n- Fixed columns & header\n- Sorting (single\u002Fmulti\u002Fremote)\n- Tree table\n- Expand rows\n- Cell highlighting\n- Area selection + keyboard navigation\n- Column resize + drag\n- Merge cells\n- Variable row height\n\n## Additional Resources\n\n- Full API reference: [api-reference.md](.\u002Fapi-reference.md)\n- Official documentation: https:\u002F\u002Fja-plus.github.io\u002Fstk-table-vue\u002F\n- GitHub: https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\n- Online Demo: https:\u002F\u002Fstackblitz.com\u002Fedit\u002Fvitejs-vite-ad91hh?file=src%2FDemo%2Findex.vue\n",{"name":5,"description":7},"master","2d2ce7db14fdc476b53552c75547e176dc4d3630",".qoder\u002Fskills\u002Fstk-table-vue",24,"https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue","https:\u002F\u002Fja-plus.github.io\u002Fstk-table-vue\u002F","https:\u002F\u002Fgithub.com\u002Fja-plus","2026-10-28 11:55:42",{"source":8,"skillName":5,"commands":46,"prompt":56,"zipAvailable":57},[47,50,53],{"tool":48,"command":49},"npx","npx skills add ja-plus\u002Fstk-table-vue --skill stk-table-vue",{"tool":51,"command":52},"bunx","bunx skills add ja-plus\u002Fstk-table-vue --skill stk-table-vue",{"tool":54,"command":55},"pnpm","pnpm dlx skills add ja-plus\u002Fstk-table-vue --skill stk-table-vue","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fstk-table-vue\u002FSKILL.md",true,[59,65],{"path":60,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":63,"sourceHtmlUrl":64},"api-reference.md","REFERENCE","参考文档",15340,"https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fstk-table-vue\u002Fapi-reference.md",{"path":66,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":67,"sourceHtmlUrl":68},"examples.md",14256,"https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fstk-table-vue\u002Fexamples.md",[70,86,96,106,115,125],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":32},"01M6BX97G7136CQ7MT7C8848S6","openspec-update-change","Update an OpenSpec change by revising its existing planning artifacts and keeping them coherent with one another. Use when the user wants to revise a change's plan, fold new decisions into it, or reconcile its artifacts after an edit. Never edits code.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-update-change\u002FSKILL.md",[],[77,78,79,80,81,82,83,84,85],"change","update","openspec update change","cli","code","planning","artifacts","Bash","plan",{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":32},"01M6BX957DB1R7XNSJDG5NB6BY","openspec-sync-specs","Sync delta specs from a change to main specs. Use when the user wants to update main specs with changes from a delta spec, without archiving the change.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-sync-specs\u002FSKILL.md",[],[93,94,80,77,95,78,84],"sync","openspec sync specs","spec",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":32},"01M6BX931KEMD755E6RMJ1TD7Y","openspec-propose","Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-propose\u002FSKILL.md",[],[103,77,84,104,80,105,83],"openspec propose","design","tasks",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":32},"01M6BX90YHTY66X75CHZWRBX89","openspec-explore","Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-explore\u002FSKILL.md",[],[113,114,80,77,84],"openspec explore","explore",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":32},"01M6BX8YP03NTMFTCFSNQED4TX","openspec-archive-change","Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-archive-change\u002FSKILL.md",[],[122,123,77,80,124,84],"archive","openspec archive change","workflow",{"skillNo":126,"name":127,"nameZh":6,"description":128,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":32},"01M6BX8WKDWAP4T9YYCQPRHXZE","openspec-apply-change","Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.","https:\u002F\u002Fgithub.com\u002Fja-plus\u002Fstk-table-vue\u002Fblob\u002Fmaster\u002F.qoder\u002Fskills\u002Fopenspec-apply-change\u002FSKILL.md",[],[132,77,133,105,134,84,135,80],"openspec apply change","implement","start","continue"]