@vue-ui-kit/ant 1.9.0 → 1.9.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.
@@ -12,6 +12,7 @@ declare const _default: <F = Recordable<any>>(__VLS_props: NonNullable<Awaited<t
12
12
  setActiveKey: (key: number) => void;
13
13
  validateAll: () => Promise<PromiseSettledResult<any>[]>;
14
14
  validate: (__index: number, ignoreTabError?: boolean) => Promise<void>;
15
+ validateFields: (__index: number, fields: string[], ignoreTabError?: boolean) => Promise<void>;
15
16
  }>): void;
16
17
  attrs: any;
17
18
  slots: ReturnType<() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -312,5 +312,6 @@ export interface PFormGroupInstance {
312
312
  activeKey: number;
313
313
  setActiveKey: (activeKey: number) => void;
314
314
  validateAll: () => Promise<void>;
315
- validate: (index: number) => Promise<void>;
315
+ validate: (index: number, ignoreTabError?: boolean) => Promise<void>;
316
+ validateFields: (index: number, fields: string[], ignoreTabError?: boolean) => Promise<void>;
316
317
  }
@@ -7,14 +7,11 @@
7
7
  import { eachTree } from '@/utils/treeHelper';
8
8
  import { getFormDefaults } from '@/utils/config';
9
9
  import PFormCol from '@/components/PFormCol.vue';
10
- import {
11
- Form as AForm,
12
- Row as ARow,
13
- } from 'ant-design-vue';
10
+ import { Form as AForm, Row as ARow } from 'ant-design-vue';
14
11
 
15
12
  const props = defineProps<PFormProps<F> & { data: F }>();
16
13
  const emit = defineEmits(['apply', 'reset']);
17
-
14
+
18
15
  // 应用默认值
19
16
  const formDefaults = getFormDefaults();
20
17
  const propsWithDefaults = computed(() => ({
@@ -22,7 +19,7 @@
22
19
  labelCol: props.labelCol ?? formDefaults.labelCol ?? { span: 6 },
23
20
  wrapperCol: props.wrapperCol ?? formDefaults.wrapperCol ?? { span: 16 },
24
21
  }));
25
-
22
+
26
23
  const { items, data: formData } = toRefs(props);
27
24
 
28
25
  function handleSubmit() {
@@ -46,12 +43,10 @@
46
43
  } else {
47
44
  obj[item.field] = undefined;
48
45
  }
49
- }
50
- else if (item.field && item.slots) {
46
+ } else if (item.field && item.slots) {
51
47
  if (isGoodValue(item.slots.defaultValue)) {
52
- obj[item.field] = item.slots.defaultValue
53
- }
54
- else {
48
+ obj[item.field] = item.slots.defaultValue;
49
+ } else {
55
50
  obj[item.field] = undefined;
56
51
  }
57
52
  }
@@ -89,7 +84,7 @@
89
84
  <a-row :gutter="[6, 12]">
90
85
  <p-form-col
91
86
  v-for="(item, idx) in items"
92
- :key="`_col_${idx}`"
87
+ :key="`_col_${item.field || idx}`"
93
88
  :form-data="formData"
94
89
  :item="item"
95
90
  @reset="resetFormData"
@@ -2,8 +2,9 @@
2
2
  import { computed, nextTick, PropType, ref, watch, watchEffect } from 'vue';
3
3
  import { PFormGroupProps, PFormBlockInstance } from '#/antProxy';
4
4
  import { MoreOutlined } from '@ant-design/icons-vue';
5
- import type { Tabs } from 'ant-design-vue'
6
- import { Form } from 'ant-design-vue'
5
+ import type { Tabs } from 'ant-design-vue';
6
+ import type { Rule } from 'ant-design-vue/lib/form';
7
+ import { Form } from 'ant-design-vue';
7
8
  import { clone, toString, isFunction, omit, max, debounce } from 'xe-utils';
8
9
  import PGroupBlock from '@/components/PGroupBlock.vue';
9
10
  import {
@@ -18,17 +19,17 @@
18
19
  import { valued } from '@/utils/is';
19
20
  import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
20
21
  import { $warning } from '@/hooks/useMessage';
21
-
22
- const useForm = Form.useForm
23
- const tabsRef = ref<InstanceType<typeof Tabs>>()
22
+
23
+ const useForm = Form.useForm;
24
+ const tabsRef = ref<InstanceType<typeof Tabs>>();
24
25
  const props = defineProps<PFormGroupProps<F>>();
25
- const rootRef = ref<InstanceType<typeof ACard>>()
26
+ const rootRef = ref<InstanceType<typeof ACard>>();
26
27
  const model = defineModel({
27
28
  type: Array as PropType<Partial<F & { __index: number }>[]>,
28
29
  default: () => [],
29
30
  });
30
31
  const activeKey = ref(0);
31
- const error_indexes = ref<number[]>([])
32
+ const error_indexes = ref<number[]>([]);
32
33
  const blockInstance = ref<PFormBlockInstance[]>([]);
33
34
  const setActiveKey = (key: number) => {
34
35
  activeKey.value = key;
@@ -51,34 +52,38 @@
51
52
  { content: '复制', code: 'copy' },
52
53
  { content: '删除', code: 'delete' },
53
54
  ];
54
- const getPopupContainer = () => rootRef.value?.$el ?? document.body
55
+ const getPopupContainer = () => rootRef.value?.$el ?? document.body;
55
56
  // 实际是否强制渲染
56
57
  const fr = computed(() => {
57
- return props.forceRender || model.value.length <= 5
58
- })
58
+ return props.forceRender || model.value.length <= 5;
59
+ });
59
60
  const handleBlockFocus = (idx: number) => {
60
- const target_index = model.value.find((f, index) => index === idx)?.__index
61
+ const target_index = model.value.find((f, index) => index === idx)?.__index;
61
62
  if (valued(target_index)) {
62
- error_indexes.value = error_indexes.value.filter(f => f !== target_index)
63
+ error_indexes.value = error_indexes.value.filter((f) => f !== target_index);
63
64
  }
64
- }
65
+ };
65
66
  const handleTabChange = () => {
66
67
  nextTick().then(() => {
67
- handleBlockFocus(activeKey.value)
68
- blockInstance.value[activeKey.value]?.$form?.validate()
69
- })
70
- }
71
- watch(() => model.value, () => {
72
- if (!props.keepSerial) {
73
- const unSortItems = model.value.filter(f => !valued(f.__index))
74
- if (unSortItems.length > 0) {
75
- unSortItems.forEach((item) => {
76
- // @ts-ignore
77
- item.__index = (max(model.value, m => m.__index ?? -1)?.__index ?? -1) + 1
78
- })
79
- }
80
- }
81
- }, { immediate: true })
68
+ handleBlockFocus(activeKey.value);
69
+ blockInstance.value[activeKey.value]?.$form?.validate();
70
+ });
71
+ };
72
+ watch(
73
+ () => model.value,
74
+ () => {
75
+ if (!props.keepSerial) {
76
+ const unSortItems = model.value.filter((f) => !valued(f.__index));
77
+ if (unSortItems.length > 0) {
78
+ unSortItems.forEach((item) => {
79
+ // @ts-ignore
80
+ item.__index = (max(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1;
81
+ });
82
+ }
83
+ }
84
+ },
85
+ { immediate: true },
86
+ );
82
87
  const handleMenu = ({ key }: MenuInfo, item: Partial<F & { __index: number }>, idx: number) => {
83
88
  if (props.menuHandler && isFunction(props.menuHandler)) {
84
89
  props.menuHandler({ code: toString(key), data: item, index: idx });
@@ -95,8 +100,8 @@
95
100
  break;
96
101
  case 'copy':
97
102
  if (model.value.length >= maxLen.value) {
98
- $warning('已达到最大数量')
99
- return
103
+ $warning('已达到最大数量');
104
+ return;
100
105
  }
101
106
  model.value = [
102
107
  ...model.value,
@@ -118,73 +123,117 @@
118
123
  }
119
124
  });
120
125
 
121
- const debounceHandleBlockFocus = debounce(handleBlockFocus, 50)
126
+ const debounceHandleBlockFocus = debounce(handleBlockFocus, 50);
122
127
  watchEffect(() => {
123
- const errorKeys = model.value.map((m, idx) => error_indexes.value.includes(m.__index!) ? idx : undefined).filter(valued)
124
- const rootDom = tabsRef.value?.$el
125
- if (rootDom) {
126
- const tabPanel = rootDom.querySelectorAll(':scope >.ant-tabs-nav>.ant-tabs-nav-wrap>.ant-tabs-nav-list>.ant-tabs-tab>.ant-tabs-tab-btn')
127
- tabPanel.forEach((tab, idx) => {
128
- if (errorKeys.includes(idx)) {
129
- tab.classList.add('p-error-group-tab')
130
- }
131
- else {
132
- tab.classList.remove('p-error-group-tab')
133
- }
134
- })
135
- }
136
- })
128
+ const errorKeys = model.value
129
+ .map((m, idx) => (error_indexes.value.includes(m.__index!) ? idx : undefined))
130
+ .filter(valued);
131
+ const rootDom = tabsRef.value?.$el;
132
+ if (rootDom) {
133
+ const tabPanel = rootDom.querySelectorAll(
134
+ ':scope >.ant-tabs-nav>.ant-tabs-nav-wrap>.ant-tabs-nav-list>.ant-tabs-tab>.ant-tabs-tab-btn',
135
+ );
136
+ tabPanel.forEach((tab, idx) => {
137
+ if (errorKeys.includes(idx)) {
138
+ tab.classList.add('p-error-group-tab');
139
+ } else {
140
+ tab.classList.remove('p-error-group-tab');
141
+ }
142
+ });
143
+ }
144
+ });
137
145
  defineExpose({
138
146
  activeKey: computed(() => activeKey.value),
139
147
  setActiveKey,
140
148
  validateAll: () => {
141
- const promiseList = fr.value
142
- ? blockInstance.value.map(block => block.$form?.validate())
143
- : model.value.map(m => useForm(m, props.getFormSetting(m).rules)?.validate() ?? Promise.resolve())
144
- return Promise.allSettled(promiseList).then((results) => {
145
- // 更新 error_indexes
146
- error_indexes.value = results
147
- .map((res, idx) => (res.status === 'rejected' && typeof model.value[idx]?.__index === 'number' ? model.value[idx].__index as number : undefined))
148
- .filter((v): v is number => typeof v === 'number')
149
- if (!props.lazyErrorMark && error_indexes.value.length) {
150
- // 跳到第一个出错的tab
151
- const firstErrorIndex = error_indexes.value[0]
152
- const firstErrorTab = model.value.findIndex(f => f.__index === firstErrorIndex)
153
- if (firstErrorTab !== -1) {
154
- activeKey.value = firstErrorTab
149
+ const promiseList = fr.value
150
+ ? blockInstance.value.map((block) => block.$form?.validate())
151
+ : model.value.map(
152
+ (m) => useForm(m, props.getFormSetting(m).rules)?.validate() ?? Promise.resolve(),
153
+ );
154
+ return Promise.allSettled(promiseList).then((results) => {
155
+ // 更新 error_indexes
156
+ error_indexes.value = results
157
+ .map((res, idx) =>
158
+ res.status === 'rejected' && typeof model.value[idx]?.__index === 'number'
159
+ ? (model.value[idx].__index as number)
160
+ : undefined,
161
+ )
162
+ .filter((v): v is number => typeof v === 'number');
163
+ if (!props.lazyErrorMark && error_indexes.value.length) {
164
+ // 跳到第一个出错的tab
165
+ const firstErrorIndex = error_indexes.value[0];
166
+ const firstErrorTab = model.value.findIndex((f) => f.__index === firstErrorIndex);
167
+ if (firstErrorTab !== -1) {
168
+ activeKey.value = firstErrorTab;
169
+ }
155
170
  }
171
+ // 判断是否有错误
172
+ if (error_indexes.value.length) {
173
+ return Promise.reject({ error_indexes: error_indexes.value, results });
174
+ }
175
+ return Promise.resolve(results);
176
+ });
177
+ },
178
+ validate: async (__index: number, ignoreTabError?: boolean) => {
179
+ const index = model.value.findIndex((f) => f.__index === __index);
180
+ try {
181
+ await (fr.value
182
+ ? (blockInstance.value[index]?.$form?.validate() ?? Promise.resolve())
183
+ : (useForm(
184
+ model.value[index],
185
+ props.getFormSetting(model.value[index]).rules,
186
+ )?.validate() ?? Promise.resolve()));
187
+ // 校验通过,移除error_indexes中的__index
188
+ error_indexes.value = error_indexes.value.filter((f) => f !== __index);
189
+ return Promise.resolve();
190
+ } catch (e) {
191
+ // 校验失败,加入error_indexes
192
+ if (!error_indexes.value.includes(__index) && !ignoreTabError) {
193
+ error_indexes.value = [...error_indexes.value, __index];
194
+ }
195
+ return Promise.reject(e);
156
196
  }
157
- // 判断是否有错误
158
- if (error_indexes.value.length) {
159
- return Promise.reject({ error_indexes: error_indexes.value, results })
160
- }
161
- return Promise.resolve(results)
162
- })
163
- },
164
- validate: async (__index: number, ignoreTabError?: boolean) => {
165
- const index = model.value.findIndex(f => f.__index === __index)
166
- try {
167
- await (fr.value
168
- ? (blockInstance.value[index]?.$form?.validate() ?? Promise.resolve())
169
- : (useForm(model.value[index], props.getFormSetting(model.value[index]).rules)?.validate() ?? Promise.resolve()))
170
- // 校验通过,移除error_indexes中的__index
171
- error_indexes.value = error_indexes.value.filter(f => f !== __index)
172
- return Promise.resolve()
173
- }
174
- catch (e) {
175
- // 校验失败,加入error_indexes
176
- if (!error_indexes.value.includes(__index) && !ignoreTabError) {
177
- error_indexes.value = [...error_indexes.value, __index]
197
+ },
198
+ validateFields: async (__index: number, fields: string[], ignoreTabError?: boolean) => {
199
+ const index = model.value.findIndex((f) => f.__index === __index);
200
+ const formSettings = props.getFormSetting(model.value[index]);
201
+ const rules = formSettings.rules as Record<string, Rule[]>;
202
+ const dataFormFactory = useForm(model.value[index], rules);
203
+ try {
204
+ await (fr.value
205
+ ? (blockInstance.value[index]?.$form?.validateFields(fields) ?? Promise.resolve())
206
+ : Promise.allSettled(
207
+ fields.map((m) =>
208
+ dataFormFactory.validateField(
209
+ m,
210
+ model.value[index][m],
211
+ (rules[m] as Record<string, unknown>[]) ?? [],
212
+ ),
213
+ ),
214
+ ));
215
+ return Promise.resolve();
216
+ } catch (e) {
217
+ // 校验失败,加入error_indexes
218
+ if (!error_indexes.value.includes(__index) && !ignoreTabError) {
219
+ error_indexes.value = [...error_indexes.value, __index];
220
+ }
221
+ return Promise.reject(e);
178
222
  }
179
- return Promise.reject(e)
180
- }
181
- },
223
+ },
182
224
  });
183
225
  </script>
184
226
  <template>
185
227
  <a-card ref="rootRef" :title="title" size="small">
186
228
  <a-spin v-if="loading" class="w-full" />
187
- <a-tabs v-else ref="tabsRef" type="editable-card" v-model:activeKey="activeKey" hide-add @change="handleTabChange">
229
+ <a-tabs
230
+ v-else
231
+ ref="tabsRef"
232
+ type="editable-card"
233
+ v-model:activeKey="activeKey"
234
+ hide-add
235
+ @change="handleTabChange"
236
+ >
188
237
  <template #rightExtra>
189
238
  <slot name="rightExtra">
190
239
  <a-button
@@ -219,17 +268,8 @@
219
268
  </template>
220
269
  </a-dropdown>
221
270
  </template>
222
- <!-- @vue-ignore -->
223
271
  <p-group-block
224
- :ref="
225
- (i: PFormBlockInstance) => {
226
- if (i) {
227
- blockInstance[idx] = i;
228
- } else if (blockInstance) {
229
- blockInstance = blockInstance.filter((_, i) => i !== idx);
230
- }
231
- }
232
- "
272
+ ref="blockInstance"
233
273
  :key="idx"
234
274
  :source="item"
235
275
  :get-form-setting="getFormSetting"
@@ -11,7 +11,18 @@
11
11
  toRefs,
12
12
  onBeforeUnmount,
13
13
  } from 'vue';
14
- import { debounce, get, isArray, isBoolean, isFunction, isObject, isString, merge, omit, toNumber } from 'xe-utils';
14
+ import {
15
+ debounce,
16
+ get,
17
+ isArray,
18
+ isBoolean,
19
+ isFunction,
20
+ isObject,
21
+ isString,
22
+ merge,
23
+ omit,
24
+ toNumber,
25
+ } from 'xe-utils';
15
26
  import { eachTree } from '@/utils/treeHelper';
16
27
  import { message as $message } from 'ant-design-vue';
17
28
  import RenderTitleSlots from '@/components/RenderTitleSlots';
@@ -34,7 +45,7 @@
34
45
  import { DownOutlined } from '@ant-design/icons-vue';
35
46
 
36
47
  const props = defineProps<PGridProps<D, F>>();
37
-
48
+
38
49
  // 应用默认值
39
50
  const gridDefaults = getGridDefaults();
40
51
  const propsWithDefaults = computed(() => ({
@@ -45,7 +56,7 @@
45
56
  lazyReset: props.lazyReset ?? gridDefaults.lazyReset ?? false,
46
57
  fitHeight: props.fitHeight ?? gridDefaults.fitHeight ?? 170,
47
58
  }));
48
-
59
+
49
60
  const {
50
61
  formConfig,
51
62
  pageConfig,
@@ -61,12 +72,12 @@
61
72
  toolbar: false,
62
73
  form: false,
63
74
  });
64
- const setLoadings = (value: boolean|Record<string, boolean>) => {
65
- if(isObject(value)) {
66
- Object.keys(value).forEach(key => {
75
+ const setLoadings = (value: boolean | Record<string, boolean>) => {
76
+ if (isObject(value)) {
77
+ Object.keys(value).forEach((key) => {
67
78
  loading[key] = value[key];
68
79
  });
69
- } else if(isBoolean(value)) {
80
+ } else if (isBoolean(value)) {
70
81
  loading.form = value;
71
82
  loading.table = value;
72
83
  loading.toolbar = value;
@@ -126,7 +137,7 @@
126
137
  const tableEl = ref();
127
138
  const renderFormKey = ref(uuid_v4());
128
139
  const renderTableKey = ref(uuid_v4());
129
-
140
+
130
141
  const codeLoadings = reactive<Record<string, boolean>>(
131
142
  [
132
143
  ...(props.toolbarConfig?.buttons?.map((m) => m.code) ?? []).filter((f) => f),
@@ -229,13 +240,11 @@
229
240
  } else {
230
241
  obj[item.field] = undefined;
231
242
  }
232
- }
233
- else if (item.field && item.slots) {
243
+ } else if (item.field && item.slots) {
234
244
  if (isGoodValue(item.slots.defaultValue)) {
235
- obj[item.field] = item.slots.defaultValue
236
- }
237
- else {
238
- obj[item.field] = undefined
245
+ obj[item.field] = item.slots.defaultValue;
246
+ } else {
247
+ obj[item.field] = undefined;
239
248
  }
240
249
  }
241
250
  });
@@ -278,8 +287,8 @@
278
287
  };
279
288
  const enoughSpacing = ref(true);
280
289
  const reload = () => {
281
- selectedCaches.value = []
282
- selectedRowKeys.value = []
290
+ selectedCaches.value = [];
291
+ selectedRowKeys.value = [];
283
292
  return resetQueryFormData();
284
293
  };
285
294
  const resetPage = () => {
@@ -417,10 +426,14 @@
417
426
  const formHeight = formOriginHeight.includes('px')
418
427
  ? toNumber(formOriginHeight.replace('px', ''))
419
428
  : 0;
420
- const showCountHeight = selectConfig.value?.showCount ? 22 : 0
429
+ const showCountHeight = selectConfig.value?.showCount ? 22 : 0;
421
430
  renderHeight.value =
422
431
  props.renderY ??
423
- toNumber(ph.replace('px', '')) -propsWithDefaults.value.fitHeight -(props.toolbarConfig ? 30 : 0) -formHeight- showCountHeight;
432
+ toNumber(ph.replace('px', '')) -
433
+ propsWithDefaults.value.fitHeight -
434
+ (props.toolbarConfig ? 30 : 0) -
435
+ formHeight -
436
+ showCountHeight;
424
437
  enoughSpacing.value = toNumber(ph.replace('px', '')) > 600;
425
438
  };
426
439
  defineExpose({
@@ -462,13 +475,17 @@
462
475
  }
463
476
  resetQueryFormData(props.manualFetch);
464
477
  });
465
- const passFields = ['align']
466
- const passDefaultColumnProps = (columns: ColumnProps<D>[]) => columns.map(c => ({
467
- ...passFields.reduce((prev, cur) => ({
468
- [cur]: propsWithDefaults.value[cur],
469
- }), {} as ColumnProps<D>),
470
- ...c,
471
- }))
478
+ const passFields = ['align'];
479
+ const passDefaultColumnProps = (columns: ColumnProps<D>[]) =>
480
+ columns.map((c) => ({
481
+ ...passFields.reduce(
482
+ (prev, cur) => ({
483
+ [cur]: propsWithDefaults.value[cur],
484
+ }),
485
+ {} as ColumnProps<D>,
486
+ ),
487
+ ...c,
488
+ }));
472
489
  onBeforeUnmount(() => {
473
490
  window.removeEventListener('resize', resizeTable);
474
491
  observer.disconnect();
@@ -494,7 +511,7 @@
494
511
  <a-row :gutter="[6, 12]">
495
512
  <p-form-col
496
513
  v-for="(item, idx) in formConfig!.items"
497
- :key="`_col_${idx}`"
514
+ :key="`_col_${item.field || idx}`"
498
515
  :form-data="queryFormData"
499
516
  :item="item as PFormItemProps<Partial<F>>"
500
517
  @reset="resetQueryFormData(propsWithDefaults.lazyReset)"
@@ -561,7 +578,10 @@
561
578
  </span>
562
579
  </div>
563
580
  <div :class="`p-pane flex-1 ${enoughSpacing ? 'h-0' : ''} p-${scrollMode ?? 'inner'}-scroll`">
564
- <div v-if="selectConfig?.multiple && selectConfig.showCount" class="w-full text-slate-5 pl-4">
581
+ <div
582
+ v-if="selectConfig?.multiple && selectConfig.showCount"
583
+ class="w-full text-slate-5 pl-4"
584
+ >
565
585
  已选:{{ selectedRowKeys.length }}
566
586
  </div>
567
587
  <a-table
@@ -4,13 +4,13 @@
4
4
  import PForm from '@/components/PForm.vue';
5
5
 
6
6
  const props = defineProps<PBlockProps<F>>();
7
- const formEl = ref<PFormInstance>()
7
+ const formEl = ref<PFormInstance>();
8
8
  const { source } = toRefs(props);
9
- const $form = computed(() => formEl.value?.$form)
9
+ const $form = computed(() => formEl.value?.$form);
10
10
  const formSetting = computed<PFormProps<Partial<F>>>(() => props.getFormSetting(source.value));
11
11
  defineExpose({
12
12
  $form,
13
- })
13
+ });
14
14
  </script>
15
15
  <template>
16
16
  <p-form ref="formEl" v-bind="formSetting" :data="source!" />
@@ -1,10 +1,10 @@
1
1
  import { defineComponent } from 'vue';
2
- import { ItemRender, RenderTableParams } from '#/antProxy';
2
+ import { CellRender, RenderTableParams } from '#/antProxy';
3
3
  import renderStore from '@/store/renderStore';
4
4
 
5
5
  export default defineComponent(
6
6
  <D = Recordable,>(props: {
7
- cellRender: ItemRender;
7
+ cellRender: CellRender;
8
8
  renderTableParams: RenderTableParams<D>;
9
9
  defaultHandler?: {
10
10
  [key: string]: (...args: any[]) => any;