filter.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <template>
  2. <el-table-v2 fixed :columns="fixedColumns" :data="data" :width="700" :height="400" />
  3. </template>
  4. <script lang="tsx" setup>
  5. import { ref } from 'vue'
  6. import { ElButton, ElCheckbox, ElIcon, ElPopover, TableV2FixedDir } from 'element-plus'
  7. import { Filter } from '@element-plus/icons-vue'
  8. import type { HeaderCellSlotProps } from 'element-plus'
  9. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  10. Array.from({ length }).map((_, columnIndex) => ({
  11. ...props,
  12. key: `${prefix}${columnIndex}`,
  13. dataKey: `${prefix}${columnIndex}`,
  14. title: `Column ${columnIndex}`,
  15. width: 150,
  16. }))
  17. const generateData = (columns: ReturnType<typeof generateColumns>, length = 200, prefix = 'row-') =>
  18. Array.from({ length }).map((_, rowIndex) => {
  19. return columns.reduce(
  20. (rowData, column, columnIndex) => {
  21. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  22. return rowData
  23. },
  24. {
  25. id: `${prefix}${rowIndex}`,
  26. parentId: null,
  27. }
  28. )
  29. })
  30. const columns = generateColumns(10)
  31. const data = ref(generateData(columns, 200))
  32. const shouldFilter = ref(false)
  33. const popoverRef = ref()
  34. const onFilter = () => {
  35. popoverRef.value.hide()
  36. if (shouldFilter.value) {
  37. data.value = generateData(columns, 100, 'filtered-')
  38. } else {
  39. data.value = generateData(columns, 200)
  40. }
  41. }
  42. const onReset = () => {
  43. shouldFilter.value = false
  44. onFilter()
  45. }
  46. columns[0].headerCellRenderer = (props: HeaderCellSlotProps) => {
  47. return (
  48. <div class="flex items-center justify-center">
  49. <span class="mr-2 text-xs">{props.column.title}</span>
  50. <ElPopover ref={popoverRef} trigger="click" {...{ width: 200 }}>
  51. {{
  52. default: () => (
  53. <div class="filter-wrapper">
  54. <div class="filter-group">
  55. <ElCheckbox v-model={shouldFilter.value}>Filter Text</ElCheckbox>
  56. </div>
  57. <div class="el-table-v2__demo-filter">
  58. <ElButton text onClick={onFilter}>
  59. Confirm
  60. </ElButton>
  61. <ElButton text onClick={onReset}>
  62. Reset
  63. </ElButton>
  64. </div>
  65. </div>
  66. ),
  67. reference: () => (
  68. <ElIcon class="cursor-pointer">
  69. <Filter />
  70. </ElIcon>
  71. ),
  72. }}
  73. </ElPopover>
  74. </div>
  75. )
  76. }
  77. const fixedColumns = columns.map((column, columnIndex) => {
  78. let fixed: TableV2FixedDir | undefined = undefined
  79. if (columnIndex < 2) fixed = TableV2FixedDir.LEFT
  80. if (columnIndex > 9) fixed = TableV2FixedDir.RIGHT
  81. return { ...column, fixed, width: 100 }
  82. })
  83. </script>
  84. <style>
  85. .el-table-v2__demo-filter {
  86. border-top: var(--el-border);
  87. margin: 12px -12px -12px;
  88. padding: 0 12px;
  89. display: flex;
  90. justify-content: space-between;
  91. }
  92. </style>