* fix(components): [upload] unable to delete files in removeFile (#19437) * fix(components): [upload] unable to delete files in removeFile * fix(components): [upload] remove file when fileList does not use v-model * Update packages/components/upload/src/use-handlers.ts Co-authored-by: btea <2356281422@qq.com> --------- Co-authored-by: leiyu <leiyu@cmss.chinamobile.com> Co-authored-by: btea <2356281422@qq.com> * fix(components): [page-header] use `$slots` instead of `useSlots` (#19455) * fix(components): [page-header] use `$slots` instead of `useSlots` closed #19453 * test(components): [page-header] add classes slots rendering case * fix(components): [select] input width fills the remaining width (#19292) * fix(components): [select] input width fills the remaining width closed #17886 * fix: type * feat(components): [select, select-v2] add loading class to validateIcon (#19379) fix(components): [select, select-v2] add loading class to validateIcon * chore: update doc (#19479) * perf(components): [table] prioritize use rowKey to determine whether it is selected (#19451) * perf(components): [table] use rowKey to determine whether it is selected * chore: revert includes * perf: use includes replace isEqual * feat(components): [table] add allow-drag-last-column prop (#19374) * chore: Update changelog 2.9.2 (#19491) chore: update changelog 2.9.2 * chore: format dropdown docs (#19495) * fix(components): [description] `labelWidth` is invalid when no border (#19162) * fix(components): [description] `labelWidth` is invalid when no border * test: add test case * fix(hooks): [use-lockscreen] remove hiddenCls (#19429) * fix(hooks): [use-lockscreen] remove hiddenCls * fix(hooks): [useLockscreen] unit test * test(hooks): [useLockscreen] should not cleanup when not all unmounted * test(hooks): [useLockscreen] update test * test(hooks): [useLockscreen] update test * feat(components): [dialog/drawer] add custom sub classes (#19099) * feat(components): [dialog/drawer] add custom sub classes * docs(components): add custom classes for drawer/dialog slots * docs(components): [dialog/drawer] keep same description * test: add dialog/drawer sub classes * refactor: sync typo docs with props * chore: change release version * chore: rename * chore: fix doc --------- Co-authored-by: btea <2356281422@qq.com> * chore: upgrade puppeteer to 23.11.1 (#19500) * ci: update test-ssr.yml (#19521) * fix(components): [form] on post rules update reset field (#19129) * fix(components): [form] track rules on post update closed #19109 * fix(components): [form] ensure reset field state if no rules closed #19128 * test: add validate on rule change case * chore: on rules update reset field error * chore: fixup --------- Co-authored-by: btea <2356281422@qq.com> * fix(components): [tabs] set modelValue synchronously if beforeLeave is not set or is synchronous (#19387) * fix: [tabs] sync modelValue if beforeLeave is not set or is synchronous * feat: add unit test * feat(i18n): add Hindi language (#19483) * feat(i18n): add Hindi language * feat(i18n): update component and hindi translations * feat(i18n): update lint * docs: [collapse] change event parameter type error (#19539) * chore: fix handleChange type error * Update docs/examples/collapse/custom-icon.vue Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> --------- Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> * fix(components): [select] make sure the e-tag is not obstructed(#19529) (#19534) Co-authored-by: baiwusanyu-c <chenzhihui@chabaidao.com> * ci: run pkg.new when push (#19544) * docs: [button] add description (#19536) * ci: stop run pkg.new when push (#19545) * improvement(components): [text] add the title attribute (#19496) * improvement(components): [text] keep the inherited title attribute (#19551) * improvement(components): [text] keep the inherited title attribute * fix: content update recalculation * fix(components): [dialog] fix scroll bar not resetting to top on reopen (#19471) * fix(components): [dialog] Fix scroll bar not resetting to top on reopen closed #19420 * fix(components): update * fix(components): [dialog] update --------- Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> * test: [table] add show-overflow-tooltip trigger (#19556) * test: [table] add show-overflow-tooltip trigger * test: [table] add show-overflow-tooltip trigger * feat(i18n): add Norsk(no) language (#19523) * chore: update doc ui (#19586) * style(components): [dialog] no rounded when in fullscreen (#19583) * feat(component): [time-select] add include end time attribute (#19253) * feat: [time-select] init includeEndTime 🚧 * test: time-select includeEndTime 🚧 * refactor: renaming & cleanup * test(components): [time-select] add includeEndTime cases ✅ * docs(components): [time-select] add `includeEndTime` attribute * chore: change release version * chore: set `includeEndTime` default to false * docs: fix props typo * chore: remove useless assignment * chore: rename optionValue to currentTime * chore: update release version * Revert "ci: update test-ssr.yml" (#19610) Revert "ci: update test-ssr.yml (#19521)" This reverts commiteab540a3f7. * chore: Update changelog 2.9.3 (#19611) chore: update changelog 2.9.3 * chore: [time-picker] correct typo in `timePickerRangeTriggerProps` (#19487) * fix: correct typo in timePickerRangeTriggerProps * chore: deprecate misspelled export `timePickerRngeTriggerProps` --------- Co-authored-by: btea <2356281422@qq.com> * chore(docs): implement dynamic links for playground based on preview state (#19612) * docs: [calendar] add exposes (#19593) * docs: [calendar] add exposes * Apply suggestions from code review add translation characters Co-authored-by: btea <2356281422@qq.com> * docs: [calendar] format the exposes table --------- Co-authored-by: btea <2356281422@qq.com> * feat(components): [image-viewer] add showPreview method (#19466) * feat(components): [image-viewer] add showPreview method * docs(components): [image] update showPreview method version to 2.9.4 * chore: enable fileNesting config (#19615) * docs(components): [table-v2] add `indent-size` (#19621) docs(components): [table-v2] add `indent-size` Co-authored-by: gongbei <gongbei@wps.cn> * chore: [message-box] remove @ts-nocheck directive (#19277) * chore: [message-box] remove @ts-nocheck directive * fix: type * Update packages/components/message-box/src/index.vue Co-authored-by: qiang <qw13131wang@gmail.com> --------- Co-authored-by: qiang <qw13131wang@gmail.com> * feat(locale): add language Chinese Hongkong and Chinese Macau (#19608) * feat(components): [select] add popup-scroll event (#19589) * feat(components): [select] add popup-scroll event * Update docs/en-US/component/select.md Co-authored-by: btea <2356281422@qq.com> * chore: format --------- Co-authored-by: btea <2356281422@qq.com> Co-authored-by: warmthsea <2586244885@qq.com> * docs: add code file-title and icon (#19638) * docs: add code file-title and icon * chore: update deps * docs: add lang records (#19650) * chore: [tree] remove unused arg (#19255) * feat(i18n): add Telugu language (#19624) * feat(i18n): add Telugu language * chore(i18n): added missing keys in Telugu locale * chore: format telugu locale file. * chore(locale): fix lint in te.ts * docs: add lang records * feat(components): [image-viewer] add `progress` slot and `show-progress` props (#19465) * refactor(components): simplify computed properties in image-viewer * feat(components): [image-viewer] add progress number * test(components): remove console logs from image-viewer tests * feat(components): [image-viewer] update progress display and style * test(components): update progress selector in image-viewer tests * feat(components): [image-viewer] add slot support for progress display * docs(components): [image] add progress content description * docs(components): update docs * feat(components): [image] simplify progress slot binding * docs(components): update * Update packages/components/image-viewer/__tests__/image-viewer.test.tsx Co-authored-by: btea <2356281422@qq.com> * Update docs/en-US/component/image.md Co-authored-by: btea <2356281422@qq.com> * docs: update progress version in image documentation * Update packages/components/image-viewer/src/image-viewer.vue Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * feat: add showProgress props * docs: add demo * docs: update v * Update docs/en-US/component/image.md Co-authored-by: btea <2356281422@qq.com> --------- Co-authored-by: btea <2356281422@qq.com> Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * fix(components): [table-footer] update cols width on layout change (#19064) fix(components): [table-footer] update cols width on layout change closed #19054 Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * fix(ci): types & dark theme sync with pr (#19668) ci: set whole pr bundle * fix(ci): move all bundle to docs dist (#19671) * docs: format table-v2 & use actions/upload-artifact v4 (#19670) * docs: format table-v2 * chore: update actions/upload-artifact * chore: update * chore: update * feat(components): [image-viewer] add toolbar slot (#19497) * feat(components): [image-viewer] add toolbar slot * feat(docs): add docs * docs: update * docs: update * docs: update image viewer API types for clarity * docs: update custom toolbar version in image documentation to 2.9.4 * Update docs/examples/image/custom-toolbar.vue Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * style: remove dividers * revert: style * docs: format --------- Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * docs: [menu] `left-and-right` example style tag add scoped (#19654) Update left-and-right.vue 防止文档演示项目整页元素布局样式被修改 Co-authored-by: btea <2356281422@qq.com> * docs: [tree-v2] fix style error and remove annotation (#19681) * docs: [transfer] fix type error (#19682) * feat(components): [cascader] add `prefix` slot (#19631) * feat(components): [cascader] add prefix slot * docs(components): [cascader] add preview slot * Revert "docs(components): [cascader] add preview slot" This reverts commit1a40ca13ea. * docs(components): [cascader] revert for typo * fix(components): do not render prefix if prefix slot is not used * docs(components): [cascader] prefix version number added Co-authored-by: btea <2356281422@qq.com> * docs(components): [cascader] format docs --------- Co-authored-by: btea <2356281422@qq.com> * fix(components): [table] selection-change event emit incorrectly (#19618) * feat(components): [table] fix 'selection-change' event emit incorrectly * fix(components): [table] add test case * docs: [timeline] fix type error (#19688) * docs: [timeline] fix type error * Update docs/examples/timeline/custom-node.vue Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * Update docs/examples/timeline/custom-node.vue Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> --------- Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * docs: [dropdown] add `button-props` prop (#19694) docs: [dropdown] add `button-props` prop Co-authored-by: Bruce Lu <smallbone.lu@gmail.com> * docs: [tabs] fix type error (#19690) * docs: [switch] fix type error (#19704) * fix(components): [table] The index parameter of the selectable function is undefined (#19587) * fix(components): [table] first record can not be checked * fix(components): [table] last commit doesnt work for others index Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> * test(components): [table] add test cases * test(components): [table] modify the test case of the last submission --------- Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> Co-authored-by: btea <2356281422@qq.com> * fix(components): [autocomplete] prevent closing if focus is inside popper content (#19522) fix: [autocomplete] prevent closing if focus is inside popper content * docs: [layout] add a tip for layout column (#19669) docs: layout add tip * docs: [checkbox] fix intermediate example type error (#19713) docs: [checkbox] fix type error * docs: [input-number] fix type error (#19712) * docs: fix Exposes error (#19733) * feat(components): [table] add tooltip-formatter table & table-column prop (#19524) * feat(components): [table] add `tooltip-formatter` table-column prop closed #19507 * docs: add example * docs: demo remove tooltip formatter index * refactor(components): refactor code * docs: simpify tooltip demo * fix: fix warning error * feat(components): add table tooltip-formatter prop & merge slot * refactor: reuse variables * test: add tooltip-formatter test * docs: upgrade version * feat(components): [table] add `tooltip-formatter` table-column prop closed #19507 * docs: add example * docs: demo remove tooltip formatter index * refactor(components): refactor code * docs: simpify tooltip demo * fix: fix warning error * feat(components): add table tooltip-formatter prop & merge slot * refactor: reuse variables * test: add tooltip-formatter test * docs: upgrade version * refactor: change parameter to obj args * fix: property change to prop * fix: export `TableOverflowTooltipFormatterData` * refactor: `TableOverflowTooltipFormatterData` to `TableTooltipData` * fix: remove useless import * fix: refactor code --------- Co-authored-by: btea <2356281422@qq.com> * docs: search input default focus (#19724) * docs: search input default focus * fix(docs): ensure search input is focused after component mounts * revert: update * Update docs/.vitepress/vitepress/components/globals/overview.vue Co-authored-by: qiang <qw13131wang@gmail.com> * Update docs/.vitepress/vitepress/components/globals/overview.vue Co-authored-by: qiang <qw13131wang@gmail.com> * docs: update --------- Co-authored-by: qiang <qw13131wang@gmail.com> * fix(components): [input] refused to apply inline style because it violates csp (#19541) fix(components): [input] CSP support #15065 `element.setAttribute('style', 'css code')` violate Content Security Policy (CSP) using `element.style.setProperty()` instead * docs: [tooltip] fix type error (#19687) * docs: fix type error * docs: [tooltip] remove unnecessary width and height in mousemove handler * fix: update * fix: update * fix(components): [table-v2] make the fixed columns scroll like mainTable (#19104) fix(components): [table-v2] Make the fixed columns scroll like mainTable Make the fixed columns behave like the mainTable, where the rows containing fixedData stick in place, and the rest of the rows scroll. closed #19103 * fix(components): [cascader-panel] lazy return children can't get value (#19100) * fix(components): [cascader-panel] lazy return children can't get value fix #9157 closed #9157 * fix: update * fix(components): [table] fix the logic of `selection` column when `fixed` state changes dynamically (#19703) * fix(components): [table] selection column fixed left * fix(components): [table] optimize function * fix(components): [table] add dynamic columns test case * fix(components): [table] the toggleTreeExpansion failed to trigger load function (#18728) * feat(components): [table] fix lazy loading * Modify the function usage * chore: format `dropdown.md` (#19758) chore: format dropdown.md * feat(locale): export zhHk/zhMo (#19762) * docs: [calendar] add CalendarDateType Type Declarations (#19766) docs: [calendar] add Type Declarations * chore: update doc (#19770) * fix(components): [table-v2] reset `lastVisitedColumnIdx` if width change (#19757) fix(components): [table-v2] reset lastVisitedColumnIdx if width change * ci: fix corepack matching keyid error (#19783) * docs: [scrollbar] fix type error (#19697) * docs: [scrollbar] fix type error * refactor(docs): improve code structure and type annotations in examples * Update docs/examples/scrollbar/manual-scroll.vue Co-authored-by: btea <2356281422@qq.com> * fix(docs): replace lodash isNumber with typeof check * fix(docs): update --------- Co-authored-by: btea <2356281422@qq.com> * chore(components): [cascader-node] remove ts-nocheck and fix type error (#19776) * chore(components): [CascaderNode] remove ts-nocheck and fix type error * chore: format --------- Co-authored-by: warmthsea <2586244885@qq.com> * feat(locale): export Norsk(no) (#19747) feat(locale): export Norsk(no) Added Norwegian language reference Co-authored-by: btea <2356281422@qq.com> * feat(locale): export missing language (#19790) feat(locale): export missing locale * chore: Update changelog 2.9.4 (#19792) chore: update changelog 2.9.4 * docs: optimization API style (#19793) * docs: optimization API style * chore: Transfer * chore: update * fix: update * chore(components): [tree] remove ts-nocheck and fix type error (#19777) * chore(components): [tree] remove ts-nocheck and fix type error * refactor: refactor --------- Co-authored-by: btea <2356281422@qq.com> * chore: update doc (#19831) * fix(components): [message-box] init validator (#19832) * fix(components): [message-box] init validator * fix: update --------- Co-authored-by: xingyixiang <452282988@qq.com> * docs: [message-box] update options default value (#19833) * refactor(components): [menu] change to `script setup` writing and optimizing code (#19816) * refactor(components): [menu] refactor * Update packages/components/menu/src/menu-collapse-transition.vue * refactor(components): migrate ElMenuItem to Composition API * fix: update * chore: chore * refactor: refactor * revert: revert * refactor: refactor * revert: revert * fix: Expose * Update packages/components/menu/src/menu-item.vue Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> --------- Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * refactor: [menu] add necessary braces (#19840) * fix(components): [tree-select] dynamic bind class invalid (#19803) * test: [tree-select] dynamic class case (#19859) * chore: change create issue use (#19865) * feat(components): [dropdown] add `persistent` prop (#19797) * feat(components): add persistent attribute * Update docs/en-US/component/dropdown.md Co-authored-by: btea <2356281422@qq.com> * fix: docs --------- Co-authored-by: btea <2356281422@qq.com> * fix(components): [table] compatible with window non-existence (#19837) ElTable's doLayout method is debounced and scheduled (relying on setTimeout) which causes problems in testing(Vitest). Sometimes the testing environment(jsdom) is destroyed before doLayout() executes which causes error due to requestAnimationFrame not existing. To mitigate this issue can check if the window exists which is a good indication that jsdom has not been thorn down yet. * feat(components): [menu] add `persistent` prop (#19874) feat(components): [menu] add persistent prop * refactor: [time-picker] optimize type declaration (#19875) chore: [time-picker] optimize type declaration * fix(components): [select] solve memory leak (#19709) fix(components): solve memory leak Watching the value of an attribute of an option can lead to a memory leak closed #19680 Co-authored-by: 张东 <A80784@internet.com> * chore: [tree] export types (#19846) * chore: [tree] export type and fix the type error of the docs * revert: revert * revert: revert * feat(components): [cascader] add suggestion slot (#19866) * feat(components): [cascader] add suggestion-item slot * docs: add version to suggestion item slot demo Co-authored-by: btea <2356281422@qq.com> * Update docs/en-US/component/cascader.md --------- Co-authored-by: btea <2356281422@qq.com> * fix(components): [steps] update border-color to support safari (#19726) * fix(components): [description] tsx rendering functional component error (#19879) * fix(components): [description] tsx render * fix: update * fix: update * test: add test case * fix(components): [cascader] prevent default behavior when pressing a key to toggle suggestion list (#19897) fix(components): [cascader] suggestion key-down scroll warn * feat(components): [message-box] support custom close icon in message-box (#18168) * fix(components): [message-box] vue warning when closeIcon is component (#19901) * docs: [button] update default value and description (#19903) * fix(components): [select] ensure scrollbar syncs when scrolling to selected option (#19636) * fix: ensure scrollbar syncs when scrolling to selected option * feat: update scrollbar when drop-down menu is displayed * fix(components): [tree-select] search solve memory leak (#19895) * fix(components): [tree-select] search solve memory leak * feat: update * fix: test * chore: update test * feat(components): [slider] add `persistent` prop (#19889) * feat(components): [Slider] add persistent prop * fix(components): [slider] update persistent prop * fix(components): [slider] rename persistent prop to tooltipPersistent * Update docs/en-US/component/slider.md Co-authored-by: btea <2356281422@qq.com> * chore: formatted * fix(components): [slider] update description for persistent prop --------- Co-authored-by: btea <2356281422@qq.com> * docs(components): [dropdown] update description and example (#19908) docs(components): [dropdown]update description and example * docs(components): [tree] change `customized-node` example (#19907) * test: other branch commit pr.new * ci: update --------- Co-authored-by: ly-yewu <leiyu_yewu@cmss.chinamobile.com> Co-authored-by: leiyu <leiyu@cmss.chinamobile.com> Co-authored-by: btea <2356281422@qq.com> Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com> Co-authored-by: qiang <qw13131wang@gmail.com> Co-authored-by: Lo <l709937065@gmail.com> Co-authored-by: 0song <82012629+0song@users.noreply.github.com> Co-authored-by: Element <wallement@gmail.com> Co-authored-by: Liao-js <43257608+Liao-js@users.noreply.github.com> Co-authored-by: DDDDD12138 <43703884+DDDDD12138@users.noreply.github.com> Co-authored-by: steveWang13 <107922326+steveWang13@users.noreply.github.com> Co-authored-by: jiaxiang <zj.x9872@foxmail.com> Co-authored-by: 白雾三语 <32354856+baiwusanyu-c@users.noreply.github.com> Co-authored-by: baiwusanyu-c <chenzhihui@chabaidao.com> Co-authored-by: 晚风予星 <75473409+lxKylin@users.noreply.github.com> Co-authored-by: Meet you <wjp_github@163.com> Co-authored-by: xingyixiang <452282988@qq.com> Co-authored-by: changehu <814394170@qq.com> Co-authored-by: iamkun <kunhello@outlook.com> Co-authored-by: betavs <34408516+betavs@users.noreply.github.com> Co-authored-by: LAMMU <38106851+LAMMUpro@users.noreply.github.com> Co-authored-by: jiaxiang <zjx9987@gmail.com> Co-authored-by: baclona <853940223@qq.com> Co-authored-by: gongbei <gongbei@wps.cn> Co-authored-by: Mark J <markpro.code@gmail.com> Co-authored-by: Mouli Bheemaneti <57999522+moulibheemaneti@users.noreply.github.com> Co-authored-by: Jiankian <i@anline.cn> Co-authored-by: David Kitano <63226115+DavidKitano@users.noreply.github.com> Co-authored-by: Nick Wu <38874640+wNing50@users.noreply.github.com> Co-authored-by: smallbone <lue2048@163.com> Co-authored-by: Bruce Lu <smallbone.lu@gmail.com> Co-authored-by: 伊墨 <1905672206@qq.com> Co-authored-by: 知晓同丶 <zhixiaotong.me@qq.com> Co-authored-by: hanchao-c0ldwave <hanchao@cmss.chinamobile.com> Co-authored-by: coderchang <coderchang0105@gmail.com> Co-authored-by: pengpeng <30883395+webvs2@users.noreply.github.com> Co-authored-by: Delyan Haralanov <purepear@gmail.com> Co-authored-by: 锌小子 <2252647301@qq.com> Co-authored-by: 张东 <A80784@internet.com> Co-authored-by: DiamondYuan <541832074@qq.com> Co-authored-by: xion <65892539+xionkq@users.noreply.github.com> Co-authored-by: zhuft-moon <zhufengting_yewu@cmss.chinamobile.com> Co-authored-by: dengguangmiaoyyds <gujiao_yewu@cmss.chinamobile.com>
26 KiB
title, lang
| title | lang |
|---|---|
| Virtualized Table | en-US |
Virtualized Table ^(beta)
Along with evolutionary web development, table component has always been the most popular component in our web apps especially for dashboards, data analysis. For Table V1, with even just 1000 records of data, it can be very annoying when using it, because of the poor performance.
With Virtualized Table, you can render massive chunks of data in a blink of an eye.
:::tip
This component is still under testing, use at your own risk. If you find any bugs or issues, please report them at GitHub for us to fix. Also there were some APIs which are not mentioned in this documentation, some of them were not fully developed yet, which is why they are not mentioned here.
Even though Virtualized Table is efficient, when the data load is too large, your network and memory size can become the bottleneck of your app. So keep in mind that Virtualized Table is never the ultimate solution for everything, consider paginating your data, adding filters etc.
:::
Basic usage
Let's demonstrate the performance of the Virtualized Table by rendering a basic example with 10 columns and 1000 rows.
:::demo
table-v2/basic
:::
Auto resizer
When you do not want to manually pass the width and height properties to the table, you can wrap the table component with the AutoResizer.
This will automatically update the width and height for you.
Resize your browser to see how it works.
:::tip
Make sure the parent node of the AutoResizer HAS A FIXED HEIGHT, since its default height value is set to 100%.
Alternatively, you can define it by passing the style attribute to AutoResizer.
:::
:::demo
table-v2/auto-resizer
:::
Customize Cell Renderer
Of course, you can render the table cell according to your needs. Here's a simple example of how to customize your cell.
:::demo
table-v2/cell-templating
:::
Table with selections
Using customized cell renderer to allow selection for your table.
:::demo
table-v2/selection
:::
Inline editing
Just as we demonstrated with selections above, you can use the same method to enable inline editing.
:::demo
table-v2/inline-editing
:::
Table with status
You can highlight your table content to distinguish between "success, information, warning, danger" and other states.
To customize the appearance of rows, use the row-class-name attribute. For example, every 10th row is highlighted using the bg-blue-200 class, and every 5th row with the bg-red-100 class.
:::demo
table-v2/row-class
:::
Table with sticky rows
You can make some rows stick to the top of the table, and that can be very easily achieved by using the fixed-data attribute.
You can dynamically set the sticky row based on scroll events, as shown in this example.
:::demo
table-v2/sticky-rows
:::
Table with fixed columns
If you want to have columns stick to the left or right for some reason, you can achieve this by adding special attributes to the table.
You can set the column's attribute fixed to true (representing FixedDir.LEFT) or FixedDir.LEFT or FixedDir.RIGHT
:::demo
table-v2/fixed-columns
:::
Grouping header
By customizing your header renderer, you can group your header as shown in this example.
:::tip
In this case we used JSX feature which is not supported in the playground. You may try them out in your local environment or on online IDEs such as codesandbox.
It is recommended that you write your table component in JSX, since it contains VNode manipulations.
:::
:::demo
table-v2/grouping-header
:::
Filter
Virtualized Table provides custom header renderers for creating customized headers. We can then utilize these to render filters.
:::demo
table-v2/filter
:::
Sortable
You can sort the table with sort state.
:::demo
table-v2/sort
:::
Controlled Sort
You can define multiple sortable columns as needed. Keep in mind that if you define multiple sortable columns, the UI may appear confusing to your users, as it becomes unclear which column is currently being sorted.
:::demo
table-v2/controlled-sort
:::
Cross hovering
When dealing with a large list, it's easy to lose track of the current row and column you are visiting. In such cases, using this feature can be very helpful.
:::demo
table-v2/cross-hovering
:::
Colspan
The virtualized table doesn't use the built-in table element, so colspan and rowspan behave a bit differently compared to TableV1. However, with a customized row renderer, these features can still be implemented. In this section, we'll demonstrate how to achieve this.
:::demo
table-v2/colspan
:::
Rowspan
Since we have covered Colspan, it's worth noting that we also have row span. It's a little bit different from colspan but the idea is basically the same.
:::demo
table-v2/rowspan
:::
Rowspan and Colspan together
We can combine rowspan and colspan together to meet your business goal!
:::demo
table-v2/spans
:::
Tree data
Virtual Table can also render data in a tree-like structure. By clicking the arrow icon, you can expand or collapse the tree nodes.
:::demo
table-v2/tree-data
:::
Dynamic height rows
Virtual Table is capable of rendering rows with dynamic heights. If you're working with data and are uncertain about the content size,
this feature is ideal for rendering rows that adjust to the content's height. To enable this, pass down the estimated-row-height attribute.
The closer the estimated height matches the actual content, the smoother the rendering experience.
:::tip
Each row's height is dynamically measured during rendering the rows. As a result, if you're trying to display a large amount of data, the UI might be bouncing.
:::
:::demo
table-v2/dynamic-height
:::
Detail view
Using dynamic height rendering, you can also display a detailed view within the table.
:::demo
table-v2/detailed-view
:::
Customized Footer
Render a customized footer when you want to show a concluding message or information.
:::demo
table-v2/footer
:::
Customized Empty Renderer
Render a customized empty element.
:::demo
table-v2/empty
:::
Overlay
Render an overlay on top of the table when you want to show a loading indicator or something else.
:::demo
table-v2/overlay
:::
Manual scrolling
Use the methods provided by Table V2 to scroll manually/programmatically with desired offset/rows.
:::tip
The second parameter for scrollToRow is the scrolling strategy which by default is auto, it calculates the position
to scroll by itself. If you wish to scroll to a specific position, you can define the strategy yourself.
The available options are "auto" | "center" | "end" | "start" | "smart"
The difference between smart and auto is that auto is a subset of smart scroll strategy.
:::
:::demo
table-v2/manual-scroll
:::
TableV2 API
Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| cache | Number of rows rendered in advance to boost the performance | number |
2 |
| estimated-row-height | The estimated row height for rendering dynamic height rows | number |
— |
| header-class | Customized class name passed to header wrapper | string / Function<HeaderClassGetter> |
— |
| header-props | Customized props name passed to header component | object / Function<HeaderPropsGetter> |
— |
| header-cell-props | Customized props name passed to header cell component | object / Function<HeaderCellPropsGetter> |
— |
| header-height | The height of the header is set by height. If given an array, it renders header rows equal to its length |
number/ number[] |
50 |
| footer-height | The height of the footer element, when provided, will be part to the calculation of the table's height. | number |
0 |
| row-class | Customized class name passed to row wrapper | string / Function<RowClassGetter> |
— |
| row-key | The key of each row, if not provided, will be the index of the row | string / Symbol / number |
id |
| row-props | Customized props name passed to row component | object / Function<RowPropsGetter> |
— |
| row-height | The height of each row, used for calculating the total height of the table | number |
50 |
| cell-props | extra props passed to each cell (except header cells) | object / Function<CellPropsGetter> |
— |
| columns | An array of column definitions. | Column[] | — |
| data | An array of data to be rendered in the table. | Data[] | [] |
| data-getter | A method to customize data fetch from the data source. | Function<DataGetter<T>> | — |
| fixed-data | Data for rendering rows above the main content and below the header | object<Data> |
— |
| expand-column-key | The column key indicates which row is expandable | string |
— |
| expanded-row-keys | An array of keys for expanded rows, can be used with v-model |
KeyType[] | — |
| default-expanded-row-keys | An array of keys for default expanded rows, NON REACTIVE | KeyType[] | — |
| class | Class name for the virtual table, will be applied to all three tables (left, right, main) | string / array / object |
— |
| fixed | Flag indicates the table column's width to be fixed or flexible. | boolean |
false |
| width ^(required) | Width of the table | number |
— |
| height ^(required) | Height of the table | number |
— |
| max-height | Maximum height of the table | number |
— |
| indent-size | horizontal indentation of tree table | number |
12 |
| h-scrollbar-size | Indicates the horizontal scrollbar's size for the table, used to prevent the horizontal and vertical scrollbar to collapse | number |
6 |
| v-scrollbar-size | Indicates the vertical scrollbar's size for the table, used to prevent the horizontal and vertical scrollbar to collapse | number |
6 |
| scrollbar-always-on | If true, the scrollbar will always be shown instead of when mouse is placed above the table | boolean |
false |
| sort-by | Sort indicator | object<SortBy> |
{} |
| sort-state | Multiple sort indicator | object<SortState> |
undefined |
Slots
| Name | Params |
|---|---|
| cell | object<CellSlotProps> |
| header | object<HeaderSlotProps> |
| header-cell | object<HeaderCellSlotProps> |
| row | object<RowSlotProps> |
| footer | — |
| empty | — |
| overlay | — |
Events
| Name | Description | Parameters |
|---|---|---|
| column-sort | Invoked when column sorted | object<ColumnSortParam> |
| expanded-rows-change | Invoked when expanded rows changed | KeyType[] |
| end-reached | Invoked when the end of the table is reached | — |
| scroll | Invoked after scrolling | object<ScrollParams> |
| rows-rendered | Invoked when rows are rendered | object<RowsRenderedParams> |
| row-expand | Invoked when expand/collapse the tree node by clicking the arrow icon | object<RowExpandParams> |
| row-event-handlers | A collection of handlers attached to each row | object<RowEventHandlers> |
Methods
| Event Name | Description | Parameters |
|---|---|---|
| scrollTo | Scroll to a given position | ^[Function](param: {scrollLeft?: number, scrollTop?: number}) => void |
| scrollToLeft | Scroll to a given horizontal position | ^[Function](scrollLeft: number) => void |
| scrollToTop | Scroll to a given vertical position | ^[Function](scrollTop: number) => void |
| scrollToRow | scroll to a given row with specified scroll strategy | ^[Function](row: number, strategy?: 'center' | 'end' | 'start' | 'smart') => void |
:::tip
Note that these are JavaScript Objects, so you CANNOT USE kebab-case for these attributes
:::
Column API
Attribute
| Name | Description | Type | Default |
|---|---|---|---|
| align | Alignment of the table cell content | Alignment | left |
| class | Class name for the column | string |
— |
| key | Unique identification | KeyType | — |
| dataKey | Unique identification of data | KeyType | — |
| fixed | Fixed direction of the column | boolean / FixedDir |
false |
| flexGrow | CSSProperties flex grow, Only useful when this is not a fixed table | number |
0 |
| flexShrink | CSSProperties flex shrink, Only useful when this is not a fixed table | number |
1 |
| headerClass | Used for customizing header column class | string |
— |
| hidden | Whether the column is invisible | boolean |
— |
| style | Customized style for column cell, will be merged with grid cell | ^[object]CSSProperties |
— |
| sortable | Indicates whether the column is sortable | boolean |
— |
| title | The default text rendered in header cell | string |
— |
| maxWidth | Maximum width for the column | number |
— |
| minWidth | Minimum width for the column | number |
— |
| width ^(required) | Width for the column | number |
— |
| cellRenderer | Customized Cell renderer | VueComponent / (props: CellRenderProps) => VNode |
— |
| headerCellRenderer | Customized Header renderer | VueComponent / (props: HeaderRenderProps) => VNode |
— |
Type Declarations
Show Type Declarations
type HeaderClassGetter = (param: {
columns: Column<any>[]
headerIndex: number
}) => string
type HeaderPropsGetter = (param: {
columns: Column<any>[]
headerIndex: number
}) => Record<string, any>
type HeaderCellPropsGetter = (param: {
columns: Column<any>[]
column: Column<any>
columnIndex: number
headerIndex: number
style: CSSProperties
}) => Record<string, any>
type RowClassGetter = (param: {
columns: Column<any>[]
rowData: any
rowIndex: number
}) => string
type RowPropsGetter = (param: {
columns: Column<any>[]
rowData: any
rowIndex: number
}) => Record<string, any>
type CellPropsGetter = (param: {
column: Column<any>
columns: Column<any>[]
columnIndex: number
cellData: any
rowData: any
rowIndex: number
}) => void
type DataGetterParams<T> = {
columns: Column<T>[]
column: Column<T>
columnIndex: number
} & RowCommonParams
type DataGetter<T> = (params: DataGetterParams<T>) => T
type CellRenderProps<T> = {
cellData: T
column: Column<T>
columns: Column<T>[]
columnIndex: number
rowData: any
rowIndex: number
}
type HeaderRenderProps<T> = {
column: Column<T>
columns: Column<T>[]
columnIndex: number
headerIndex: number
}
type ScrollParams = {
xAxisScrollDir: 'forward' | 'backward'
scrollLeft: number
yAxisScrollDir: 'forward' | 'backward'
scrollTop: number
}
type CellSlotProps<T> = {
column: Column<T>
columns: Column<T>[]
columnIndex: number
depth: number
style: CSSProperties
rowData: any
rowIndex: number
isScrolling: boolean
expandIconProps?:
| {
rowData: any
rowIndex: number
onExpand: (expand: boolean) => void
}
| undefined
}
type HeaderSlotProps = {
cells: VNode[]
columns: Column<any>[]
headerIndex: number
}
type HeaderCellSlotProps = {
class: string
columns: Column<any>[]
column: Column<any>
columnIndex: number
headerIndex: number
style: CSSProperties
headerCellProps?: any
sortBy: SortBy
sortState?: SortState | undefined
onColumnSorted: (e: MouseEvent) => void
}
type RowCommonParams = {
rowData: any
rowIndex: number
}
type RowEventHandlerParams = {
rowKey: KeyType
event: Event
} & RowCommonParams
type RowEventHandler = (params: RowEventHandlerParams) => void
type RowEventHandlers = {
onClick?: RowEventHandler
onContextmenu?: RowEventHandler
onDblclick?: RowEventHandler
onMouseenter?: RowEventHandler
onMouseleave?: RowEventHandler
}
type RowsRenderedParams = {
rowCacheStart: number
rowCacheEnd: number
rowVisibleStart: number
rowVisibleEnd: number
}
type RowSlotProps = {
columns: Column<any>[]
rowData: any
columnIndex: number
rowIndex: number
data: any
key: number | string
isScrolling?: boolean
style: CSSProperties
}
type RowExpandParams = {
expanded: boolean
rowKey: KeyType
} & RowCommonParams
type Data = {
[key: KeyType]: any
children?: Array<any>
}
type FixedData = Data
type KeyType = string | number | symbol
type ColumnSortParam<T> = { column: Column<T>; key: KeyType; order: SortOrder }
enum SortOrder {
ASC = 'asc',
DESC = 'desc',
}
type SortBy = { key: KeyType; Order: SortOrder }
type SortState = Record<KeyType, SortOrder>
FAQs
How do I render a list with a checkbox in the first column?
Since you are allowed to define your own cell renderer, you can do what the example
Customize Cell Renderer did to render checkbox yourself, and maintain the
state by yourself.
Why does virtualized table provide less features than TableV1
For virtualized table, we intend to provide less feature and let our users implement their own features as needed. Integrating too many features makes the code hard to maintain and for most users the basic features are enough. Some key features were not developed yet. We would love to hear from you. Join Discord to stay tuned.