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,13 +32,19 @@ | ||
32 | </div> | 32 | </div> |
33 | </template> | 33 | </template> |
34 | <script lang="ts"> | 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 | import { defineComponent, ref, computed, unref, toRaw } from 'vue'; | 42 | import { defineComponent, ref, computed, unref, toRaw } from 'vue'; |
38 | import { Table } from 'ant-design-vue'; | 43 | import { Table } from 'ant-design-vue'; |
39 | import { BasicForm, useForm } from '/@/components/Form/index'; | 44 | import { BasicForm, useForm } from '/@/components/Form/index'; |
40 | import expandIcon from './components/ExpandIcon'; | 45 | import expandIcon from './components/ExpandIcon'; |
41 | import HeaderCell from './components/HeaderCell.vue'; | 46 | import HeaderCell from './components/HeaderCell.vue'; |
47 | + import { InnerHandlers } from './types/table'; | ||
42 | 48 | ||
43 | import { usePagination } from './hooks/usePagination'; | 49 | import { usePagination } from './hooks/usePagination'; |
44 | import { useColumns } from './hooks/useColumns'; | 50 | import { useColumns } from './hooks/useColumns'; |
@@ -83,6 +89,7 @@ | @@ -83,6 +89,7 @@ | ||
83 | 'edit-change', | 89 | 'edit-change', |
84 | 'expanded-rows-change', | 90 | 'expanded-rows-change', |
85 | 'change', | 91 | 'change', |
92 | + 'columns-change', | ||
86 | ], | 93 | ], |
87 | setup(props, { attrs, emit, slots }) { | 94 | setup(props, { attrs, emit, slots }) { |
88 | const tableElRef = ref<ComponentRef>(null); | 95 | const tableElRef = ref<ComponentRef>(null); |
@@ -177,7 +184,15 @@ | @@ -177,7 +184,15 @@ | ||
177 | 184 | ||
178 | const { getExpandOption, expandAll, collapseAll } = useTableExpand(getProps, tableData, emit); | 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 | const { getFooterProps } = useTableFooter( | 197 | const { getFooterProps } = useTableFooter( |
183 | getProps, | 198 | getProps, |
src/components/Table/src/components/TableHeader.vue
@@ -6,11 +6,15 @@ | @@ -6,11 +6,15 @@ | ||
6 | <div :class="`${prefixCls}__toolbar`"> | 6 | <div :class="`${prefixCls}__toolbar`"> |
7 | <slot name="toolbar"></slot> | 7 | <slot name="toolbar"></slot> |
8 | <Divider type="vertical" v-if="$slots.toolbar && showTableSetting" /> | 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 | </div> | 14 | </div> |
11 | </template> | 15 | </template> |
12 | <script lang="ts"> | 16 | <script lang="ts"> |
13 | - import type { TableSetting } from '../types/table'; | 17 | + import type { TableSetting, ColumnChangeParam } from '../types/table'; |
14 | import type { PropType } from 'vue'; | 18 | import type { PropType } from 'vue'; |
15 | 19 | ||
16 | import { defineComponent } from 'vue'; | 20 | import { defineComponent } from 'vue'; |
@@ -42,9 +46,13 @@ | @@ -42,9 +46,13 @@ | ||
42 | default: '', | 46 | default: '', |
43 | }, | 47 | }, |
44 | }, | 48 | }, |
45 | - setup() { | 49 | + emits: ['columns-change'], |
50 | + setup(_, { emit }) { | ||
46 | const { prefixCls } = useDesign('basic-table-header'); | 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 | </script> | 58 | </script> |
src/components/Table/src/components/settings/ColumnSetting.vue
@@ -114,7 +114,7 @@ | @@ -114,7 +114,7 @@ | ||
114 | import { getPopupContainer } from '/@/utils'; | 114 | import { getPopupContainer } from '/@/utils'; |
115 | import { omit } from 'lodash-es'; | 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 | interface State { | 119 | interface State { |
120 | checkAll: boolean; | 120 | checkAll: boolean; |
@@ -141,8 +141,9 @@ | @@ -141,8 +141,9 @@ | ||
141 | Divider, | 141 | Divider, |
142 | Icon, | 142 | Icon, |
143 | }, | 143 | }, |
144 | + emits: ['columns-change'], | ||
144 | 145 | ||
145 | - setup() { | 146 | + setup(_, { emit }) { |
146 | const { t } = useI18n(); | 147 | const { t } = useI18n(); |
147 | const table = useTableContext(); | 148 | const table = useTableContext(); |
148 | 149 | ||
@@ -234,10 +235,10 @@ | @@ -234,10 +235,10 @@ | ||
234 | const checkList = plainOptions.value.map((item) => item.value); | 235 | const checkList = plainOptions.value.map((item) => item.value); |
235 | if (e.target.checked) { | 236 | if (e.target.checked) { |
236 | state.checkedList = checkList; | 237 | state.checkedList = checkList; |
237 | - table.setColumns(checkList); | 238 | + setColumns(checkList); |
238 | } else { | 239 | } else { |
239 | state.checkedList = []; | 240 | state.checkedList = []; |
240 | - table.setColumns([]); | 241 | + setColumns([]); |
241 | } | 242 | } |
242 | } | 243 | } |
243 | 244 | ||
@@ -257,7 +258,7 @@ | @@ -257,7 +258,7 @@ | ||
257 | checkedList.sort((prev, next) => { | 258 | checkedList.sort((prev, next) => { |
258 | return sortList.indexOf(prev) - sortList.indexOf(next); | 259 | return sortList.indexOf(prev) - sortList.indexOf(next); |
259 | }); | 260 | }); |
260 | - table.setColumns(checkedList); | 261 | + setColumns(checkedList); |
261 | } | 262 | } |
262 | 263 | ||
263 | // reset columns | 264 | // reset columns |
@@ -266,7 +267,7 @@ | @@ -266,7 +267,7 @@ | ||
266 | state.checkAll = true; | 267 | state.checkAll = true; |
267 | plainOptions.value = unref(cachePlainOptions); | 268 | plainOptions.value = unref(cachePlainOptions); |
268 | plainSortOptions.value = unref(cachePlainOptions); | 269 | plainSortOptions.value = unref(cachePlainOptions); |
269 | - table.setColumns(table.getCacheColumns()); | 270 | + setColumns(table.getCacheColumns()); |
270 | } | 271 | } |
271 | 272 | ||
272 | // Open the pop-up window for drag and drop initialization | 273 | // Open the pop-up window for drag and drop initialization |
@@ -298,7 +299,7 @@ | @@ -298,7 +299,7 @@ | ||
298 | 299 | ||
299 | plainSortOptions.value = columns; | 300 | plainSortOptions.value = columns; |
300 | plainOptions.value = columns; | 301 | plainOptions.value = columns; |
301 | - table.setColumns(columns); | 302 | + setColumns(columns); |
302 | }, | 303 | }, |
303 | }); | 304 | }); |
304 | initSortable(); | 305 | initSortable(); |
@@ -335,7 +336,21 @@ | @@ -335,7 +336,21 @@ | ||
335 | item.width = 100; | 336 | item.width = 100; |
336 | } | 337 | } |
337 | table.setCacheColumnsByField?.(item.dataIndex, { fixed: isFixed }); | 338 | table.setCacheColumnsByField?.(item.dataIndex, { fixed: isFixed }); |
339 | + setColumns(columns); | ||
340 | + } | ||
341 | + | ||
342 | + function setColumns(columns: BasicColumn[] | string[]) { | ||
338 | table.setColumns(columns); | 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 | return { | 356 | return { |
src/components/Table/src/components/settings/index.vue
@@ -2,13 +2,13 @@ | @@ -2,13 +2,13 @@ | ||
2 | <div class="table-settings"> | 2 | <div class="table-settings"> |
3 | <RedoSetting v-if="getSetting.redo" /> | 3 | <RedoSetting v-if="getSetting.redo" /> |
4 | <SizeSetting v-if="getSetting.size" /> | 4 | <SizeSetting v-if="getSetting.size" /> |
5 | - <ColumnSetting v-if="getSetting.setting" /> | 5 | + <ColumnSetting v-if="getSetting.setting" @columns-change="handleColumnChange" /> |
6 | <FullScreenSetting v-if="getSetting.fullScreen" /> | 6 | <FullScreenSetting v-if="getSetting.fullScreen" /> |
7 | </div> | 7 | </div> |
8 | </template> | 8 | </template> |
9 | <script lang="ts"> | 9 | <script lang="ts"> |
10 | import type { PropType } from 'vue'; | 10 | import type { PropType } from 'vue'; |
11 | - import type { TableSetting } from '../../types/table'; | 11 | + import type { TableSetting, ColumnChangeParam } from '../../types/table'; |
12 | 12 | ||
13 | import { defineComponent, computed } from 'vue'; | 13 | import { defineComponent, computed } from 'vue'; |
14 | 14 | ||
@@ -33,7 +33,8 @@ | @@ -33,7 +33,8 @@ | ||
33 | default: () => ({}), | 33 | default: () => ({}), |
34 | }, | 34 | }, |
35 | }, | 35 | }, |
36 | - setup(props) { | 36 | + emits: ['columns-change'], |
37 | + setup(props, { emit }) { | ||
37 | const { t } = useI18n(); | 38 | const { t } = useI18n(); |
38 | 39 | ||
39 | const getSetting = computed((): TableSetting => { | 40 | const getSetting = computed((): TableSetting => { |
@@ -46,7 +47,11 @@ | @@ -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 | </script> | 57 | </script> |
src/components/Table/src/hooks/useTableHeader.ts
1 | import type { ComputedRef, Slots } from 'vue'; | 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 | import { unref, computed, h } from 'vue'; | 4 | import { unref, computed, h } from 'vue'; |
5 | import TableHeader from '../components/TableHeader.vue'; | 5 | import TableHeader from '../components/TableHeader.vue'; |
@@ -7,7 +7,11 @@ import TableHeader from '../components/TableHeader.vue'; | @@ -7,7 +7,11 @@ import TableHeader from '../components/TableHeader.vue'; | ||
7 | import { isString } from '/@/utils/is'; | 7 | import { isString } from '/@/utils/is'; |
8 | import { getSlot } from '/@/utils/helper/tsxHelper'; | 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 | const getHeaderProps = computed((): Recordable => { | 15 | const getHeaderProps = computed((): Recordable => { |
12 | const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(propsRef); | 16 | const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(propsRef); |
13 | const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting; | 17 | const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting; |
@@ -26,6 +30,7 @@ export function useTableHeader(propsRef: ComputedRef<BasicTableProps>, slots: Sl | @@ -26,6 +30,7 @@ export function useTableHeader(propsRef: ComputedRef<BasicTableProps>, slots: Sl | ||
26 | titleHelpMessage, | 30 | titleHelpMessage, |
27 | showTableSetting, | 31 | showTableSetting, |
28 | tableSetting, | 32 | tableSetting, |
33 | + onColumnsChange: handlers.onColumnsChange, | ||
29 | } as Recordable, | 34 | } as Recordable, |
30 | { | 35 | { |
31 | ...(slots.toolbar | 36 | ...(slots.toolbar |
src/components/Table/src/types/table.ts
@@ -381,6 +381,8 @@ export interface BasicTableProps<T = any> { | @@ -381,6 +381,8 @@ export interface BasicTableProps<T = any> { | ||
381 | * @param expandedRows | 381 | * @param expandedRows |
382 | */ | 382 | */ |
383 | onExpandedRowsChange?: (expandedRows: string[] | number[]) => void; | 383 | onExpandedRowsChange?: (expandedRows: string[] | number[]) => void; |
384 | + | ||
385 | + onColumnsChange?: (data: ColumnChangeParam[]) => void; | ||
384 | } | 386 | } |
385 | 387 | ||
386 | export type CellFormat = | 388 | export type CellFormat = |
@@ -427,3 +429,13 @@ export interface BasicColumn extends ColumnProps { | @@ -427,3 +429,13 @@ export interface BasicColumn extends ColumnProps { | ||
427 | // 业务控制是否显示 | 429 | // 业务控制是否显示 |
428 | ifShow?: boolean | ((column: BasicColumn) => boolean); | 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,6 +11,7 @@ | ||
11 | :bordered="border" | 11 | :bordered="border" |
12 | showTableSetting | 12 | showTableSetting |
13 | :pagination="pagination" | 13 | :pagination="pagination" |
14 | + @columns-change="handleColumnChange" | ||
14 | > | 15 | > |
15 | <template #toolbar> | 16 | <template #toolbar> |
16 | <a-button type="primary" @click="toggleCanResize"> | 17 | <a-button type="primary" @click="toggleCanResize"> |
@@ -29,7 +30,7 @@ | @@ -29,7 +30,7 @@ | ||
29 | </template> | 30 | </template> |
30 | <script lang="ts"> | 31 | <script lang="ts"> |
31 | import { defineComponent, ref } from 'vue'; | 32 | import { defineComponent, ref } from 'vue'; |
32 | - import { BasicTable } from '/@/components/Table'; | 33 | + import { BasicTable, ColumnChangeParam } from '/@/components/Table'; |
33 | import { getBasicColumns, getBasicData } from './tableData'; | 34 | import { getBasicColumns, getBasicData } from './tableData'; |
34 | 35 | ||
35 | export default defineComponent({ | 36 | export default defineComponent({ |
@@ -56,6 +57,11 @@ | @@ -56,6 +57,11 @@ | ||
56 | function toggleBorder() { | 57 | function toggleBorder() { |
57 | border.value = !border.value; | 58 | border.value = !border.value; |
58 | } | 59 | } |
60 | + | ||
61 | + function handleColumnChange(data: ColumnChangeParam[]) { | ||
62 | + console.log('ColumnChanged', data); | ||
63 | + } | ||
64 | + | ||
59 | return { | 65 | return { |
60 | columns: getBasicColumns(), | 66 | columns: getBasicColumns(), |
61 | data: getBasicData(), | 67 | data: getBasicData(), |
@@ -68,6 +74,7 @@ | @@ -68,6 +74,7 @@ | ||
68 | toggleLoading, | 74 | toggleLoading, |
69 | toggleBorder, | 75 | toggleBorder, |
70 | pagination, | 76 | pagination, |
77 | + handleColumnChange, | ||
71 | }; | 78 | }; |
72 | }, | 79 | }, |
73 | }); | 80 | }); |
src/views/demo/table/UseTable.vue
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | </template> | 20 | </template> |
21 | <script lang="ts"> | 21 | <script lang="ts"> |
22 | import { defineComponent } from 'vue'; | 22 | import { defineComponent } from 'vue'; |
23 | - import { BasicTable, useTable } from '/@/components/Table'; | 23 | + import { BasicTable, ColumnChangeParam, useTable } from '/@/components/Table'; |
24 | import { getBasicColumns, getBasicShortColumns } from './tableData'; | 24 | import { getBasicColumns, getBasicShortColumns } from './tableData'; |
25 | import { useMessage } from '/@/hooks/web/useMessage'; | 25 | import { useMessage } from '/@/hooks/web/useMessage'; |
26 | import { demoListApi } from '/@/api/demo/table'; | 26 | import { demoListApi } from '/@/api/demo/table'; |
@@ -58,6 +58,9 @@ | @@ -58,6 +58,9 @@ | ||
58 | rowSelection: { | 58 | rowSelection: { |
59 | type: 'checkbox', | 59 | type: 'checkbox', |
60 | }, | 60 | }, |
61 | + onColumnsChange: (data: ColumnChangeParam[]) => { | ||
62 | + console.log('ColumnsChanged', data); | ||
63 | + }, | ||
61 | }); | 64 | }); |
62 | 65 | ||
63 | function changeLoading() { | 66 | function changeLoading() { |