@vue-ui-kit/ant 1.1.0 → 1.1.2
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 +1 -1
- package/dist/declarations/antProxy.d.ts +13 -0
- package/dist/es/index.js +686 -646
- package/dist/packages/components/PFormGroup.vue.d.ts +1 -0
- package/dist/packages/store/renderStore.d.ts +3 -0
- package/package.json +1 -1
- package/src/declarations/antProxy.ts +20 -6
- package/src/packages/components/PForm.vue +83 -82
- package/src/packages/components/PFormGroup.vue +70 -57
- package/src/packages/components/PGrid.vue +361 -360
- package/src/packages/store/renderStore.tsx +109 -88
|
@@ -10,6 +10,7 @@ declare const _default: <F = Recordable<any>>(__VLS_props: NonNullable<Awaited<t
|
|
|
10
10
|
expose(exposed: import('vue').ShallowUnwrapRef<{
|
|
11
11
|
activeKey: import('vue').ComputedRef<number>;
|
|
12
12
|
setActiveKey: (key: number) => void;
|
|
13
|
+
validateAll: () => Promise<any[]>;
|
|
13
14
|
}>): void;
|
|
14
15
|
attrs: any;
|
|
15
16
|
slots: ReturnType<() => {
|
|
@@ -29,6 +29,9 @@ declare const _default: {
|
|
|
29
29
|
renderItemContent({ props, options }: RenderOptions, { data, field }: RenderFormParams): import("vue/jsx-runtime").JSX.Element | null;
|
|
30
30
|
renderDefault({ props, options }: RenderOptions, { row, field }: RenderTableParams): import("vue/jsx-runtime").JSX.Element | null;
|
|
31
31
|
};
|
|
32
|
+
$autoComplete: {
|
|
33
|
+
renderItemContent({ props, events }: RenderOptions, { data, field }: RenderFormParams): import("vue/jsx-runtime").JSX.Element | null;
|
|
34
|
+
};
|
|
32
35
|
$switch: {
|
|
33
36
|
renderItemContent({ props, events }: RenderOptions, { data, field }: RenderFormParams): import("vue/jsx-runtime").JSX.Element | null;
|
|
34
37
|
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Rule } from 'ant-design-vue/lib/form'
|
|
2
|
-
import { ButtonProps } from 'ant-design-vue/lib/button'
|
|
3
|
-
import { ColProps } from 'ant-design-vue/lib/grid/Col'
|
|
4
|
-
import { FormProps } from 'ant-design-vue/lib/form/Form'
|
|
5
|
-
import { TableColumnType, TableProps } from 'ant-design-vue'
|
|
6
|
-
import { ButtonType } from 'ant-design-vue/lib/button/buttonTypes'
|
|
1
|
+
import type { Rule } from 'ant-design-vue/lib/form'
|
|
2
|
+
import { ButtonProps } from 'ant-design-vue/lib/button'
|
|
3
|
+
import { ColProps } from 'ant-design-vue/lib/grid/Col'
|
|
4
|
+
import { FormProps } from 'ant-design-vue/lib/form/Form'
|
|
5
|
+
import { TableColumnType, TableProps } from 'ant-design-vue'
|
|
6
|
+
import { ButtonType } from 'ant-design-vue/lib/button/buttonTypes'
|
|
7
7
|
|
|
8
8
|
export interface CellFuncArg<D = Recordable> {
|
|
9
9
|
row: D;
|
|
@@ -46,6 +46,7 @@ export interface PFormItemProps<F = Recordable> {
|
|
|
46
46
|
field?: string;
|
|
47
47
|
title?: string;
|
|
48
48
|
span?: number;
|
|
49
|
+
colon?: boolean
|
|
49
50
|
align?: 'left' | 'right' | 'center';
|
|
50
51
|
col?: ColProps;
|
|
51
52
|
rule?: Rule[];
|
|
@@ -177,6 +178,14 @@ export type PGridProps<D = Recordable, F = Recordable> = {
|
|
|
177
178
|
proxyConfig?: ProxyConfig<D, F>;
|
|
178
179
|
tableConfig?: TableProps<D>;
|
|
179
180
|
scrollMode?: 'outer' | 'inner';
|
|
181
|
+
/**
|
|
182
|
+
* 适应展示区到页面顶部的高度,通常和容器最上的y值有关(正比)
|
|
183
|
+
*/
|
|
184
|
+
fitHeight?: number;
|
|
185
|
+
/**
|
|
186
|
+
* 虚拟列表 Y区计算高度
|
|
187
|
+
*/
|
|
188
|
+
renderY?: number;
|
|
180
189
|
};
|
|
181
190
|
|
|
182
191
|
export interface RenderOptions {
|
|
@@ -249,7 +258,12 @@ export interface PromisePickerInstance<D = Recordable> {
|
|
|
249
258
|
pick: () => Promise<{ row: D; field?: string }>;
|
|
250
259
|
}
|
|
251
260
|
|
|
261
|
+
export interface PFormBlockInstance {
|
|
262
|
+
$form: Recordable
|
|
263
|
+
}
|
|
264
|
+
|
|
252
265
|
export interface PFormGroupInstance<F = Recordable> {
|
|
253
266
|
activeKey: number;
|
|
254
267
|
setActiveKey: (activeKey: number) => void;
|
|
268
|
+
validateAll: () => Promise<void>;
|
|
255
269
|
}
|
|
@@ -1,103 +1,104 @@
|
|
|
1
1
|
<script generic="F = Recordable" lang="ts" name="PForm" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import { PFormItemProps, PFormProps } from '#/antProxy'
|
|
3
|
+
import { computed, onMounted, ref, toRefs, watch } from 'vue'
|
|
4
|
+
import { debounce, omit } from 'lodash-es'
|
|
5
|
+
import { v4 as uuid_v4 } from 'uuid'
|
|
6
|
+
import RenderAntItem from '@/components/RenderAntItem'
|
|
7
|
+
import RenderItemSlots from '@/components/RenderItemSlots'
|
|
8
|
+
import { valued } from '@/utils/is'
|
|
9
|
+
import { eachTree } from '@/utils/treeHelper'
|
|
10
|
+
import { defaultItemResponsive } from '@/utils/core'
|
|
11
|
+
import { Form as AForm, Row as ARow, Col as ACol, FormItem as AFormItem } from 'ant-design-vue'
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const props = defineProps<PFormProps<F> & { data: F }>()
|
|
14
|
+
const emit = defineEmits(['apply', 'reset'])
|
|
15
|
+
const { items, data: formData } = toRefs(props)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
function handleSubmit () {
|
|
18
|
+
emit('apply', formData.value)
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
21
|
+
const formEl = ref()
|
|
22
|
+
const renderFormKey = ref(uuid_v4())
|
|
23
|
+
const resetForm = () => {
|
|
24
|
+
renderFormKey.value = uuid_v4()
|
|
25
|
+
}
|
|
26
|
+
const debounceResetForm = debounce(resetForm, 100)
|
|
27
|
+
watch(() => items.value, debounceResetForm, { deep: true })
|
|
28
|
+
const resetFormData = () => {
|
|
29
|
+
if (props.customReset) {
|
|
30
|
+
props.customReset()
|
|
31
|
+
} else {
|
|
32
|
+
const obj: Partial<F> = {}
|
|
33
|
+
eachTree(items.value, (item) => {
|
|
34
|
+
if (item.field && item.itemRender) {
|
|
35
|
+
if (valued(item.itemRender.defaultValue)) {
|
|
36
|
+
obj[item.field] = item.itemRender.defaultValue
|
|
37
|
+
} else {
|
|
38
|
+
obj[item.field] = undefined
|
|
40
39
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
Object.assign(formData.value, obj)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// omit({labelCol:defaultLabelCol,...props},['items','data','model'])
|
|
46
|
+
const fc = computed(() => ({
|
|
47
|
+
...omit(props, ['items', 'data', 'model', 'labelCol', 'wrapperCol']),
|
|
48
|
+
labelCol: props.labelCol ?? { span: 6 },
|
|
49
|
+
wrapperCol: props.wrapperCol ?? { span: 16 },
|
|
50
|
+
}))
|
|
51
|
+
const validateField = (fields?: string | string[]) => {
|
|
52
|
+
if (fields) {
|
|
53
|
+
formEl.value?.validateFields(fields)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const handleTrigger = (cusFields?: string | string[]) => {
|
|
57
|
+
validateField(cusFields)
|
|
58
|
+
}
|
|
59
|
+
defineExpose({
|
|
60
|
+
reset: resetForm,
|
|
61
|
+
$form: computed(() => formEl.value),
|
|
62
|
+
})
|
|
63
|
+
onMounted(() => {
|
|
64
|
+
resetForm()
|
|
65
|
+
})
|
|
66
66
|
</script>
|
|
67
67
|
<template>
|
|
68
68
|
<div
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
v-if="items.some((s: PFormItemProps<F>) => s.field && s.itemRender)"
|
|
70
|
+
class="p-pane p-wrapper"
|
|
71
71
|
>
|
|
72
72
|
<a-form :key="renderFormKey" ref="formEl" :model="formData" v-bind="fc" @submit="handleSubmit">
|
|
73
73
|
<a-row :gutter="[6, 12]">
|
|
74
74
|
<a-col
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
v-for="(item, idx) in items"
|
|
76
|
+
:key="'_col_' + idx"
|
|
77
|
+
v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
|
|
78
78
|
>
|
|
79
79
|
<a-form-item
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
:key="'_item_' + idx"
|
|
81
|
+
:label="item.title"
|
|
82
|
+
:name="item.field"
|
|
83
|
+
:wrapper-col="item.wrapperCol ?? (item.title ? undefined : { span: 24 })"
|
|
84
|
+
colon
|
|
85
|
+
:class="`p-content-align-${item.align ?? 'left'}`"
|
|
86
|
+
v-bind="omit(item, ['field', 'title', 'span', 'col', 'wrapperCol', 'itemRender'])"
|
|
87
87
|
>
|
|
88
88
|
<render-item-slots
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
v-if="item.slots?.default"
|
|
90
|
+
:form-data="formData"
|
|
91
|
+
:item="item"
|
|
92
|
+
:key="'_sl_'+(item.field??'_')+'_'+idx"
|
|
93
|
+
:pass-trigger="handleTrigger"
|
|
93
94
|
/>
|
|
94
95
|
<render-ant-item
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
v-else-if="item.itemRender?.name"
|
|
97
|
+
:key="'_re_'+(item.field??'_')+'_'+idx"
|
|
98
|
+
:default-handler="{ reset: resetFormData }"
|
|
99
|
+
:item-render="item.itemRender"
|
|
100
|
+
@trigger="handleTrigger"
|
|
101
|
+
:render-form-params="{ data: formData, field: item.field }"
|
|
101
102
|
/>
|
|
102
103
|
<span v-else></span>
|
|
103
104
|
</a-form-item>
|
|
@@ -1,55 +1,61 @@
|
|
|
1
1
|
<script lang="ts" generic="F = Recordable" setup name="PFormGroup">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
import { computed, PropType, ref } from 'vue'
|
|
3
|
+
import { PFormGroupProps, PFormBlockInstance } from '#/antProxy'
|
|
4
|
+
import { MoreOutlined } from '@ant-design/icons-vue'
|
|
5
|
+
import { cloneDeep, toString, isFunction, omit } from 'lodash-es'
|
|
6
|
+
import PGroupBlock from '@/components/PGroupBlock.vue'
|
|
7
|
+
import {
|
|
8
|
+
Card as ACard,
|
|
9
|
+
Tabs as ATabs,
|
|
10
|
+
TabPane as ATabPane,
|
|
11
|
+
Button as AButton,
|
|
12
|
+
Dropdown as ADropdown,
|
|
13
|
+
Menu as AMenu,
|
|
14
|
+
MenuItem as AMenuItem,
|
|
15
|
+
} from 'ant-design-vue'
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
17
|
+
const props = defineProps<PFormGroupProps<F>>()
|
|
18
|
+
const model = defineModel({
|
|
19
|
+
type: Array as PropType<Partial<F>[]>,
|
|
20
|
+
default: () => [],
|
|
21
|
+
})
|
|
22
|
+
const activeKey = ref(0)
|
|
23
|
+
const blockInstance = ref<PFormBlockInstance[]>([])
|
|
24
|
+
const setActiveKey = (key: number) => {
|
|
25
|
+
activeKey.value = key
|
|
26
|
+
}
|
|
27
|
+
const maxLen = props.max ?? Infinity
|
|
28
|
+
const handleAddItem = (idx: number) => {
|
|
29
|
+
const creator = props.creatItem ?? (() => Promise.resolve({} as Partial<F>))
|
|
30
|
+
creator({ list: model.value }).then((item) => {
|
|
31
|
+
model.value = [...model.value, item]
|
|
32
|
+
activeKey.value = idx
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
const itemMenus = props.itemMenus ?? [{ content: '删除', code: 'delete' }]
|
|
36
|
+
const handleMenu = (key: string, item: Partial<F>, idx: number) => {
|
|
37
|
+
if (props.menuHandler && isFunction(props.menuHandler)) {
|
|
38
|
+
props.menuHandler({ code: key, data: item, index: idx })
|
|
39
|
+
} else {
|
|
40
|
+
switch (key) {
|
|
41
|
+
case 'delete':
|
|
42
|
+
model.value = model.value.filter((_, i) => i !== idx)
|
|
43
|
+
break
|
|
44
|
+
case 'copy':
|
|
45
|
+
model.value = [...model.value, cloneDeep(omit(item, ['id']))]
|
|
46
|
+
break
|
|
47
47
|
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
defineExpose({
|
|
51
|
+
activeKey: computed(() => activeKey.value),
|
|
52
|
+
setActiveKey,
|
|
53
|
+
validateAll: () => {
|
|
54
|
+
return Promise.all(blockInstance.value.map((block) =>
|
|
55
|
+
block.$form?.validate() ?? Promise.resolve()
|
|
56
|
+
))
|
|
57
|
+
},
|
|
58
|
+
})
|
|
53
59
|
</script>
|
|
54
60
|
<template>
|
|
55
61
|
<a-card :title="title" size="small">
|
|
@@ -57,25 +63,25 @@
|
|
|
57
63
|
<template #rightExtra>
|
|
58
64
|
<slot name="rightExtra">
|
|
59
65
|
<a-button
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
type="link"
|
|
67
|
+
@click="handleAddItem(model.length)"
|
|
68
|
+
v-if="showAdd && model.length < maxLen"
|
|
63
69
|
>
|
|
64
70
|
+ 新增
|
|
65
71
|
</a-button>
|
|
66
72
|
</slot>
|
|
67
73
|
</template>
|
|
68
|
-
<a-tab-pane v-for="(item, idx) in model" :key="idx" :tab="`${tabLabel} ${idx + 1}`">
|
|
74
|
+
<a-tab-pane v-for="(item, idx) in model" :key="idx" :tab="`${tabLabel} ${idx + 1}`" force-render>
|
|
69
75
|
<template #closeIcon>
|
|
70
76
|
<a-dropdown v-if="editAble && itemMenus?.length">
|
|
71
|
-
<MoreOutlined
|
|
77
|
+
<MoreOutlined/>
|
|
72
78
|
<template #overlay>
|
|
73
79
|
<a-menu @click="(e) => handleMenu(toString(e.key), item, idx)">
|
|
74
80
|
<a-menu-item
|
|
75
|
-
|
|
81
|
+
v-for="menu in itemMenus.filter(
|
|
76
82
|
(f) => f.visibleMethod?.({ data: item, index: idx }) ?? true,
|
|
77
83
|
)"
|
|
78
|
-
|
|
84
|
+
:key="menu.code"
|
|
79
85
|
>
|
|
80
86
|
<div>{{ menu.content }}</div>
|
|
81
87
|
</a-menu-item>
|
|
@@ -83,7 +89,14 @@
|
|
|
83
89
|
</template>
|
|
84
90
|
</a-dropdown>
|
|
85
91
|
</template>
|
|
86
|
-
|
|
92
|
+
<!-- @vue-ignore -->
|
|
93
|
+
<p-group-block :ref="(i:PFormBlockInstance)=>{
|
|
94
|
+
if(i){
|
|
95
|
+
blockInstance[idx] = i
|
|
96
|
+
}else if(blockInstance){
|
|
97
|
+
blockInstance = blockInstance.filter((_,i)=>i!==idx)
|
|
98
|
+
}
|
|
99
|
+
}" :key="idx" :source="item" :get-form-setting="getFormSetting"/>
|
|
87
100
|
</a-tab-pane>
|
|
88
101
|
</a-tabs>
|
|
89
102
|
</a-card>
|