Commit 125a7d14831642c9cbb2e4b3e75953c3b2e2cdef

Authored by 无木
1 parent 966571bd

feat(table): support columns-change event

添加列改变事件(含排序、可见性、固定列)。该事件仅由表格设置组件中人为触发。
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 &#39;../components/TableHeader.vue&#39;;
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&lt;BasicTableProps&gt;, 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&lt;T = any&gt; {
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() {
... ...