Commit 125a7d14831642c9cbb2e4b3e75953c3b2e2cdef
1 parent
966571bd
feat(table): support columns-change event
添加列改变事件(含排序、可见性、固定列)。该事件仅由表格设置组件中人为触发。
Showing
8 changed files
with
91 additions
and
21 deletions
src/components/Table/src/BasicTable.vue
... | ... | @@ -32,13 +32,19 @@ |
32 | 32 | </div> |
33 | 33 | </template> |
34 | 34 | <script lang="ts"> |
35 | - import type { BasicTableProps, TableActionType, SizeType } from './types/table'; | |
35 | + import type { | |
36 | + BasicTableProps, | |
37 | + TableActionType, | |
38 | + SizeType, | |
39 | + ColumnChangeParam, | |
40 | + } from './types/table'; | |
36 | 41 | |
37 | 42 | import { defineComponent, ref, computed, unref, toRaw } from 'vue'; |
38 | 43 | import { Table } from 'ant-design-vue'; |
39 | 44 | import { BasicForm, useForm } from '/@/components/Form/index'; |
40 | 45 | import expandIcon from './components/ExpandIcon'; |
41 | 46 | import HeaderCell from './components/HeaderCell.vue'; |
47 | + import { InnerHandlers } from './types/table'; | |
42 | 48 | |
43 | 49 | import { usePagination } from './hooks/usePagination'; |
44 | 50 | import { useColumns } from './hooks/useColumns'; |
... | ... | @@ -83,6 +89,7 @@ |
83 | 89 | 'edit-change', |
84 | 90 | 'expanded-rows-change', |
85 | 91 | 'change', |
92 | + 'columns-change', | |
86 | 93 | ], |
87 | 94 | setup(props, { attrs, emit, slots }) { |
88 | 95 | const tableElRef = ref<ComponentRef>(null); |
... | ... | @@ -177,7 +184,15 @@ |
177 | 184 | |
178 | 185 | const { getExpandOption, expandAll, collapseAll } = useTableExpand(getProps, tableData, emit); |
179 | 186 | |
180 | - const { getHeaderProps } = useTableHeader(getProps, slots); | |
187 | + const handlers: InnerHandlers = { | |
188 | + onColumnsChange: (data: ColumnChangeParam[]) => { | |
189 | + emit('columns-change', data); | |
190 | + // support useTable | |
191 | + unref(getProps).onColumnsChange?.(data); | |
192 | + }, | |
193 | + }; | |
194 | + | |
195 | + const { getHeaderProps } = useTableHeader(getProps, slots, handlers); | |
181 | 196 | |
182 | 197 | const { getFooterProps } = useTableFooter( |
183 | 198 | getProps, | ... | ... |
src/components/Table/src/components/TableHeader.vue
... | ... | @@ -6,11 +6,15 @@ |
6 | 6 | <div :class="`${prefixCls}__toolbar`"> |
7 | 7 | <slot name="toolbar"></slot> |
8 | 8 | <Divider type="vertical" v-if="$slots.toolbar && showTableSetting" /> |
9 | - <TableSetting :setting="tableSetting" v-if="showTableSetting" /> | |
9 | + <TableSetting | |
10 | + :setting="tableSetting" | |
11 | + v-if="showTableSetting" | |
12 | + @columns-change="handleColumnChange" | |
13 | + /> | |
10 | 14 | </div> |
11 | 15 | </template> |
12 | 16 | <script lang="ts"> |
13 | - import type { TableSetting } from '../types/table'; | |
17 | + import type { TableSetting, ColumnChangeParam } from '../types/table'; | |
14 | 18 | import type { PropType } from 'vue'; |
15 | 19 | |
16 | 20 | import { defineComponent } from 'vue'; |
... | ... | @@ -42,9 +46,13 @@ |
42 | 46 | default: '', |
43 | 47 | }, |
44 | 48 | }, |
45 | - setup() { | |
49 | + emits: ['columns-change'], | |
50 | + setup(_, { emit }) { | |
46 | 51 | const { prefixCls } = useDesign('basic-table-header'); |
47 | - return { prefixCls }; | |
52 | + function handleColumnChange(data: ColumnChangeParam[]) { | |
53 | + emit('columns-change', data); | |
54 | + } | |
55 | + return { prefixCls, handleColumnChange }; | |
48 | 56 | }, |
49 | 57 | }); |
50 | 58 | </script> | ... | ... |
src/components/Table/src/components/settings/ColumnSetting.vue
... | ... | @@ -114,7 +114,7 @@ |
114 | 114 | import { getPopupContainer } from '/@/utils'; |
115 | 115 | import { omit } from 'lodash-es'; |
116 | 116 | |
117 | - import type { BasicColumn } from '../../types/table'; | |
117 | + import type { BasicColumn, ColumnChangeParam } from '../../types/table'; | |
118 | 118 | |
119 | 119 | interface State { |
120 | 120 | checkAll: boolean; |
... | ... | @@ -141,8 +141,9 @@ |
141 | 141 | Divider, |
142 | 142 | Icon, |
143 | 143 | }, |
144 | + emits: ['columns-change'], | |
144 | 145 | |
145 | - setup() { | |
146 | + setup(_, { emit }) { | |
146 | 147 | const { t } = useI18n(); |
147 | 148 | const table = useTableContext(); |
148 | 149 | |
... | ... | @@ -234,10 +235,10 @@ |
234 | 235 | const checkList = plainOptions.value.map((item) => item.value); |
235 | 236 | if (e.target.checked) { |
236 | 237 | state.checkedList = checkList; |
237 | - table.setColumns(checkList); | |
238 | + setColumns(checkList); | |
238 | 239 | } else { |
239 | 240 | state.checkedList = []; |
240 | - table.setColumns([]); | |
241 | + setColumns([]); | |
241 | 242 | } |
242 | 243 | } |
243 | 244 | |
... | ... | @@ -257,7 +258,7 @@ |
257 | 258 | checkedList.sort((prev, next) => { |
258 | 259 | return sortList.indexOf(prev) - sortList.indexOf(next); |
259 | 260 | }); |
260 | - table.setColumns(checkedList); | |
261 | + setColumns(checkedList); | |
261 | 262 | } |
262 | 263 | |
263 | 264 | // reset columns |
... | ... | @@ -266,7 +267,7 @@ |
266 | 267 | state.checkAll = true; |
267 | 268 | plainOptions.value = unref(cachePlainOptions); |
268 | 269 | plainSortOptions.value = unref(cachePlainOptions); |
269 | - table.setColumns(table.getCacheColumns()); | |
270 | + setColumns(table.getCacheColumns()); | |
270 | 271 | } |
271 | 272 | |
272 | 273 | // Open the pop-up window for drag and drop initialization |
... | ... | @@ -298,7 +299,7 @@ |
298 | 299 | |
299 | 300 | plainSortOptions.value = columns; |
300 | 301 | plainOptions.value = columns; |
301 | - table.setColumns(columns); | |
302 | + setColumns(columns); | |
302 | 303 | }, |
303 | 304 | }); |
304 | 305 | initSortable(); |
... | ... | @@ -335,7 +336,21 @@ |
335 | 336 | item.width = 100; |
336 | 337 | } |
337 | 338 | table.setCacheColumnsByField?.(item.dataIndex, { fixed: isFixed }); |
339 | + setColumns(columns); | |
340 | + } | |
341 | + | |
342 | + function setColumns(columns: BasicColumn[] | string[]) { | |
338 | 343 | table.setColumns(columns); |
344 | + const data: ColumnChangeParam[] = unref(plainOptions).map((col) => { | |
345 | + const visible = | |
346 | + columns.findIndex( | |
347 | + (c: BasicColumn | string) => | |
348 | + c === col.value || (typeof c !== 'string' && c.dataIndex === col.value) | |
349 | + ) !== -1; | |
350 | + return { dataIndex: col.value, fixed: col.fixed, visible }; | |
351 | + }); | |
352 | + | |
353 | + emit('columns-change', data); | |
339 | 354 | } |
340 | 355 | |
341 | 356 | return { | ... | ... |
src/components/Table/src/components/settings/index.vue
... | ... | @@ -2,13 +2,13 @@ |
2 | 2 | <div class="table-settings"> |
3 | 3 | <RedoSetting v-if="getSetting.redo" /> |
4 | 4 | <SizeSetting v-if="getSetting.size" /> |
5 | - <ColumnSetting v-if="getSetting.setting" /> | |
5 | + <ColumnSetting v-if="getSetting.setting" @columns-change="handleColumnChange" /> | |
6 | 6 | <FullScreenSetting v-if="getSetting.fullScreen" /> |
7 | 7 | </div> |
8 | 8 | </template> |
9 | 9 | <script lang="ts"> |
10 | 10 | import type { PropType } from 'vue'; |
11 | - import type { TableSetting } from '../../types/table'; | |
11 | + import type { TableSetting, ColumnChangeParam } from '../../types/table'; | |
12 | 12 | |
13 | 13 | import { defineComponent, computed } from 'vue'; |
14 | 14 | |
... | ... | @@ -33,7 +33,8 @@ |
33 | 33 | default: () => ({}), |
34 | 34 | }, |
35 | 35 | }, |
36 | - setup(props) { | |
36 | + emits: ['columns-change'], | |
37 | + setup(props, { emit }) { | |
37 | 38 | const { t } = useI18n(); |
38 | 39 | |
39 | 40 | const getSetting = computed((): TableSetting => { |
... | ... | @@ -46,7 +47,11 @@ |
46 | 47 | }; |
47 | 48 | }); |
48 | 49 | |
49 | - return { getSetting, t }; | |
50 | + function handleColumnChange(data: ColumnChangeParam[]) { | |
51 | + emit('columns-change', data); | |
52 | + } | |
53 | + | |
54 | + return { getSetting, t, handleColumnChange }; | |
50 | 55 | }, |
51 | 56 | }); |
52 | 57 | </script> | ... | ... |
src/components/Table/src/hooks/useTableHeader.ts
1 | 1 | import type { ComputedRef, Slots } from 'vue'; |
2 | -import type { BasicTableProps } from '../types/table'; | |
2 | +import type { BasicTableProps, InnerHandlers } from '../types/table'; | |
3 | 3 | |
4 | 4 | import { unref, computed, h } from 'vue'; |
5 | 5 | import TableHeader from '../components/TableHeader.vue'; |
... | ... | @@ -7,7 +7,11 @@ import TableHeader from '../components/TableHeader.vue'; |
7 | 7 | import { isString } from '/@/utils/is'; |
8 | 8 | import { getSlot } from '/@/utils/helper/tsxHelper'; |
9 | 9 | |
10 | -export function useTableHeader(propsRef: ComputedRef<BasicTableProps>, slots: Slots) { | |
10 | +export function useTableHeader( | |
11 | + propsRef: ComputedRef<BasicTableProps>, | |
12 | + slots: Slots, | |
13 | + handlers: InnerHandlers | |
14 | +) { | |
11 | 15 | const getHeaderProps = computed((): Recordable => { |
12 | 16 | const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(propsRef); |
13 | 17 | const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting; |
... | ... | @@ -26,6 +30,7 @@ export function useTableHeader(propsRef: ComputedRef<BasicTableProps>, slots: Sl |
26 | 30 | titleHelpMessage, |
27 | 31 | showTableSetting, |
28 | 32 | tableSetting, |
33 | + onColumnsChange: handlers.onColumnsChange, | |
29 | 34 | } as Recordable, |
30 | 35 | { |
31 | 36 | ...(slots.toolbar | ... | ... |
src/components/Table/src/types/table.ts
... | ... | @@ -381,6 +381,8 @@ export interface BasicTableProps<T = any> { |
381 | 381 | * @param expandedRows |
382 | 382 | */ |
383 | 383 | onExpandedRowsChange?: (expandedRows: string[] | number[]) => void; |
384 | + | |
385 | + onColumnsChange?: (data: ColumnChangeParam[]) => void; | |
384 | 386 | } |
385 | 387 | |
386 | 388 | export type CellFormat = |
... | ... | @@ -427,3 +429,13 @@ export interface BasicColumn extends ColumnProps { |
427 | 429 | // 业务控制是否显示 |
428 | 430 | ifShow?: boolean | ((column: BasicColumn) => boolean); |
429 | 431 | } |
432 | + | |
433 | +export type ColumnChangeParam = { | |
434 | + dataIndex: string; | |
435 | + fixed: boolean | 'left' | 'right' | undefined; | |
436 | + visible: boolean; | |
437 | +}; | |
438 | + | |
439 | +export interface InnerHandlers { | |
440 | + onColumnsChange: (data: ColumnChangeParam[]) => void; | |
441 | +} | ... | ... |
src/views/demo/table/Basic.vue
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | :bordered="border" |
12 | 12 | showTableSetting |
13 | 13 | :pagination="pagination" |
14 | + @columns-change="handleColumnChange" | |
14 | 15 | > |
15 | 16 | <template #toolbar> |
16 | 17 | <a-button type="primary" @click="toggleCanResize"> |
... | ... | @@ -29,7 +30,7 @@ |
29 | 30 | </template> |
30 | 31 | <script lang="ts"> |
31 | 32 | import { defineComponent, ref } from 'vue'; |
32 | - import { BasicTable } from '/@/components/Table'; | |
33 | + import { BasicTable, ColumnChangeParam } from '/@/components/Table'; | |
33 | 34 | import { getBasicColumns, getBasicData } from './tableData'; |
34 | 35 | |
35 | 36 | export default defineComponent({ |
... | ... | @@ -56,6 +57,11 @@ |
56 | 57 | function toggleBorder() { |
57 | 58 | border.value = !border.value; |
58 | 59 | } |
60 | + | |
61 | + function handleColumnChange(data: ColumnChangeParam[]) { | |
62 | + console.log('ColumnChanged', data); | |
63 | + } | |
64 | + | |
59 | 65 | return { |
60 | 66 | columns: getBasicColumns(), |
61 | 67 | data: getBasicData(), |
... | ... | @@ -68,6 +74,7 @@ |
68 | 74 | toggleLoading, |
69 | 75 | toggleBorder, |
70 | 76 | pagination, |
77 | + handleColumnChange, | |
71 | 78 | }; |
72 | 79 | }, |
73 | 80 | }); | ... | ... |
src/views/demo/table/UseTable.vue
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | </template> |
21 | 21 | <script lang="ts"> |
22 | 22 | import { defineComponent } from 'vue'; |
23 | - import { BasicTable, useTable } from '/@/components/Table'; | |
23 | + import { BasicTable, ColumnChangeParam, useTable } from '/@/components/Table'; | |
24 | 24 | import { getBasicColumns, getBasicShortColumns } from './tableData'; |
25 | 25 | import { useMessage } from '/@/hooks/web/useMessage'; |
26 | 26 | import { demoListApi } from '/@/api/demo/table'; |
... | ... | @@ -58,6 +58,9 @@ |
58 | 58 | rowSelection: { |
59 | 59 | type: 'checkbox', |
60 | 60 | }, |
61 | + onColumnsChange: (data: ColumnChangeParam[]) => { | |
62 | + console.log('ColumnsChanged', data); | |
63 | + }, | |
61 | 64 | }); |
62 | 65 | |
63 | 66 | function changeLoading() { | ... | ... |