@vue-ui-kit/ant 1.9.4 → 2.0.1
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.
- package/dist/cjs/index.js +4 -1
- package/dist/declarations/antProxy.d.ts +55 -20
- package/dist/es/index.js +8888 -2987
- package/dist/index.d.ts +5 -6
- package/dist/packages/components/PCanvasGrid.vue.d.ts +2 -0
- package/dist/packages/components/PCanvasTable.vue.d.ts +136 -0
- package/dist/packages/components/PForm.vue.d.ts +8 -14
- package/dist/packages/components/PFormCol.vue.d.ts +8 -13
- package/dist/packages/components/PFormGroup.vue.d.ts +16 -16
- package/dist/packages/components/PGrid.vue.d.ts +7 -27
- package/dist/packages/components/PGroupBlock.vue.d.ts +5 -7
- package/dist/packages/components/PromisePicker.vue.d.ts +5 -7
- package/dist/packages/components/RenderEditCell.d.ts +10 -0
- package/dist/packages/renders/TableInput.vue.d.ts +7 -26
- package/dist/packages/store/renderStore.d.ts +10 -58
- package/dist/packages/utils/AFormatters.d.ts +3 -13
- package/dist/packages/utils/treeHelper.d.ts +7 -7
- package/dist/style.scss +58 -30
- package/package.json +2 -1
- package/src/declarations/antProxy.ts +75 -22
- package/src/index.ts +15 -2
- package/src/packages/components/PCanvasGrid.vue +6 -0
- package/src/packages/components/PCanvasTable.vue +292 -0
- package/src/packages/components/PForm.vue +5 -5
- package/src/packages/components/PFormGroup.vue +1 -1
- package/src/packages/components/PGrid.vue +10 -5
- package/src/packages/components/PGroupBlock.vue +1 -1
- package/src/packages/components/PromisePicker.vue +6 -1
- package/src/packages/components/RenderAntCell.tsx +2 -2
- package/src/packages/components/RenderAntItem.tsx +2 -2
- package/src/packages/components/RenderDefaultSlots.tsx +1 -1
- package/src/packages/components/RenderEditCell.tsx +36 -0
- package/src/packages/components/RenderItemSlots.tsx +1 -1
- package/src/packages/components/RenderTitleSlots.tsx +1 -1
- package/src/packages/renders/TableInput.vue +1 -1
- package/src/packages/store/renderStore.tsx +44 -18
- package/src/packages/styles/index.scss +59 -31
- package/src/packages/utils/AFormatters.ts +3 -3
package/dist/style.scss
CHANGED
|
@@ -104,9 +104,9 @@
|
|
|
104
104
|
z-index: 4;
|
|
105
105
|
}
|
|
106
106
|
.p-error-hang-out {
|
|
107
|
-
.ant-input-affix-wrapper-status-error:not(
|
|
108
|
-
.ant-input-affix-wrapper-
|
|
109
|
-
)
|
|
107
|
+
.ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(
|
|
108
|
+
.ant-input-affix-wrapper-borderless
|
|
109
|
+
).ant-input-affix-wrapper {
|
|
110
110
|
border-color: #d9d9d9 !important;
|
|
111
111
|
|
|
112
112
|
&:focus {
|
|
@@ -126,7 +126,9 @@
|
|
|
126
126
|
transform: translateY(-10px);
|
|
127
127
|
max-height: 0;
|
|
128
128
|
overflow: hidden;
|
|
129
|
-
transition:
|
|
129
|
+
transition:
|
|
130
|
+
opacity 0.3s ease-out 0.3s,
|
|
131
|
+
transform 0.3s ease-out 0.3s,
|
|
130
132
|
max-height 0.3s ease-out 0.3s;
|
|
131
133
|
}
|
|
132
134
|
.ant-form-item-has-error .ant-form-item-explain-error {
|
|
@@ -238,25 +240,25 @@
|
|
|
238
240
|
}
|
|
239
241
|
}
|
|
240
242
|
}
|
|
241
|
-
.p-error-group-tab{
|
|
242
|
-
position:relative;
|
|
243
|
+
.p-error-group-tab {
|
|
244
|
+
position: relative;
|
|
243
245
|
overflow: visible;
|
|
244
|
-
color
|
|
245
|
-
&:after{
|
|
246
|
-
content:'🏷️';
|
|
247
|
-
position:absolute;
|
|
248
|
-
top
|
|
249
|
-
right:0;
|
|
250
|
-
width:1em;
|
|
251
|
-
height:1em;
|
|
252
|
-
font-size:0.8em;
|
|
246
|
+
color: #f5222d !important;
|
|
247
|
+
&:after {
|
|
248
|
+
content: '🏷️';
|
|
249
|
+
position: absolute;
|
|
250
|
+
top: -1em;
|
|
251
|
+
right: 0;
|
|
252
|
+
width: 1em;
|
|
253
|
+
height: 1em;
|
|
254
|
+
font-size: 0.8em;
|
|
253
255
|
animation: heartbeat 2s infinite;
|
|
254
256
|
}
|
|
255
257
|
}
|
|
256
258
|
.p-error-hang-out {
|
|
257
|
-
.ant-input-affix-wrapper-status-error:not(
|
|
258
|
-
.ant-input-affix-wrapper-
|
|
259
|
-
)
|
|
259
|
+
.ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(
|
|
260
|
+
.ant-input-affix-wrapper-borderless
|
|
261
|
+
).ant-input-affix-wrapper {
|
|
260
262
|
border-color: #d9d9d9 !important;
|
|
261
263
|
|
|
262
264
|
&:focus {
|
|
@@ -276,6 +278,10 @@
|
|
|
276
278
|
}
|
|
277
279
|
//endregion
|
|
278
280
|
|
|
281
|
+
/* #region EVirtTable */
|
|
282
|
+
|
|
283
|
+
/* #endregion */
|
|
284
|
+
|
|
279
285
|
@each $align in right center {
|
|
280
286
|
/**/
|
|
281
287
|
.p-content-align-#{$align}.ant-form-item .ant-form-item-control-input-content {
|
|
@@ -291,15 +297,37 @@
|
|
|
291
297
|
}
|
|
292
298
|
|
|
293
299
|
@keyframes heartbeat {
|
|
294
|
-
0%
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
300
|
+
0% {
|
|
301
|
+
transform: scale(1);
|
|
302
|
+
}
|
|
303
|
+
6% {
|
|
304
|
+
transform: scale(1.22);
|
|
305
|
+
}
|
|
306
|
+
12% {
|
|
307
|
+
transform: scale(1);
|
|
308
|
+
}
|
|
309
|
+
18% {
|
|
310
|
+
transform: scale(1.18);
|
|
311
|
+
}
|
|
312
|
+
24% {
|
|
313
|
+
transform: scale(1);
|
|
314
|
+
}
|
|
315
|
+
48% {
|
|
316
|
+
transform: scale(1);
|
|
317
|
+
} // 长停顿
|
|
318
|
+
54% {
|
|
319
|
+
transform: scale(1.22);
|
|
320
|
+
}
|
|
321
|
+
60% {
|
|
322
|
+
transform: scale(1);
|
|
323
|
+
}
|
|
324
|
+
66% {
|
|
325
|
+
transform: scale(1.18);
|
|
326
|
+
}
|
|
327
|
+
72% {
|
|
328
|
+
transform: scale(1);
|
|
329
|
+
}
|
|
330
|
+
100% {
|
|
331
|
+
transform: scale(1);
|
|
332
|
+
} // 长停顿
|
|
333
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue-ui-kit/ant",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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
|
|
11
|
+
column?: ColumnProps<D>;
|
|
11
12
|
rowIndex: number;
|
|
12
13
|
cellValue: any;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
export
|
|
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,17 +74,20 @@ 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<
|
|
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;
|
|
@@ -91,7 +96,7 @@ export interface PromisePickerProps<D = Recordable, F = Recordable> {
|
|
|
91
96
|
beforePick?: (rowOrRows: D | Array<D>) => Promise<void>;
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
export type GroupMenuItemHandler<F = Recordable> = ({
|
|
99
|
+
export type GroupMenuItemHandler<F extends Recordable = Recordable> = ({
|
|
95
100
|
index,
|
|
96
101
|
data,
|
|
97
102
|
code,
|
|
@@ -101,14 +106,14 @@ export type GroupMenuItemHandler<F = Recordable> = ({
|
|
|
101
106
|
data: Partial<F & { __index: number }>;
|
|
102
107
|
}) => void;
|
|
103
108
|
|
|
104
|
-
export interface GroupMenuItem<F = Recordable> {
|
|
109
|
+
export interface GroupMenuItem<F extends Recordable = Recordable> {
|
|
105
110
|
content: string;
|
|
106
111
|
icon?: string;
|
|
107
112
|
code: string;
|
|
108
113
|
visibleMethod?: ({ data, index }: { data: Partial<F>; index: number }) => boolean;
|
|
109
114
|
}
|
|
110
115
|
|
|
111
|
-
export interface PFormGroupProps<F = Recordable> {
|
|
116
|
+
export interface PFormGroupProps<F extends Recordable = Recordable> {
|
|
112
117
|
getFormSetting: (data: Partial<F>) => PFormProps<Partial<F>>;
|
|
113
118
|
title?: string;
|
|
114
119
|
tabLabel?: string;
|
|
@@ -125,7 +130,8 @@ export interface PFormGroupProps<F = Recordable> {
|
|
|
125
130
|
menuHandler?: GroupMenuItemHandler<F>;
|
|
126
131
|
}
|
|
127
132
|
|
|
128
|
-
export interface ColumnProps<D
|
|
133
|
+
export interface ColumnProps<D extends Recordable = Recordable>
|
|
134
|
+
extends Omit<TableColumnType, 'slots'> {
|
|
129
135
|
field?: string;
|
|
130
136
|
children?: ColumnProps<D>[];
|
|
131
137
|
formatter?:
|
|
@@ -163,7 +169,7 @@ export interface ToolbarConfig {
|
|
|
163
169
|
disabled?: boolean;
|
|
164
170
|
}
|
|
165
171
|
|
|
166
|
-
export interface ResponsePathConfig<D = Recordable> {
|
|
172
|
+
export interface ResponsePathConfig<D extends Recordable = Recordable> {
|
|
167
173
|
/*非分页取值路径*/
|
|
168
174
|
list?: string | ((res: Recordable) => D[]);
|
|
169
175
|
/*分页取值路径*/
|
|
@@ -177,12 +183,12 @@ export interface ResponsePathConfig<D = Recordable> {
|
|
|
177
183
|
|
|
178
184
|
export type HandlerMultiDel = (ids: Array<string | number>) => any;
|
|
179
185
|
|
|
180
|
-
export interface AjaxConfig<F = Recordable> {
|
|
186
|
+
export interface AjaxConfig<F extends Recordable = Recordable> {
|
|
181
187
|
query: (Q: { page?: IPage; form: Partial<F> }) => Promise<Recordable>;
|
|
182
188
|
multiDelete?: HandlerMultiDel;
|
|
183
189
|
}
|
|
184
190
|
|
|
185
|
-
export interface ProxyConfig<D = Recordable, F = Recordable> {
|
|
191
|
+
export interface ProxyConfig<D extends Recordable = Recordable, F extends Recordable = Recordable> {
|
|
186
192
|
// 结果集 取值路径
|
|
187
193
|
response?: ResponsePathConfig<D>;
|
|
188
194
|
ajax: AjaxConfig<F>;
|
|
@@ -191,15 +197,17 @@ export interface ProxyConfig<D = Recordable, F = Recordable> {
|
|
|
191
197
|
export interface PageConfig {
|
|
192
198
|
pageSizes?: number[];
|
|
193
199
|
pageSize?: number;
|
|
200
|
+
showSizeChanger?: boolean;
|
|
201
|
+
showQuickJumper?: boolean;
|
|
194
202
|
}
|
|
195
203
|
|
|
196
|
-
export interface SelectConfig<D = Recordable> {
|
|
204
|
+
export interface SelectConfig<D extends Recordable = Recordable> {
|
|
197
205
|
multiple?: boolean;
|
|
198
206
|
showCount?: boolean;
|
|
199
207
|
getCheckboxProps?: (record: D) => { disabled?: boolean };
|
|
200
208
|
}
|
|
201
209
|
|
|
202
|
-
export type PGridProps<D = Recordable, F = Recordable> = {
|
|
210
|
+
export type PGridProps<D extends Recordable = Recordable, F extends Recordable = Recordable> = {
|
|
203
211
|
selectConfig?: SelectConfig<D>;
|
|
204
212
|
rowKey?: string;
|
|
205
213
|
manualFetch?: boolean;
|
|
@@ -265,20 +273,65 @@ export interface RenderOptions {
|
|
|
265
273
|
handleDelayTrigger?: (cusFields?: string | string[], time?: number) => void;
|
|
266
274
|
}
|
|
267
275
|
|
|
268
|
-
export interface RenderFormParams<F = Recordable> {
|
|
276
|
+
export interface RenderFormParams<F extends Recordable = Recordable> {
|
|
269
277
|
data: F;
|
|
270
278
|
field?: string;
|
|
271
279
|
}
|
|
272
280
|
|
|
273
|
-
export interface RenderTableParams<D = Recordable> {
|
|
281
|
+
export interface RenderTableParams<D extends Recordable = Recordable> {
|
|
274
282
|
data?: D[];
|
|
275
283
|
row: D;
|
|
276
284
|
rowIndex?: number;
|
|
277
285
|
field?: string;
|
|
278
286
|
title?: string;
|
|
279
287
|
}
|
|
280
|
-
|
|
281
|
-
|
|
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
|
+
> {
|
|
282
335
|
commitProxy: {
|
|
283
336
|
query: () => Promise<D[]>;
|
|
284
337
|
reload: () => Promise<D[]>;
|
|
@@ -300,7 +353,7 @@ export interface PFormInstance {
|
|
|
300
353
|
$form: Recordable;
|
|
301
354
|
}
|
|
302
355
|
|
|
303
|
-
export interface PromisePickerInstance<D = Recordable> {
|
|
356
|
+
export interface PromisePickerInstance<D extends Recordable = Recordable> {
|
|
304
357
|
pick: () => Promise<{ row: D; field?: string }>;
|
|
305
358
|
pickMultiple: () => Promise<D[]>;
|
|
306
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
|
-
|
|
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 {
|
|
43
|
+
export {
|
|
44
|
+
PForm,
|
|
45
|
+
PGrid,
|
|
46
|
+
PCanvasTable,
|
|
47
|
+
PCanvasGrid,
|
|
48
|
+
PFormGroup,
|
|
49
|
+
PGroupBlock,
|
|
50
|
+
PromisePicker,
|
|
51
|
+
addFormatter,
|
|
52
|
+
addRender,
|
|
53
|
+
};
|
|
@@ -0,0 +1,292 @@
|
|
|
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
|
+
eVirtTable.on('selectionChange', (selection) => {
|
|
167
|
+
console.log('selection', selection);
|
|
168
|
+
});
|
|
169
|
+
emit('ready', eVirtTable);
|
|
170
|
+
});
|
|
171
|
+
function saveCellValue(value) {
|
|
172
|
+
if (!eVirtTable || !editorCell.value) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const { rowKey, key } = editorCell.value;
|
|
176
|
+
eVirtTable?.setItemValueByEditor(rowKey, key, value);
|
|
177
|
+
}
|
|
178
|
+
const getPopupContainer = () => {
|
|
179
|
+
return document.body;
|
|
180
|
+
};
|
|
181
|
+
watch(
|
|
182
|
+
props.data,
|
|
183
|
+
(newValue) => {
|
|
184
|
+
eVirtTable?.loadData(newValue);
|
|
185
|
+
},
|
|
186
|
+
{ deep: true },
|
|
187
|
+
);
|
|
188
|
+
watch(
|
|
189
|
+
() => props.columns,
|
|
190
|
+
(newValue, oldValue) => {
|
|
191
|
+
if (!isEqual(newValue, oldValue)) {
|
|
192
|
+
eVirtTable?.loadColumns(newValue.map((col) => parseToEVirtColumn(col)));
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{ deep: true },
|
|
196
|
+
);
|
|
197
|
+
watch(
|
|
198
|
+
() => props.config,
|
|
199
|
+
(newValue) => {
|
|
200
|
+
eVirtTable?.loadConfig(newValue);
|
|
201
|
+
},
|
|
202
|
+
{ deep: true },
|
|
203
|
+
);
|
|
204
|
+
watch(
|
|
205
|
+
() => props.footerData,
|
|
206
|
+
(newValue) => {
|
|
207
|
+
eVirtTable?.loadFooterData(newValue || []);
|
|
208
|
+
},
|
|
209
|
+
{ deep: true },
|
|
210
|
+
);
|
|
211
|
+
defineExpose({
|
|
212
|
+
$table: eVirtTable,
|
|
213
|
+
});
|
|
214
|
+
</script>
|
|
215
|
+
<template>
|
|
216
|
+
<a-spin :spinning="loading">
|
|
217
|
+
<div ref="eVirtTableRef">
|
|
218
|
+
<div ref="eVirtTableEditorRef">
|
|
219
|
+
<!-- 插槽编辑器 -->
|
|
220
|
+
<component
|
|
221
|
+
v-if="editorType.startsWith('__slot:')"
|
|
222
|
+
:is="
|
|
223
|
+
cacheEditorSlotColumns[editorType]!.slots!.edit!({
|
|
224
|
+
row: editorCell!.row,
|
|
225
|
+
column: cacheEditorSlotColumns[editorType],
|
|
226
|
+
rowIndex: editorCell!.rowIndex,
|
|
227
|
+
})
|
|
228
|
+
"
|
|
229
|
+
:bordered="false"
|
|
230
|
+
:style="editorStyle"
|
|
231
|
+
class="ev-editor-wrapper"
|
|
232
|
+
:get-popup-container="getPopupContainer"
|
|
233
|
+
v-model:value="editorCell!.value"
|
|
234
|
+
:cell="editorCell"
|
|
235
|
+
@blur="saveCellValue"
|
|
236
|
+
>
|
|
237
|
+
</component>
|
|
238
|
+
<!-- 自定义编辑器 -->
|
|
239
|
+
<render-edit-cell
|
|
240
|
+
v-else-if="renderStore.renders[editorType]?.renderEdit"
|
|
241
|
+
:cell-render="cacheEditorRenders[editorCell!.key]"
|
|
242
|
+
class="ev-editor-wrapper"
|
|
243
|
+
:style="editorStyle"
|
|
244
|
+
:render-table-params="{
|
|
245
|
+
data: props.data,
|
|
246
|
+
row: editorCell?.row,
|
|
247
|
+
rowIndex: editorCell?.rowIndex ?? -1,
|
|
248
|
+
field: editorCell?.key ?? '',
|
|
249
|
+
title: editorCell?.column?.title ?? '',
|
|
250
|
+
}"
|
|
251
|
+
:bordered="false"
|
|
252
|
+
:get-popup-container="getPopupContainer"
|
|
253
|
+
@blur="saveCellValue"
|
|
254
|
+
/>
|
|
255
|
+
</div>
|
|
256
|
+
<div ref="eVirtTableEmptyRef">
|
|
257
|
+
<slot name="empty">
|
|
258
|
+
<!-- 自定义空数据 -->
|
|
259
|
+
<a-empty description="空数据" />
|
|
260
|
+
</slot>
|
|
261
|
+
</div>
|
|
262
|
+
<div ref="eVirtTableOverlayerRef">
|
|
263
|
+
<!-- 自定覆盖层 -->
|
|
264
|
+
<div
|
|
265
|
+
:class="wrapper.class"
|
|
266
|
+
v-for="wrapper in overlayerView?.views || []"
|
|
267
|
+
:style="wrapper.style"
|
|
268
|
+
:key="wrapper.type"
|
|
269
|
+
>
|
|
270
|
+
<div :style="view.style" v-for="view in wrapper.views" :key="view.key">
|
|
271
|
+
<div
|
|
272
|
+
class="cell"
|
|
273
|
+
v-for="cell in view.cells"
|
|
274
|
+
:key="`${cell.rowKey}_${cell.key}`"
|
|
275
|
+
:style="cell.style"
|
|
276
|
+
>
|
|
277
|
+
<component
|
|
278
|
+
v-if="typeof cell.render === 'function'"
|
|
279
|
+
:is="cell.render(cell)"
|
|
280
|
+
></component>
|
|
281
|
+
<template
|
|
282
|
+
v-else-if="typeof cell.render === 'string' && cell.render.startsWith('slot:')"
|
|
283
|
+
>
|
|
284
|
+
<slot :name="cell.render.replace('slot:', '')" v-bind="cell" :cell="cell"></slot>
|
|
285
|
+
</template>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
</a-spin>
|
|
292
|
+
</template>
|