@vue-ui-kit/ant 1.9.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/cjs/index.js +4 -1
  2. package/dist/declarations/antProxy.d.ts +58 -20
  3. package/dist/es/index.js +8857 -2969
  4. package/dist/index.d.ts +5 -6
  5. package/dist/packages/components/PCanvasGrid.vue.d.ts +2 -0
  6. package/dist/packages/components/PCanvasTable.vue.d.ts +134 -0
  7. package/dist/packages/components/PForm.vue.d.ts +8 -14
  8. package/dist/packages/components/PFormCol.vue.d.ts +8 -13
  9. package/dist/packages/components/PFormGroup.vue.d.ts +16 -16
  10. package/dist/packages/components/PGrid.vue.d.ts +7 -27
  11. package/dist/packages/components/PGroupBlock.vue.d.ts +5 -7
  12. package/dist/packages/components/PromisePicker.vue.d.ts +8 -43
  13. package/dist/packages/components/RenderEditCell.d.ts +10 -0
  14. package/dist/packages/renders/TableInput.vue.d.ts +7 -26
  15. package/dist/packages/store/renderStore.d.ts +10 -58
  16. package/dist/packages/utils/AFormatters.d.ts +3 -13
  17. package/dist/packages/utils/treeHelper.d.ts +7 -7
  18. package/dist/style.scss +59 -35
  19. package/package.json +2 -1
  20. package/src/declarations/antProxy.ts +78 -22
  21. package/src/index.ts +15 -2
  22. package/src/packages/components/PCanvasGrid.vue +6 -0
  23. package/src/packages/components/PCanvasTable.vue +286 -0
  24. package/src/packages/components/PForm.vue +5 -5
  25. package/src/packages/components/PFormGroup.vue +1 -1
  26. package/src/packages/components/PGrid.vue +10 -5
  27. package/src/packages/components/PGroupBlock.vue +1 -1
  28. package/src/packages/components/PromisePicker.vue +19 -29
  29. package/src/packages/components/RenderAntCell.tsx +2 -2
  30. package/src/packages/components/RenderAntItem.tsx +2 -2
  31. package/src/packages/components/RenderDefaultSlots.tsx +1 -1
  32. package/src/packages/components/RenderEditCell.tsx +36 -0
  33. package/src/packages/components/RenderItemSlots.tsx +1 -1
  34. package/src/packages/components/RenderTitleSlots.tsx +1 -1
  35. package/src/packages/renders/TableInput.vue +1 -1
  36. package/src/packages/store/renderStore.tsx +44 -18
  37. package/src/packages/styles/index.scss +59 -31
  38. package/src/packages/utils/AFormatters.ts +3 -3
package/dist/style.scss CHANGED
@@ -1,8 +1,4 @@
1
- // Variables inlined for npm distribution
2
- :root {
3
- --p-theme-bg: #fff;
4
- }
5
-
1
+ @use 'variables';
6
2
 
7
3
  .p-pane {
8
4
  background-color: var(--p-theme-bg);
@@ -104,9 +100,9 @@
104
100
  z-index: 4;
105
101
  }
106
102
  .p-error-hang-out {
107
- .ant-input-affix-wrapper-status-error:not(
108
- .ant-input-affix-wrapper-disabled
109
- ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
103
+ .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(
104
+ .ant-input-affix-wrapper-borderless
105
+ ).ant-input-affix-wrapper {
110
106
  border-color: #d9d9d9 !important;
111
107
 
112
108
  &:focus {
@@ -126,7 +122,9 @@
126
122
  transform: translateY(-10px);
127
123
  max-height: 0;
128
124
  overflow: hidden;
129
- transition: opacity 0.3s ease-out 0.3s, transform 0.3s ease-out 0.3s,
125
+ transition:
126
+ opacity 0.3s ease-out 0.3s,
127
+ transform 0.3s ease-out 0.3s,
130
128
  max-height 0.3s ease-out 0.3s;
131
129
  }
132
130
  .ant-form-item-has-error .ant-form-item-explain-error {
@@ -238,25 +236,25 @@
238
236
  }
239
237
  }
240
238
  }
241
- .p-error-group-tab{
242
- position:relative;
239
+ .p-error-group-tab {
240
+ position: relative;
243
241
  overflow: visible;
244
- color:#f5222d!important;
245
- &:after{
246
- content:'🏷️';
247
- position:absolute;
248
- top:-1em;
249
- right:0;
250
- width:1em;
251
- height:1em;
252
- font-size:0.8em;
242
+ color: #f5222d !important;
243
+ &:after {
244
+ content: '🏷️';
245
+ position: absolute;
246
+ top: -1em;
247
+ right: 0;
248
+ width: 1em;
249
+ height: 1em;
250
+ font-size: 0.8em;
253
251
  animation: heartbeat 2s infinite;
254
252
  }
255
253
  }
256
254
  .p-error-hang-out {
257
- .ant-input-affix-wrapper-status-error:not(
258
- .ant-input-affix-wrapper-disabled
259
- ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
255
+ .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(
256
+ .ant-input-affix-wrapper-borderless
257
+ ).ant-input-affix-wrapper {
260
258
  border-color: #d9d9d9 !important;
261
259
 
262
260
  &:focus {
@@ -276,6 +274,10 @@
276
274
  }
277
275
  //endregion
278
276
 
277
+ /* #region EVirtTable */
278
+
279
+ /* #endregion */
280
+
279
281
  @each $align in right center {
280
282
  /**/
281
283
  .p-content-align-#{$align}.ant-form-item .ant-form-item-control-input-content {
@@ -291,15 +293,37 @@
291
293
  }
292
294
 
293
295
  @keyframes heartbeat {
294
- 0% { transform: scale(1); }
295
- 6% { transform: scale(1.22); }
296
- 12% { transform: scale(1); }
297
- 18% { transform: scale(1.18); }
298
- 24% { transform: scale(1); }
299
- 48% { transform: scale(1); } // 长停顿
300
- 54% { transform: scale(1.22); }
301
- 60% { transform: scale(1); }
302
- 66% { transform: scale(1.18); }
303
- 72% { transform: scale(1); }
304
- 100% { transform: scale(1); } // 长停顿
305
- }
296
+ 0% {
297
+ transform: scale(1);
298
+ }
299
+ 6% {
300
+ transform: scale(1.22);
301
+ }
302
+ 12% {
303
+ transform: scale(1);
304
+ }
305
+ 18% {
306
+ transform: scale(1.18);
307
+ }
308
+ 24% {
309
+ transform: scale(1);
310
+ }
311
+ 48% {
312
+ transform: scale(1);
313
+ } // 长停顿
314
+ 54% {
315
+ transform: scale(1.22);
316
+ }
317
+ 60% {
318
+ transform: scale(1);
319
+ }
320
+ 66% {
321
+ transform: scale(1.18);
322
+ }
323
+ 72% {
324
+ transform: scale(1);
325
+ }
326
+ 100% {
327
+ transform: scale(1);
328
+ } // 长停顿
329
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "1.9.3",
3
+ "version": "2.0.0",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -48,6 +48,7 @@
48
48
  "email": "adoin@qq.com"
49
49
  },
50
50
  "dependencies": {
51
+ "e-virt-table": "^1.2.20",
51
52
  "uuid": "^10.0.0",
52
53
  "xe-utils": "^3.7.6"
53
54
  },
@@ -4,15 +4,17 @@ import { ColProps } from 'ant-design-vue/lib/grid/Col';
4
4
  import { FormProps } from 'ant-design-vue/lib/form/Form';
5
5
  import { TableColumnType, TableProps, TooltipProps } from 'ant-design-vue';
6
6
  import { ButtonType } from 'ant-design-vue/lib/button/buttonTypes';
7
+ import type { ConfigType, Column as EVirtColumn } from 'e-virt-table';
7
8
 
8
- export interface CellFuncArg<D = Recordable> {
9
+ export interface CellFuncArg<D extends Recordable = Recordable> {
9
10
  row: D;
10
- column: ColumnProps<D>;
11
+ column?: ColumnProps<D>;
11
12
  rowIndex: number;
12
13
  cellValue: any;
13
14
  }
14
-
15
- export interface ItemFuncArg<F = Recordable> {
15
+ export type FormatterFunc = (c: CellFuncArg, ...args: any[]) => any;
16
+ export type PFormatter = Record<string, FormatterFunc>;
17
+ export interface ItemFuncArg<F extends Recordable = Recordable> {
16
18
  data: F;
17
19
  field?: string;
18
20
  }
@@ -48,7 +50,7 @@ export interface TooltipConfig extends TooltipProps {
48
50
  title: TooltipProps['title'] | (() => any);
49
51
  }
50
52
 
51
- export interface PFormItemProps<F = Recordable> {
53
+ export interface PFormItemProps<F extends Recordable = Recordable> {
52
54
  field?: string;
53
55
  title?: string;
54
56
  span?: number;
@@ -72,23 +74,29 @@ export interface PFormItemProps<F = Recordable> {
72
74
  };
73
75
  }
74
76
 
75
- export interface PFormProps<F = Recordable> extends FormProps {
77
+ export interface PFormProps<F extends Recordable = Recordable> extends FormProps {
76
78
  items: PFormItemProps<F>[];
77
79
  customReset?: () => void;
78
80
  }
79
81
 
80
- export interface PBlockProps<F = Recordable> {
82
+ export interface PBlockProps<F extends Recordable = Recordable> {
81
83
  getFormSetting: (data: Partial<F>) => PFormProps<Partial<F>>;
82
84
  source: Partial<F>;
83
85
  }
84
86
 
85
- export interface PromisePickerProps<D = Recordable, F = Recordable> {
87
+ export interface PromisePickerProps<
88
+ D extends Recordable = Recordable,
89
+ F extends Recordable = Recordable,
90
+ > {
86
91
  gridSetting: PGridProps<D, F>;
87
92
  title?: string;
88
93
  width?: string | number;
94
+ multipleAllowEmpty?: boolean;
95
+ bodyStyle?: Recordable;
96
+ beforePick?: (rowOrRows: D | Array<D>) => Promise<void>;
89
97
  }
90
98
 
91
- export type GroupMenuItemHandler<F = Recordable> = ({
99
+ export type GroupMenuItemHandler<F extends Recordable = Recordable> = ({
92
100
  index,
93
101
  data,
94
102
  code,
@@ -98,14 +106,14 @@ export type GroupMenuItemHandler<F = Recordable> = ({
98
106
  data: Partial<F & { __index: number }>;
99
107
  }) => void;
100
108
 
101
- export interface GroupMenuItem<F = Recordable> {
109
+ export interface GroupMenuItem<F extends Recordable = Recordable> {
102
110
  content: string;
103
111
  icon?: string;
104
112
  code: string;
105
113
  visibleMethod?: ({ data, index }: { data: Partial<F>; index: number }) => boolean;
106
114
  }
107
115
 
108
- export interface PFormGroupProps<F = Recordable> {
116
+ export interface PFormGroupProps<F extends Recordable = Recordable> {
109
117
  getFormSetting: (data: Partial<F>) => PFormProps<Partial<F>>;
110
118
  title?: string;
111
119
  tabLabel?: string;
@@ -122,7 +130,8 @@ export interface PFormGroupProps<F = Recordable> {
122
130
  menuHandler?: GroupMenuItemHandler<F>;
123
131
  }
124
132
 
125
- export interface ColumnProps<D = Recordable> extends Omit<TableColumnType, 'slots'> {
133
+ export interface ColumnProps<D extends Recordable = Recordable>
134
+ extends Omit<TableColumnType, 'slots'> {
126
135
  field?: string;
127
136
  children?: ColumnProps<D>[];
128
137
  formatter?:
@@ -160,7 +169,7 @@ export interface ToolbarConfig {
160
169
  disabled?: boolean;
161
170
  }
162
171
 
163
- export interface ResponsePathConfig<D = Recordable> {
172
+ export interface ResponsePathConfig<D extends Recordable = Recordable> {
164
173
  /*非分页取值路径*/
165
174
  list?: string | ((res: Recordable) => D[]);
166
175
  /*分页取值路径*/
@@ -174,12 +183,12 @@ export interface ResponsePathConfig<D = Recordable> {
174
183
 
175
184
  export type HandlerMultiDel = (ids: Array<string | number>) => any;
176
185
 
177
- export interface AjaxConfig<F = Recordable> {
186
+ export interface AjaxConfig<F extends Recordable = Recordable> {
178
187
  query: (Q: { page?: IPage; form: Partial<F> }) => Promise<Recordable>;
179
188
  multiDelete?: HandlerMultiDel;
180
189
  }
181
190
 
182
- export interface ProxyConfig<D = Recordable, F = Recordable> {
191
+ export interface ProxyConfig<D extends Recordable = Recordable, F extends Recordable = Recordable> {
183
192
  // 结果集 取值路径
184
193
  response?: ResponsePathConfig<D>;
185
194
  ajax: AjaxConfig<F>;
@@ -188,15 +197,17 @@ export interface ProxyConfig<D = Recordable, F = Recordable> {
188
197
  export interface PageConfig {
189
198
  pageSizes?: number[];
190
199
  pageSize?: number;
200
+ showSizeChanger?: boolean;
201
+ showQuickJumper?: boolean;
191
202
  }
192
203
 
193
- export interface SelectConfig<D = Recordable> {
204
+ export interface SelectConfig<D extends Recordable = Recordable> {
194
205
  multiple?: boolean;
195
206
  showCount?: boolean;
196
207
  getCheckboxProps?: (record: D) => { disabled?: boolean };
197
208
  }
198
209
 
199
- export type PGridProps<D = Recordable, F = Recordable> = {
210
+ export type PGridProps<D extends Recordable = Recordable, F extends Recordable = Recordable> = {
200
211
  selectConfig?: SelectConfig<D>;
201
212
  rowKey?: string;
202
213
  manualFetch?: boolean;
@@ -262,20 +273,65 @@ export interface RenderOptions {
262
273
  handleDelayTrigger?: (cusFields?: string | string[], time?: number) => void;
263
274
  }
264
275
 
265
- export interface RenderFormParams<F = Recordable> {
276
+ export interface RenderFormParams<F extends Recordable = Recordable> {
266
277
  data: F;
267
278
  field?: string;
268
279
  }
269
280
 
270
- export interface RenderTableParams<D = Recordable> {
281
+ export interface RenderTableParams<D extends Recordable = Recordable> {
271
282
  data?: D[];
272
283
  row: D;
273
284
  rowIndex?: number;
274
285
  field?: string;
275
286
  title?: string;
276
287
  }
277
-
278
- export interface PGridInstance<D = Recordable, F = Recordable> {
288
+ export interface CanvasColumnProps<T extends Recordable = Recordable>
289
+ extends Omit<EVirtColumn, 'children' | 'formatter' | 'key'> {
290
+ key?: string;
291
+ field?: string;
292
+ children?: CanvasColumnProps<T>[];
293
+ formatter?:
294
+ | string
295
+ | [string, ...Array<any>]
296
+ | ((arg: PartialByKeys<CellFuncArg<T>, 'cellValue'>) => any);
297
+ slots?: {
298
+ default?: ({
299
+ row,
300
+ column,
301
+ rowIndex,
302
+ }: {
303
+ row: T;
304
+ column: CanvasColumnProps<T>;
305
+ rowIndex: number;
306
+ }) => any;
307
+ edit?: ({
308
+ row,
309
+ column,
310
+ rowIndex,
311
+ }: {
312
+ row: T;
313
+ column: CanvasColumnProps<T>;
314
+ rowIndex: number;
315
+ }) => any;
316
+ title?: ({ column }: { column: CanvasColumnProps<T> }) => any;
317
+ };
318
+ cellRender?: CellRender;
319
+ editRender?: CellRender;
320
+ }
321
+ export interface CanvasTableProps<
322
+ T extends Recordable = Recordable,
323
+ B extends Recordable = Recordable,
324
+ > {
325
+ columns: CanvasColumnProps<T>[];
326
+ data: T[];
327
+ config: ConfigType;
328
+ footerData?: B[];
329
+ loading?: boolean;
330
+ }
331
+ export interface PGridInstance<
332
+ D extends Recordable = Recordable,
333
+ F extends Recordable = Recordable,
334
+ > {
279
335
  commitProxy: {
280
336
  query: () => Promise<D[]>;
281
337
  reload: () => Promise<D[]>;
@@ -297,7 +353,7 @@ export interface PFormInstance {
297
353
  $form: Recordable;
298
354
  }
299
355
 
300
- export interface PromisePickerInstance<D = Recordable> {
356
+ export interface PromisePickerInstance<D extends Recordable = Recordable> {
301
357
  pick: () => Promise<{ row: D; field?: string }>;
302
358
  pickMultiple: () => Promise<D[]>;
303
359
  grid: PGridInstance<D>;
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { App } from 'vue';
2
2
  import PForm from '@/components/PForm.vue';
3
3
  import PGrid from '@/components/PGrid.vue';
4
+ import PCanvasTable from '@/components/PCanvasTable.vue';
5
+ import PCanvasGrid from '@/components/PCanvasGrid.vue';
4
6
  import PFormGroup from '@/components/PFormGroup.vue';
5
7
  import PGroupBlock from '@/components/PGroupBlock.vue';
6
8
  import PromisePicker from '@/components/PromisePicker.vue';
@@ -19,7 +21,8 @@ export default {
19
21
  install(app: App) {
20
22
  app.component('PForm', PForm);
21
23
  app.component('PGrid', PGrid);
22
- // @ts-ignore
24
+ app.component('PCanvasTable', PCanvasTable);
25
+ app.component('PCanvasGrid', PCanvasGrid);
23
26
  app.component('PFormGroup', PFormGroup);
24
27
  app.component('PGroupBlock', PGroupBlock);
25
28
  app.component('PromisePicker', PromisePicker);
@@ -37,4 +40,14 @@ export * from '@/utils/core';
37
40
  export { setup, setUIKitConfig, getUIKitConfig, resetUIKitConfig, type UIKitConfig };
38
41
 
39
42
  // 直接导出组件,使用户可以直接导入使用
40
- export { PForm, PGrid, PFormGroup, PGroupBlock, PromisePicker, addFormatter, addRender };
43
+ export {
44
+ PForm,
45
+ PGrid,
46
+ PCanvasTable,
47
+ PCanvasGrid,
48
+ PFormGroup,
49
+ PGroupBlock,
50
+ PromisePicker,
51
+ addFormatter,
52
+ addRender,
53
+ };
@@ -0,0 +1,6 @@
1
+ <script lang="ts" setup>
2
+ import PCanvasTable from './PCanvasTable.vue';
3
+ </script>
4
+ <template>
5
+ <div>todo</div>
6
+ </template>
@@ -0,0 +1,286 @@
1
+ <script
2
+ lang="ts"
3
+ setup
4
+ generic="T extends Recordable = Recordable, B extends Recordable = Recordable"
5
+ >
6
+ import Cell from 'e-virt-table/dist/lib/Cell';
7
+ import type CellType from 'e-virt-table/dist/lib/Cell';
8
+ import EVirtTable from 'e-virt-table';
9
+ import type {
10
+ Column as EVirtColumn,
11
+ CellParams,
12
+ OverlayerContainer,
13
+ FormatterMethod,
14
+ } from 'e-virt-table';
15
+ import { ref, onMounted, computed, useAttrs, watch } from 'vue';
16
+ import { EventCallback } from 'e-virt-table/dist/lib/EventBus';
17
+ import { isArray, isEqual, isFunction, isString, omit } from 'xe-utils';
18
+ import renderStore from '@/store/renderStore';
19
+ import RenderEditCell from './RenderEditCell';
20
+ import type { CanvasColumnProps, CanvasTableProps, FormatterFunc, CellRender } from '#/antProxy';
21
+ import { v4 as uuidv4 } from 'uuid';
22
+ import { antFormatters } from '@/utils/AFormatters';
23
+
24
+ const emit = defineEmits<{
25
+ (e: 'change', value: any[]): void; // 需要默认实现change,不能动态绑定
26
+ (e: 'ready', value: EVirtTable): void;
27
+ }>();
28
+ const defaultConfig = {
29
+ DISABLED: true,
30
+ };
31
+ const props = defineProps<CanvasTableProps<T, B>>();
32
+ let eVirtTable: EVirtTable | null = null;
33
+ const attrs = useAttrs();
34
+ const eVirtTableRef = ref(null);
35
+ const eVirtTableEditorRef = ref(null);
36
+ const eVirtTableEmptyRef = ref(null);
37
+ const eVirtTableOverlayerRef = ref(null);
38
+ const editorCell = ref<Cell>();
39
+ const editorType = ref<string>('text');
40
+ const overlayerView = ref<OverlayerContainer>();
41
+ const cacheEditorSlotColumns: Record<string, CanvasColumnProps<T>> = {};
42
+ const cacheEditorRenders: Record<string, CellRender> = {};
43
+ // 编辑器样式
44
+ const editorStyle = computed(() => {
45
+ const cell = editorCell.value;
46
+ if (!cell) {
47
+ return {};
48
+ }
49
+ return {
50
+ width: `${cell.width}px`,
51
+ height: `${cell.height}px`,
52
+ };
53
+ });
54
+ const getFormatter = (name: string) => antFormatters[name] || (({ cellValue }) => cellValue);
55
+ const getCellRender = (name: string) => renderStore.renders[name]?.renderDefault;
56
+ const transferFormatter =
57
+ (formatter: FormatterFunc, ...restArgs: any[]): FormatterMethod =>
58
+ ({ row, rowIndex, value }) =>
59
+ formatter(
60
+ {
61
+ row,
62
+ rowIndex,
63
+ cellValue: value,
64
+ },
65
+ ...restArgs,
66
+ );
67
+ // 将复杂的三元运算符拆分成函数
68
+ const getRenderFunction = (column: CanvasColumnProps<T>) => {
69
+ if (column.slots?.default && isFunction(column.slots?.default)) {
70
+ return (cell: CellParams) =>
71
+ column.slots?.default?.({
72
+ row: cell.row,
73
+ column: column,
74
+ rowIndex: cell.rowIndex,
75
+ });
76
+ }
77
+
78
+ if (column.slots?.default && isString(column.slots?.default)) {
79
+ return `slot:${column.slots?.default}`;
80
+ }
81
+
82
+ if (column.cellRender && column.cellRender.name) {
83
+ return (cell: CellParams) =>
84
+ getCellRender(column.cellRender!.name)?.(
85
+ column.cellRender!,
86
+ {
87
+ data: props.data,
88
+ row: cell.row,
89
+ rowIndex: cell.rowIndex,
90
+ field: column.field || cell.column.key,
91
+ title: cell.column?.title ?? '',
92
+ },
93
+ {},
94
+ );
95
+ }
96
+
97
+ return undefined;
98
+ };
99
+ const parseToEVirtColumn = (column: CanvasColumnProps<T>): EVirtColumn => {
100
+ if (column.slots?.edit && (column.field || column.key) && isFunction(column.slots?.edit)) {
101
+ cacheEditorSlotColumns[`__slot:${column.field || column.key}`] = column;
102
+ } else if (column.editRender?.name && (column.field || column.key)) {
103
+ cacheEditorRenders[column.field! || column.key!] = column.editRender;
104
+ }
105
+ return {
106
+ ...omit(column, ['formatter']),
107
+ key: column.key || column.field || uuidv4(),
108
+ formatter: isString(column.formatter)
109
+ ? transferFormatter(getFormatter(column.formatter as string))
110
+ : isArray(column.formatter) && isString(column.formatter[0])
111
+ ? transferFormatter(getFormatter(column.formatter[0]), ...column.formatter.slice(1))
112
+ : isFunction(column.formatter)
113
+ ? transferFormatter(column.formatter as FormatterFunc)
114
+ : undefined,
115
+ editorType:
116
+ column.editorType ??
117
+ (column.slots?.edit && (column.field || column.key) && isFunction(column.slots?.edit)
118
+ ? `__slot:${column.field || column.key}`
119
+ : column.editRender?.name
120
+ ? column.editRender.name
121
+ : undefined),
122
+ render: getRenderFunction(column),
123
+ children: column.children?.map((child) => parseToEVirtColumn(child)),
124
+ };
125
+ };
126
+ onMounted(() => {
127
+ if (!eVirtTableRef.value) {
128
+ return;
129
+ }
130
+ eVirtTable = new EVirtTable(eVirtTableRef.value, {
131
+ config: {
132
+ ...defaultConfig,
133
+ ...props.config,
134
+ },
135
+ columns: props.columns.map((col) => parseToEVirtColumn(col)),
136
+ data: props.data,
137
+ emptyElement: eVirtTableEmptyRef.value || undefined,
138
+ overlayerElement: eVirtTableOverlayerRef.value || undefined,
139
+ editorElement: eVirtTableEditorRef.value || undefined,
140
+ });
141
+ // 动态绑定事件
142
+ Object.keys(attrs).forEach((key) => {
143
+ const func = attrs[key];
144
+ if (typeof func === 'function' && key.startsWith('on')) {
145
+ const _eventName = key.charAt(2).toLowerCase() + key.slice(3); // 去掉 'on' 前缀 只将 'on' 后第一个字母转换为小写
146
+ eVirtTable?.on(_eventName, func as EventCallback);
147
+ }
148
+ });
149
+ eVirtTable.on('change', (value) => {
150
+ emit('change', value);
151
+ });
152
+ eVirtTable.on('overlayerChange', (overlayer: OverlayerContainer) => {
153
+ overlayerView.value = overlayer;
154
+ });
155
+ eVirtTable.on('startEdit', (cell) => {
156
+ editorCell.value = cell;
157
+ editorType.value = cell.editorType;
158
+ // 内部已经处理了文本类型的编辑
159
+ if (editorType.value === 'text') {
160
+ return;
161
+ }
162
+ });
163
+ eVirtTable.on('doneEdit', () => {
164
+ editorType.value = 'text';
165
+ });
166
+ emit('ready', eVirtTable);
167
+ });
168
+ function saveCellValue(value) {
169
+ if (!eVirtTable || !editorCell.value) {
170
+ return;
171
+ }
172
+ const { rowKey, key } = editorCell.value;
173
+ eVirtTable?.setItemValueByEditor(rowKey, key, value);
174
+ }
175
+ watch(
176
+ props.data,
177
+ (newValue) => {
178
+ eVirtTable?.loadData(newValue);
179
+ },
180
+ { deep: true },
181
+ );
182
+ watch(
183
+ () => props.columns,
184
+ (newValue, oldValue) => {
185
+ if (!isEqual(newValue, oldValue)) {
186
+ eVirtTable?.loadColumns(newValue.map((col) => parseToEVirtColumn(col)));
187
+ }
188
+ },
189
+ { deep: true },
190
+ );
191
+ watch(
192
+ () => props.config,
193
+ (newValue) => {
194
+ eVirtTable?.loadConfig(newValue);
195
+ },
196
+ { deep: true },
197
+ );
198
+ watch(
199
+ () => props.footerData,
200
+ (newValue) => {
201
+ eVirtTable?.loadFooterData(newValue || []);
202
+ },
203
+ { deep: true },
204
+ );
205
+ const getPopupContainer = () => {
206
+ return document.body;
207
+ };
208
+ </script>
209
+ <template>
210
+ <a-spin :spinning="loading">
211
+ <div ref="eVirtTableRef">
212
+ <div ref="eVirtTableEditorRef">
213
+ <!-- 插槽编辑器 -->
214
+ <component
215
+ v-if="editorType.startsWith('__slot:')"
216
+ :is="
217
+ cacheEditorSlotColumns[editorType]!.slots!.edit!({
218
+ row: editorCell!.row,
219
+ column: cacheEditorSlotColumns[editorType],
220
+ rowIndex: editorCell!.rowIndex,
221
+ })
222
+ "
223
+ :bordered="false"
224
+ :style="editorStyle"
225
+ class="ev-editor-wrapper"
226
+ :get-popup-container="getPopupContainer"
227
+ v-model:value="editorCell!.value"
228
+ :cell="editorCell"
229
+ @blur="saveCellValue"
230
+ >
231
+ </component>
232
+ <!-- 自定义编辑器 -->
233
+ <render-edit-cell
234
+ v-else-if="renderStore.renders[editorType]?.renderEdit"
235
+ :cell-render="cacheEditorRenders[editorCell!.key]"
236
+ class="ev-editor-wrapper"
237
+ :style="editorStyle"
238
+ :render-table-params="{
239
+ data: props.data,
240
+ row: editorCell?.row,
241
+ rowIndex: editorCell?.rowIndex ?? -1,
242
+ field: editorCell?.key ?? '',
243
+ title: editorCell?.column?.title ?? '',
244
+ }"
245
+ :bordered="false"
246
+ :get-popup-container="getPopupContainer"
247
+ @blur="saveCellValue"
248
+ />
249
+ </div>
250
+ <div ref="eVirtTableEmptyRef">
251
+ <slot name="empty">
252
+ <!-- 自定义空数据 -->
253
+ <a-empty description="空数据" />
254
+ </slot>
255
+ </div>
256
+ <div ref="eVirtTableOverlayerRef">
257
+ <!-- 自定覆盖层 -->
258
+ <div
259
+ :class="wrapper.class"
260
+ v-for="wrapper in overlayerView?.views || []"
261
+ :style="wrapper.style"
262
+ :key="wrapper.type"
263
+ >
264
+ <div :style="view.style" v-for="view in wrapper.views" :key="view.key">
265
+ <div
266
+ class="cell"
267
+ v-for="cell in view.cells"
268
+ :key="`${cell.rowKey}_${cell.key}`"
269
+ :style="cell.style"
270
+ >
271
+ <component
272
+ v-if="typeof cell.render === 'function'"
273
+ :is="cell.render(cell)"
274
+ ></component>
275
+ <template
276
+ v-else-if="typeof cell.render === 'string' && cell.render.startsWith('slot:')"
277
+ >
278
+ <slot :name="cell.render.replace('slot:', '')" v-bind="cell" :cell="cell"></slot>
279
+ </template>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+ </a-spin>
286
+ </template>