@vue-ui-kit/ant 2.0.6 → 2.0.8

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.
@@ -0,0 +1,33 @@
1
+ interface Props {
2
+ /** 是否默认折叠 */
3
+ defaultCollapsed?: boolean;
4
+ title?: string;
5
+ /** 是否可以折叠 */
6
+ collapsible?: boolean;
7
+ }
8
+ declare function __VLS_template(): {
9
+ attrs: Partial<{}>;
10
+ slots: Readonly<{
11
+ title: () => any;
12
+ }> & {
13
+ title: () => any;
14
+ };
15
+ refs: {};
16
+ rootEl: any;
17
+ };
18
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
19
+ declare const __VLS_component: import('vue').DefineComponent<Props, {
20
+ collapse: () => void;
21
+ expand: () => void;
22
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {
23
+ title: string;
24
+ defaultCollapsed: boolean;
25
+ collapsible: boolean;
26
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
27
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
28
+ export default _default;
29
+ type __VLS_WithTemplateSlots<T, S> = T & {
30
+ new (): {
31
+ $slots: S;
32
+ };
33
+ };
@@ -10,6 +10,8 @@ declare const _default: <F extends Recordable = Recordable>(__VLS_props: NonNull
10
10
  }>[];
11
11
  } & PFormGroupProps<F>) & Partial<{}>> & import('vue').PublicProps;
12
12
  expose(exposed: import('vue').ShallowUnwrapRef<{
13
+ collapse: () => void;
14
+ expand: () => void;
13
15
  activeKey: import('vue').ComputedRef<number>;
14
16
  setActiveKey: (key: number) => void;
15
17
  validateAll: () => Promise<PromiseSettledResult<any>[]>;
@@ -1,8 +1,10 @@
1
1
  import { ColumnProps, Responsive } from '../../declarations/antProxy';
2
2
  import { TableColumnGroupType, TableColumnType } from 'ant-design-vue';
3
+ import { WatchOptions, WatchSource } from 'vue';
3
4
  export declare const cleanCol: (col: ColumnProps) => TableColumnType | TableColumnGroupType<Recordable>;
4
5
  export declare const defaultItemResponsive: Responsive;
5
6
  export declare const defaultLabelCol: Responsive;
6
7
  export declare const labelColDict: Record<number, Responsive>;
7
8
  export declare const get24rest: (exist: number[]) => number;
8
9
  export declare const getButtonResponsive: (itemResponsive: number | Responsive[]) => any;
10
+ export declare function watchPreviousDeep<T extends object>(source: WatchSource<T>, cb: (value: T, oldValue: T, onCleanup: () => void) => void, options?: WatchOptions): import('vue').WatchHandle;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";:root{--p-theme-bg: #fff}.p-pane{background-color:var(--p-theme-bg);padding:16px;border-radius:4px}.text-slate-5{color:#64748b}.w-full{width:100%}.cursor-pointer{cursor:pointer}.py-4x{padding-top:4px;padding-bottom:4px}.px-2x{padding-left:2px;padding-right:2px}.pl-4x{padding-left:1em}.pl-8{padding-left:2em}.h-0{height:0}.h-full{height:100%}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-4px{gap:4px}.gap-8px{gap:8px}.pt-8px{padding-top:8px}.px-16px{padding-left:16px;padding-right:16px}.mt-4px{margin-top:4px}.text-right{text-align:right}.overflow-y-auto{overflow-y:auto}.p-theme-bg{background-color:var(--p-theme-bg)}.p-wrapper .p-form-wrapper{z-index:4}.p-wrapper .p-canvas-pagination.ant-pagination{padding:16px 0}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-wrapper .p-error-hang-out .ant-form-item-explain-error{opacity:0!important;transform:translateY(-10px)!important;max-height:0!important;overflow:hidden!important;transition:none!important}.p-wrapper .ant-form-item-explain-error{opacity:0;transform:translateY(-10px);max-height:0;overflow:hidden;transition:opacity .3s ease-out .3s,transform .3s ease-out .3s,max-height .3s ease-out .3s}.p-wrapper .ant-form-item-has-error .ant-form-item-explain-error{opacity:1;transform:translateY(0);max-height:100px}.p-wrapper .p-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0;margin-bottom:-.5em}.p-wrapper .p-canvas-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0}.p-wrapper .ant-form .ant-form-item{margin-bottom:0}.p-wrapper .ant-form .ant-form-item.p-required .ant-form-item-label>label:before{display:inline-block;margin-inline-end:4px;color:#ff4d4f;font-size:14px;font-family:SimSun,sans-serif;line-height:1;content:"*"}.p-wrapper .ant-form .ant-form-item .ant-form-item-label{display:flex;align-items:start;justify-content:flex-end}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label{white-space:break-spaces;align-items:flex-start;height:fit-content;padding-top:.36em}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label:after{padding-left:4px;margin-inline-start:unset}.p-wrapper .ant-form.ant-form-vertical .ant-form-item .ant-form-item-label{justify-content:flex-start;font-weight:600}.p-wrapper .ant-table-sticky-scroll{visibility:hidden}.p-wrapper .ant-table-header.ant-table-sticky-holder:before{content:"";width:100%;position:absolute;height:22px;display:block;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);top:-16px}.p-wrapper .ant-table-wrapper .ant-table-pagination.ant-pagination{margin:unset;padding:16px 0}.p-wrapper .h-lack .ant-table-wrapper .ant-table-pagination.ant-pagination{padding:unset;margin-top:8px}.p-wrapper .p-inner-scroll>.ant-table-wrapper{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container{height:100%;display:flex;flex-direction:column}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table{flex:1;height:0;overflow-y:hidden;border-radius:unset}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-container>.ant-table-body{position:relative}.p-wrapper .ant-pagination-options .ant-select{width:100px}.p-wrapper .ant-table-cell:not(.normal-break){word-break:break-all}.p-error-group-tab{position:relative;overflow:visible;color:#f5222d!important}.p-error-group-tab:after{content:"🏷️";position:absolute;top:-1em;right:0;width:1em;height:1em;font-size:.8em;animation:heartbeat 2s infinite}.ant-picker-dropdown .ant-picker-footer{padding-left:4px}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-error-hang-out .ant-form-item-explain-error{display:none}.no-error-border{border-color:#d9d9d9!important}.no-error-border:focus{border-color:#4096ff!important}@media (max-width: 575px){.p-wrapper .ant-form .ant-form-item .ant-form-item-label{justify-content:flex-start}}.p-content-align-right.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:flex-end;align-items:center;text-align:right}.p-content-align-center.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:center;align-items:center;text-align:center}@keyframes heartbeat{0%{transform:scale(1)}6%{transform:scale(1.22)}12%{transform:scale(1)}18%{transform:scale(1.18)}24%{transform:scale(1)}48%{transform:scale(1)}54%{transform:scale(1.22)}60%{transform:scale(1)}66%{transform:scale(1.18)}72%{transform:scale(1)}to{transform:scale(1)}}
1
+ @charset "UTF-8";.collapsible-card[data-v-e5901b25]{background-color:#fff;border-color:#f0f0f0}.collapsible-card[data-v-e5901b25] .ant-collapse-header{padding:0 12px;min-height:38px;display:flex;align-items:center;font-weight:600}.collapsible-card[data-v-e5901b25] .ant-collapse-content{border-color:#f0f0f0}.collapsible-card[data-v-e5901b25] .ant-collapse-content .ant-collapse-content-box{padding:var(--collapsible-card-body-padding, 12px)}.collapsible-card[data-v-e5901b25] .ant-collapse-item{border-color:#f0f0f0}:root{--p-theme-bg: #fff}.p-pane{background-color:var(--p-theme-bg);padding:16px;border-radius:4px}.text-slate-5{color:#64748b}.w-full{width:100%}.cursor-pointer{cursor:pointer}.py-4x{padding-top:4px;padding-bottom:4px}.px-2x{padding-left:2px;padding-right:2px}.pl-4x{padding-left:1em}.pl-8{padding-left:2em}.h-0{height:0}.h-full{height:100%}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-4px{gap:4px}.gap-8px{gap:8px}.pt-8px{padding-top:8px}.px-16px{padding-left:16px;padding-right:16px}.mt-4px{margin-top:4px}.text-right{text-align:right}.overflow-y-auto{overflow-y:auto}.p-theme-bg{background-color:var(--p-theme-bg)}.p-wrapper .p-form-wrapper{z-index:4}.p-wrapper .p-canvas-pagination.ant-pagination{padding:16px 0}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-wrapper .p-error-hang-out .ant-form-item-explain-error{opacity:0!important;transform:translateY(-10px)!important;max-height:0!important;overflow:hidden!important;transition:none!important}.p-wrapper .ant-form-item-explain-error{opacity:0;transform:translateY(-10px);max-height:0;overflow:hidden;transition:opacity .3s ease-out .3s,transform .3s ease-out .3s,max-height .3s ease-out .3s}.p-wrapper .ant-form-item-has-error .ant-form-item-explain-error{opacity:1;transform:translateY(0);max-height:100px}.p-wrapper .p-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0;margin-bottom:-.5em}.p-wrapper .p-canvas-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0}.p-wrapper .ant-form .ant-form-item{margin-bottom:0}.p-wrapper .ant-form .ant-form-item.p-required .ant-form-item-label>label:before{display:inline-block;margin-inline-end:4px;color:#ff4d4f;font-size:14px;font-family:SimSun,sans-serif;line-height:1;content:"*"}.p-wrapper .ant-form .ant-form-item .ant-form-item-label{display:flex;align-items:start;justify-content:flex-end}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label{white-space:break-spaces;align-items:flex-start;height:fit-content;padding-top:.36em}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label:after{padding-left:4px;margin-inline-start:unset}.p-wrapper .ant-form.ant-form-vertical .ant-form-item .ant-form-item-label{justify-content:flex-start;font-weight:600}.p-wrapper .ant-table-sticky-scroll{visibility:hidden}.p-wrapper .ant-table-header.ant-table-sticky-holder:before{content:"";width:100%;position:absolute;height:22px;display:block;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);top:-16px}.p-wrapper .ant-table-wrapper .ant-table-pagination.ant-pagination{margin:unset;padding:16px 0}.p-wrapper .h-lack .ant-table-wrapper .ant-table-pagination.ant-pagination{padding:unset;margin-top:8px}.p-wrapper .p-inner-scroll>.ant-table-wrapper{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container{height:100%;display:flex;flex-direction:column}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table{flex:1;height:0;overflow-y:hidden;border-radius:unset}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-container>.ant-table-body{position:relative}.p-wrapper .ant-pagination-options .ant-select{width:100px}.p-wrapper .ant-table-cell:not(.normal-break){word-break:break-all}.p-error-group-tab{position:relative;overflow:visible;color:#f5222d!important}.p-error-group-tab:after{content:"🏷️";position:absolute;top:-1em;right:0;width:1em;height:1em;font-size:.8em;animation:heartbeat 2s infinite}.ant-picker-dropdown .ant-picker-footer{padding-left:4px}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-error-hang-out .ant-form-item-explain-error{display:none}.no-error-border{border-color:#d9d9d9!important}.no-error-border:focus{border-color:#4096ff!important}@media (max-width: 575px){.p-wrapper .ant-form .ant-form-item .ant-form-item-label{justify-content:flex-start}}.p-content-align-right.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:flex-end;align-items:center;text-align:right}.p-content-align-center.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:center;align-items:center;text-align:center}@keyframes heartbeat{0%{transform:scale(1)}6%{transform:scale(1.22)}12%{transform:scale(1)}18%{transform:scale(1.18)}24%{transform:scale(1)}48%{transform:scale(1)}54%{transform:scale(1.22)}60%{transform:scale(1)}66%{transform:scale(1.18)}72%{transform:scale(1)}to{transform:scale(1)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -46,7 +46,7 @@
46
46
  "email": "adoin@qq.com"
47
47
  },
48
48
  "dependencies": {
49
- "e-virt-table": "^1.2.20",
49
+ "e-virt-table": "^1.2.27",
50
50
  "uuid": "^10.0.0",
51
51
  "xe-utils": "^3.7.6"
52
52
  },
@@ -120,6 +120,10 @@ export interface PFormGroupProps<F extends Recordable = Recordable> {
120
120
  tabLabel?: string;
121
121
  editAble?: boolean;
122
122
  showAdd?: boolean;
123
+ /* 是否启用折叠 */
124
+ collapsible?: boolean;
125
+ /** 是否默认折叠 */
126
+ defaultCollapsed?: boolean
123
127
  lazyErrorMark?: boolean;
124
128
  forceRender?: boolean;
125
129
  /* 是否保持连续编号 */
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+
4
+ interface Props {
5
+ /** 是否默认折叠 */
6
+ defaultCollapsed?: boolean
7
+ title?: string
8
+ /** 是否可以折叠 */
9
+ collapsible?: boolean
10
+ }
11
+
12
+ const props = withDefaults(defineProps<Props>(), {
13
+ title: undefined,
14
+ defaultCollapsed: false,
15
+ collapsible: false,
16
+ })
17
+ const slots = defineSlots<{
18
+ title: () => any
19
+ }>()
20
+ const activeKey = ref(props.defaultCollapsed ? [] : ['content'])
21
+ defineExpose({
22
+ collapse: () => {
23
+ activeKey.value = []
24
+ },
25
+ expand: () => {
26
+ activeKey.value = ['content']
27
+ },
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <a-collapse
33
+ v-if="collapsible"
34
+ v-model:active-key="activeKey"
35
+ class="collapsible-card"
36
+ >
37
+ <a-collapse-panel key="content" force-render :header="title">
38
+ <template v-if="slots.title" #header>
39
+ <slot name="title" />
40
+ </template>
41
+ <slot />
42
+ </a-collapse-panel>
43
+ </a-collapse>
44
+ <a-card v-else size="small" :title="title">
45
+ <template v-if="slots.title" #title>
46
+ <slot name="title" />
47
+ </template>
48
+ <slot />
49
+ </a-card>
50
+ </template>
51
+
52
+ <style scoped lang="scss">
53
+ //样式改成card样式
54
+ .collapsible-card {
55
+ background-color: #fff;
56
+ border-color: #f0f0f0;
57
+ :deep(.ant-collapse-header) {
58
+ padding: 0 12px;
59
+ min-height: 38px;
60
+ display: flex;
61
+ align-items: center;
62
+ font-weight: 600;
63
+ }
64
+ :deep(.ant-collapse-content) {
65
+ border-color: #f0f0f0;
66
+ .ant-collapse-content-box {
67
+ padding: var(--collapsible-card-body-padding, 12px);
68
+ }
69
+ }
70
+ :deep(.ant-collapse-item) {
71
+ border-color: #f0f0f0;
72
+ }
73
+ }
74
+ </style>
@@ -21,6 +21,7 @@
21
21
  import { v4 as uuidv4 } from 'uuid';
22
22
  import { antFormatters } from '@/utils/AFormatters';
23
23
  import { getCanvasTableDefaults } from '@/utils/config';
24
+ import { watchPreviousDeep } from '@/utils/core';
24
25
 
25
26
  const emit = defineEmits<{
26
27
  (e: 'change', value: any[]): void; // 需要默认实现change,不能动态绑定
@@ -197,7 +198,7 @@
197
198
  },
198
199
  { deep: true },
199
200
  );
200
- watch(
201
+ watchPreviousDeep(
201
202
  () => props.columns,
202
203
  (newValue, oldValue) => {
203
204
  if (!isEqual(newValue, oldValue)) {
@@ -1,46 +1,50 @@
1
1
  <script setup lang="ts" generic="T extends Recordable = Recordable">
2
- import type { PFormItemProps } from '#/antProxy'
3
- import { defaultItemResponsive } from '@/utils/core';
4
- import RenderAntItem from '@/components/RenderAntItem';
5
- import RenderItemSlots from '@/components/RenderItemSlots';
6
- import { InfoCircleOutlined } from '@ant-design/icons-vue'
7
- import { v4 as uuid_v4 } from 'uuid'
8
- import { ref, watch } from 'vue'
9
- import { isEqual,debounce, isFunction, omit } from 'xe-utils'
2
+ import type { PFormItemProps } from '#/antProxy';
3
+ import { defaultItemResponsive, watchPreviousDeep } from '@/utils/core';
4
+ import RenderAntItem from '@/components/RenderAntItem';
5
+ import RenderItemSlots from '@/components/RenderItemSlots';
6
+ import { InfoCircleOutlined } from '@ant-design/icons-vue';
7
+ import { v4 as uuid_v4 } from 'uuid';
8
+ import { ref } from 'vue';
9
+ import { isEqual, debounce, isFunction, omit } from 'xe-utils';
10
10
 
11
- const props = defineProps<{
12
- item: PFormItemProps<T>
13
- formData: T
14
- }>()
15
- const emit = defineEmits<{
16
- (e: 'trigger', cusFields?: string | string[]): void
17
- (e: 'reset'): void
18
- }>()
19
- const hangOut = ref(false)
20
- const renderFormKey = ref(uuid_v4())
21
- const handleDelayTrigger = (cusFields?: string | string[], time?: number) => {
22
- const delayTime = time ?? 222
23
- hangOut.value = true
24
- setTimeout(() => {
25
- hangOut.value = false
26
- emit('trigger', cusFields)
27
- }, delayTime)
28
- }
29
- const handleTrigger = (cusFields?: string | string[]) => {
30
- emit('trigger', cusFields)
31
- }
32
- const resetFormData = () => {
33
- emit('reset')
34
- }
35
- const refreshCol = () => {
36
- renderFormKey.value = uuid_v4()
37
- }
38
- const debounceRefreshCol = debounce(refreshCol, 100)
39
- watch(() => props.item, (cur, old) => {
40
- if (!isEqual(cur, old)) {
41
- debounceRefreshCol()
42
- }
43
- }, { deep: true })
11
+ const props = defineProps<{
12
+ item: PFormItemProps<T>;
13
+ formData: T;
14
+ }>();
15
+ const emit = defineEmits<{
16
+ (e: 'trigger', cusFields?: string | string[]): void;
17
+ (e: 'reset'): void;
18
+ }>();
19
+ const hangOut = ref(false);
20
+ const renderFormKey = ref(uuid_v4());
21
+ const handleDelayTrigger = (cusFields?: string | string[], time?: number) => {
22
+ const delayTime = time ?? 222;
23
+ hangOut.value = true;
24
+ setTimeout(() => {
25
+ hangOut.value = false;
26
+ emit('trigger', cusFields);
27
+ }, delayTime);
28
+ };
29
+ const handleTrigger = (cusFields?: string | string[]) => {
30
+ emit('trigger', cusFields);
31
+ };
32
+ const resetFormData = () => {
33
+ emit('reset');
34
+ };
35
+ const refreshCol = () => {
36
+ renderFormKey.value = uuid_v4();
37
+ };
38
+ const debounceRefreshCol = debounce(refreshCol, 100);
39
+ watchPreviousDeep(
40
+ () => props.item,
41
+ (cur, old) => {
42
+ if (!isEqual(cur, old)) {
43
+ debounceRefreshCol();
44
+ }
45
+ },
46
+ { deep: true },
47
+ );
44
48
  </script>
45
49
 
46
50
  <template>
@@ -58,7 +62,18 @@ watch(() => props.item, (cur, old) => {
58
62
  :label="item.title"
59
63
  :name="item.field"
60
64
  :wrapper-col="item.wrapperCol ?? (item.title ? undefined : { span: 24 })"
61
- v-bind="omit(item, ['field', 'title', 'span', 'col', 'wrapperCol', 'itemRender', 'forceRequired', 'tooltip'])"
65
+ v-bind="
66
+ omit(item, [
67
+ 'field',
68
+ 'title',
69
+ 'span',
70
+ 'col',
71
+ 'wrapperCol',
72
+ 'itemRender',
73
+ 'forceRequired',
74
+ 'tooltip',
75
+ ])
76
+ "
62
77
  >
63
78
  <template v-if="item.slots?.title" #label>
64
79
  <component :is="item.slots.title" />
@@ -82,7 +97,10 @@ watch(() => props.item, (cur, old) => {
82
97
  />
83
98
  <span v-else />
84
99
  <template v-if="item.tooltipConfig" #tooltip>
85
- <a-tooltip v-if="isFunction(item.tooltipConfig.title)" v-bind="omit(item.tooltipConfig, ['title'])">
100
+ <a-tooltip
101
+ v-if="isFunction(item.tooltipConfig.title)"
102
+ v-bind="omit(item.tooltipConfig, ['title'])"
103
+ >
86
104
  <info-circle-outlined class="cursor-pointer py-4 px-2" />
87
105
  <template #title>
88
106
  <div v-html="item.tooltipConfig.title()" />
@@ -19,11 +19,12 @@
19
19
  import { valued } from '@/utils/is';
20
20
  import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
21
21
  import { $warning } from '@/hooks/useMessage';
22
+ import CollapseCard from './CollapseCard.vue';
22
23
 
23
24
  const useForm = Form.useForm;
24
25
  const tabsRef = ref<InstanceType<typeof Tabs>>();
25
26
  const props = defineProps<PFormGroupProps<F>>();
26
- const rootRef = ref<InstanceType<typeof ACard>>();
27
+ const rootRef = ref<InstanceType<typeof CollapseCard>>();
27
28
  const model = defineModel({
28
29
  type: Array as PropType<Partial<F & { __index: number }>[]>,
29
30
  default: () => [],
@@ -52,7 +53,7 @@
52
53
  { content: '复制', code: 'copy' },
53
54
  { content: '删除', code: 'delete' },
54
55
  ];
55
- const getPopupContainer = (el) =>
56
+ const getPopupContainer = (el: HTMLElement) =>
56
57
  el?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement ??
57
58
  rootRef.value?.$el ??
58
59
  document.body;
@@ -146,6 +147,12 @@
146
147
  }
147
148
  });
148
149
  defineExpose({
150
+ collapse: () => {
151
+ rootRef.value?.collapse?.();
152
+ },
153
+ expand: () => {
154
+ rootRef.value?.expand?.();
155
+ },
149
156
  activeKey: computed(() => activeKey.value),
150
157
  setActiveKey,
151
158
  validateAll: () => {
@@ -227,7 +234,7 @@
227
234
  });
228
235
  </script>
229
236
  <template>
230
- <a-card ref="rootRef" :title="title" size="small">
237
+ <collapse-card ref="rootRef" :title="title" size="small" :collapsible="collapsible" :default-collapsed="defaultCollapsed">
231
238
  <a-spin v-if="loading" class="w-full" />
232
239
  <a-tabs
233
240
  v-else
@@ -281,5 +288,5 @@
281
288
  />
282
289
  </a-tab-pane>
283
290
  </a-tabs>
284
- </a-card>
291
+ </collapse-card>
285
292
  </template>
@@ -1,7 +1,8 @@
1
1
  import { ColumnProps, Responsive } from '#/antProxy';
2
2
  import { TableColumnGroupType, TableColumnType } from 'ant-design-vue';
3
- import { isArray, isNumber, omit, zipObject } from 'xe-utils';
3
+ import { clone, isArray, isNumber, omit, zipObject } from 'xe-utils';
4
4
  import { valued } from '@/utils/is';
5
+ import { toValue, watch, WatchCallback, WatchOptions, WatchSource } from 'vue';
5
6
 
6
7
  export const cleanCol = (col: ColumnProps): TableColumnType | TableColumnGroupType<Recordable> => {
7
8
  return {
@@ -50,3 +51,23 @@ export const getButtonResponsive = (itemResponsive: number | Responsive[]) => {
50
51
  ),
51
52
  );
52
53
  };
54
+
55
+ export function watchPreviousDeep<T extends object>(
56
+ source: WatchSource<T>,
57
+ cb: (value: T, oldValue: T, onCleanup: () => void) => void,
58
+ options?: WatchOptions,
59
+ ) {
60
+ const val = toValue(source);
61
+ if (typeof val !== 'object' || val === null) {
62
+ return watch(source, cb as WatchCallback<T>, options);
63
+ }
64
+ let previousValue = clone(val) as T;
65
+ return watch(
66
+ source,
67
+ (crtValue, _, onCleanup) => {
68
+ cb(crtValue as T, previousValue, onCleanup as () => void);
69
+ previousValue = clone(crtValue) as T;
70
+ },
71
+ options,
72
+ );
73
+ }