@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.
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -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
- 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';
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
- const props = defineProps<PFormProps<F> & { data: F }>();
14
- const emit = defineEmits(['apply', 'reset']);
15
- const { items, data: formData } = toRefs(props);
13
+ const props = defineProps<PFormProps<F> & { data: F }>()
14
+ const emit = defineEmits(['apply', 'reset'])
15
+ const { items, data: formData } = toRefs(props)
16
16
 
17
- function handleSubmit() {
18
- emit('apply', formData.value);
19
- }
17
+ function handleSubmit () {
18
+ emit('apply', formData.value)
19
+ }
20
20
 
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;
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
- 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
- });
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
- v-if="items.some((s: PFormItemProps<F>) => s.field && s.itemRender)"
70
- class="p-pane p-wrapper"
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
- v-for="(item, idx) in items"
76
- :key="'_col_' + idx"
77
- v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
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
- :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'])"
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
- v-if="item.slots?.default"
90
- :form-data="formData"
91
- :item="item"
92
- :pass-trigger="handleTrigger"
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
- v-else-if="item.itemRender?.name"
96
- :key="'_re_' + idx"
97
- :default-handler="{ reset: resetFormData }"
98
- :item-render="item.itemRender"
99
- @trigger="handleTrigger"
100
- :render-form-params="{ data: formData, field: item.field }"
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
- import { computed, PropType, ref } from 'vue';
3
- import { PFormGroupProps } 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';
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
- 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 setActiveKey = (key: number) => {
24
- activeKey.value = key;
25
- };
26
- const maxLen = props.max ?? Infinity;
27
- const handleAddItem = (idx: number) => {
28
- const creator = props.creatItem ?? (() => Promise.resolve({} as Partial<F>));
29
- creator({ list: model.value }).then((item) => {
30
- model.value = [...model.value, item];
31
- activeKey.value = idx;
32
- });
33
- };
34
- const itemMenus = props.itemMenus ?? [{ content: '删除', code: 'delete' }];
35
- const handleMenu = (key: string, item: Partial<F>, idx: number) => {
36
- if (props.menuHandler && isFunction(props.menuHandler)) {
37
- props.menuHandler({ code: key, data: item, index: idx });
38
- } else {
39
- switch (key) {
40
- case 'delete':
41
- model.value = model.value.filter((_, i) => i !== idx);
42
- break;
43
- case 'copy':
44
- model.value = [...model.value, cloneDeep(omit(item, ['id']))];
45
- break;
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
- defineExpose({
50
- activeKey: computed(() => activeKey.value),
51
- setActiveKey,
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
- type="link"
61
- @click="handleAddItem(model.length)"
62
- v-if="showAdd && model.length < maxLen"
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
- v-for="menu in itemMenus.filter(
81
+ v-for="menu in itemMenus.filter(
76
82
  (f) => f.visibleMethod?.({ data: item, index: idx }) ?? true,
77
83
  )"
78
- :key="menu.code"
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
- <p-group-block :key="idx" :source="item" :get-form-setting="getFormSetting" />
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>