@tmagic/form 1.1.6 → 1.2.0-beta.10

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.
Files changed (76) hide show
  1. package/dist/tmagic-form.mjs +2318 -2632
  2. package/dist/tmagic-form.mjs.map +1 -1
  3. package/dist/tmagic-form.umd.js +2341 -2656
  4. package/dist/tmagic-form.umd.js.map +1 -1
  5. package/package.json +5 -5
  6. package/src/Form.vue +123 -158
  7. package/src/FormDialog.vue +140 -158
  8. package/src/containers/Col.vue +22 -38
  9. package/src/containers/Container.vue +138 -171
  10. package/src/containers/Fieldset.vue +12 -8
  11. package/src/containers/GroupList.vue +80 -112
  12. package/src/containers/GroupListItem.vue +87 -124
  13. package/src/containers/Panel.vue +26 -49
  14. package/src/containers/Row.vue +18 -40
  15. package/src/containers/Step.vue +36 -48
  16. package/src/containers/Table.vue +449 -479
  17. package/src/containers/Tabs.vue +92 -118
  18. package/src/fields/Cascader.vue +88 -136
  19. package/src/fields/Checkbox.vue +46 -50
  20. package/src/fields/CheckboxGroup.vue +39 -35
  21. package/src/fields/ColorPicker.vue +5 -3
  22. package/src/fields/Date.vue +20 -26
  23. package/src/fields/DateTime.vue +31 -39
  24. package/src/fields/Daterange.vue +4 -3
  25. package/src/fields/Display.vue +1 -1
  26. package/src/fields/DynamicField.vue +63 -77
  27. package/src/fields/Hidden.vue +1 -1
  28. package/src/fields/Link.vue +65 -86
  29. package/src/fields/Number.vue +32 -34
  30. package/src/fields/RadioGroup.vue +23 -23
  31. package/src/fields/Select.vue +294 -321
  32. package/src/fields/SelectOptionGroups.vue +11 -6
  33. package/src/fields/SelectOptions.vue +5 -3
  34. package/src/fields/Switch.vue +46 -49
  35. package/src/fields/Text.vue +99 -107
  36. package/src/fields/Textarea.vue +32 -44
  37. package/src/fields/Time.vue +19 -30
  38. package/src/index.ts +22 -23
  39. package/src/schema.ts +46 -12
  40. package/src/utils/form.ts +4 -0
  41. package/types/Form.vue.d.ts +211 -111
  42. package/types/FormDialog.vue.d.ts +809 -154
  43. package/types/containers/Col.vue.d.ts +92 -40
  44. package/types/containers/Container.vue.d.ts +122 -65
  45. package/types/containers/Fieldset.vue.d.ts +1 -3
  46. package/types/containers/GroupList.vue.d.ts +86 -53
  47. package/types/containers/GroupListItem.vue.d.ts +97 -67
  48. package/types/containers/Panel.vue.d.ts +92 -39
  49. package/types/containers/Row.vue.d.ts +92 -39
  50. package/types/containers/Step.vue.d.ts +102 -42
  51. package/types/containers/Table.vue.d.ts +157 -130
  52. package/types/containers/Tabs.vue.d.ts +93 -50
  53. package/types/fields/Cascader.vue.d.ts +95 -71
  54. package/types/fields/Checkbox.vue.d.ts +95 -56
  55. package/types/fields/CheckboxGroup.vue.d.ts +95 -53
  56. package/types/fields/ColorPicker.vue.d.ts +1 -3
  57. package/types/fields/Date.vue.d.ts +95 -54
  58. package/types/fields/DateTime.vue.d.ts +95 -54
  59. package/types/fields/Daterange.vue.d.ts +1 -3
  60. package/types/fields/Display.vue.d.ts +1 -3
  61. package/types/fields/DynamicField.vue.d.ts +95 -64
  62. package/types/fields/Hidden.vue.d.ts +1 -3
  63. package/types/fields/Link.vue.d.ts +60 -657
  64. package/types/fields/Number.vue.d.ts +99 -56
  65. package/types/fields/RadioGroup.vue.d.ts +96 -52
  66. package/types/fields/Select.vue.d.ts +97 -65
  67. package/types/fields/SelectOptionGroups.vue.d.ts +1 -3
  68. package/types/fields/SelectOptions.vue.d.ts +1 -3
  69. package/types/fields/Switch.vue.d.ts +95 -56
  70. package/types/fields/Text.vue.d.ts +98 -57
  71. package/types/fields/Textarea.vue.d.ts +100 -60
  72. package/types/fields/Time.vue.d.ts +95 -55
  73. package/types/index.d.ts +0 -1
  74. package/types/schema.d.ts +38 -9
  75. package/src/utils/fieldProps.ts +0 -39
  76. package/types/utils/fieldProps.d.ts +0 -21
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.6",
2
+ "version": "1.2.0-beta.10",
3
3
  "name": "@tmagic/form",
4
4
  "sideEffects": [
5
5
  "dist/*",
@@ -35,14 +35,13 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@element-plus/icons-vue": "^2.0.9",
38
- "@tmagic/utils": "1.1.6",
39
- "element-plus": "^2.2.17",
38
+ "@tmagic/design": "1.2.0-beta.10",
39
+ "@tmagic/utils": "1.2.0-beta.10",
40
40
  "lodash-es": "^4.17.21",
41
41
  "sortablejs": "^1.14.0",
42
42
  "vue": "^3.2.37"
43
43
  },
44
44
  "peerDependencies": {
45
- "element-plus": "^2.2.17",
46
45
  "vue": "^3.2.37"
47
46
  },
48
47
  "devDependencies": {
@@ -57,6 +56,7 @@
57
56
  "sass": "^1.35.1",
58
57
  "typescript": "^4.7.4",
59
58
  "vite": "^3.1.3",
60
- "vue-tsc": "^0.39.4"
59
+ "vite-plugin-vue-setup-extend": "^0.4.0",
60
+ "vue-tsc": "^1.0.8"
61
61
  }
62
62
  }
package/src/Form.vue CHANGED
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <el-form
2
+ <TMagicForm
3
3
  class="m-form"
4
- ref="elForm"
4
+ ref="tMagicForm"
5
5
  :model="values"
6
6
  :label-width="labelWidth"
7
7
  :disabled="disabled"
@@ -10,7 +10,7 @@
10
10
  :label-position="labelPosition"
11
11
  >
12
12
  <template v-if="initialized && Array.isArray(config)">
13
- <m-form-container
13
+ <Container
14
14
  v-for="(item, index) in config"
15
15
  :key="item[keyProp] ?? index"
16
16
  :config="item"
@@ -19,175 +19,140 @@
19
19
  :step-active="stepActive"
20
20
  :size="size"
21
21
  @change="changeHandler"
22
- ></m-form-container>
22
+ ></Container>
23
23
  </template>
24
- </el-form>
24
+ </TMagicForm>
25
25
  </template>
26
26
 
27
- <script lang="ts">
28
- import { defineComponent, PropType, provide, reactive, ref, toRaw, watch } from 'vue';
29
- import { cloneDeep, isEqual } from 'lodash-es';
27
+ <script setup lang="ts" name="MForm">
28
+ import { provide, reactive, ref, toRaw, watch, watchEffect } from 'vue';
29
+ import cloneDeep from 'lodash-es/cloneDeep';
30
+ import isEqual from 'lodash-es/isEqual';
30
31
 
32
+ import { TMagicForm } from '@tmagic/design';
33
+
34
+ import Container from './containers/Container.vue';
31
35
  import { getConfig } from './utils/config';
32
36
  import { initValue } from './utils/form';
33
- import { FormConfig, FormState, FormValue } from './schema';
34
-
35
- interface ValidateError {
36
- message: string;
37
- field: string;
38
- }
39
-
40
- export default defineComponent({
41
- name: 'm-form',
42
-
43
- props: {
44
- // 表单初始化值
45
- initValues: {
46
- type: Object,
47
- required: true,
48
- default: () => ({}),
49
- },
50
-
51
- parentValues: {
52
- type: Object,
53
- default: () => ({}),
54
- },
55
-
56
- // 表单配置
57
- config: {
58
- type: Array as PropType<FormConfig>,
59
- required: true,
60
- default: () => [],
61
- },
62
-
63
- labelWidth: {
64
- type: String,
65
- default: () => '200px',
66
- },
67
-
68
- disabled: {
69
- type: Boolean,
70
- default: () => false,
71
- },
72
-
73
- height: {
74
- type: String,
75
- default: () => 'auto',
76
- },
77
-
78
- stepActive: {
79
- type: [String, Number],
80
- default: () => 1,
81
- },
82
-
83
- size: {
84
- type: String as PropType<'small' | 'default' | 'large'>,
85
- },
86
-
87
- inline: {
88
- type: Boolean,
89
- default: false,
90
- },
91
-
92
- labelPosition: {
93
- type: String,
94
- default: 'right',
95
- },
96
-
97
- keyProp: {
98
- type: String,
99
- default: '__key',
100
- },
101
-
102
- popperClass: {
103
- type: String,
104
- },
37
+ import type { FormConfig, FormState, FormValue, ValidateError } from './schema';
38
+
39
+ const props = withDefaults(
40
+ defineProps<{
41
+ config: FormConfig;
42
+ initValues: Object;
43
+ parentValues?: Object;
44
+ labelWidth?: string;
45
+ disabled?: boolean;
46
+ height?: string;
47
+ stepActive?: string | number;
48
+ size?: 'small' | 'default' | 'large';
49
+ inline?: boolean;
50
+ labelPosition?: string;
51
+ keyProp?: string;
52
+ popperClass?: string;
53
+ }>(),
54
+ {
55
+ config: () => [],
56
+ initValues: () => ({}),
57
+ parentValues: () => ({}),
58
+ labelWidth: '200px',
59
+ disabled: false,
60
+ height: 'auto',
61
+ stepActive: 1,
62
+ inline: false,
63
+ labelPosition: 'right',
64
+ keyProp: '__key',
65
+ },
66
+ );
67
+
68
+ const emit = defineEmits(['change', 'field-input', 'field-change']);
69
+
70
+ const tMagicForm = ref<InstanceType<typeof TMagicForm>>();
71
+ const initialized = ref(false);
72
+ const values = ref<FormValue>({});
73
+ const fields = new Map<string, any>();
74
+
75
+ const requestFuc = getConfig('request') as Function;
76
+
77
+ const formState: FormState = reactive<FormState>({
78
+ keyProp: props.keyProp,
79
+ popperClass: props.popperClass,
80
+ config: props.config,
81
+ initValues: props.initValues,
82
+ parentValues: props.parentValues,
83
+ values,
84
+ $emit: emit as (event: string, ...args: any[]) => void,
85
+ fields,
86
+ setField: (prop: string, field: any) => fields.set(prop, field),
87
+ getField: (prop: string) => fields.get(prop),
88
+ deleteField: (prop: string) => fields.delete(prop),
89
+ post: (options: any) => {
90
+ if (requestFuc) {
91
+ return requestFuc({
92
+ ...options,
93
+ method: 'POST',
94
+ });
95
+ }
105
96
  },
97
+ });
106
98
 
107
- emits: ['change', 'field-input', 'field-change'],
99
+ watchEffect(() => {
100
+ formState.initValues = props.initValues;
101
+ formState.config = props.config;
102
+ formState.keyProp = props.keyProp;
103
+ formState.popperClass = props.popperClass;
104
+ formState.parentValues = props.parentValues;
105
+ });
108
106
 
109
- setup(props, { emit }) {
110
- // InstanceType<typeof ElForm>,构建types的时候会出错
111
- const elForm = ref<any>();
112
- const initialized = ref(false);
113
- const values = ref<FormValue>({});
114
- const fields = new Map<string, any>();
107
+ provide('mForm', formState);
115
108
 
116
- const requestFuc = getConfig('request') as Function;
109
+ watch(
110
+ [() => props.config, () => props.initValues],
111
+ ([config], [preConfig]) => {
112
+ if (!isEqual(toRaw(config), toRaw(preConfig))) {
113
+ initialized.value = false;
114
+ }
117
115
 
118
- const formState: FormState = reactive<FormState>({
119
- keyProp: props.keyProp,
120
- popperClass: props.popperClass,
121
- config: props.config,
116
+ initValue(formState, {
122
117
  initValues: props.initValues,
123
- parentValues: props.parentValues,
124
- values,
125
- $emit: emit as (event: string, ...args: any[]) => void,
126
- fields,
127
- setField: (prop: string, field: any) => fields.set(prop, field),
128
- getField: (prop: string) => fields.get(prop),
129
- deleteField: (prop: string) => fields.delete(prop),
130
- post: (options: any) => {
131
- if (requestFuc) {
132
- return requestFuc({
133
- ...options,
134
- method: 'POST',
135
- });
136
- }
137
- },
118
+ config: props.config,
119
+ }).then((value) => {
120
+ values.value = value;
121
+ initialized.value = true;
138
122
  });
139
-
140
- provide('mForm', formState);
141
-
142
- watch(
143
- [() => props.config, () => props.initValues],
144
- ([config], [preConfig]) => {
145
- if (!isEqual(toRaw(config), toRaw(preConfig))) {
146
- initialized.value = false;
147
- }
148
-
149
- initValue(formState, {
150
- initValues: props.initValues,
151
- config: props.config,
152
- }).then((value) => {
153
- values.value = value;
154
- initialized.value = true;
123
+ },
124
+ { immediate: true },
125
+ );
126
+
127
+ const changeHandler = () => {
128
+ emit('change', values.value);
129
+ };
130
+
131
+ defineExpose({
132
+ values,
133
+ formState,
134
+ initialized,
135
+
136
+ changeHandler,
137
+
138
+ resetForm: () => tMagicForm.value?.resetFields(),
139
+
140
+ submitForm: async (native?: boolean): Promise<any> => {
141
+ try {
142
+ await tMagicForm.value?.validate();
143
+ return native ? values.value : cloneDeep(toRaw(values.value));
144
+ } catch (invalidFields: any) {
145
+ const error: string[] = [];
146
+
147
+ Object.entries(invalidFields).forEach(([, ValidateError]) => {
148
+ (ValidateError as ValidateError[]).forEach(({ field, message }) => {
149
+ if (field && message) error.push(`${field} -> ${message}`);
150
+ if (field && !message) error.push(`${field} -> 出现错误`);
151
+ if (!field && message) error.push(`${message}`);
155
152
  });
156
- },
157
- { immediate: true },
158
- );
159
-
160
- return {
161
- initialized,
162
- values,
163
- elForm,
164
-
165
- formState,
166
-
167
- changeHandler: () => {
168
- emit('change', values.value);
169
- },
170
-
171
- resetForm: () => elForm.value?.resetFields(),
172
-
173
- submitForm: async (native?: boolean): Promise<any> => {
174
- try {
175
- await elForm.value?.validate();
176
- return native ? values.value : cloneDeep(toRaw(values.value));
177
- } catch (invalidFields: any) {
178
- const error: string[] = [];
179
-
180
- Object.entries(invalidFields).forEach(([, ValidateError]) => {
181
- (ValidateError as ValidateError[]).forEach(({ field, message }) => {
182
- if (field && message) error.push(`${field} -> ${message}`);
183
- if (field && !message) error.push(`${field} -> 出现错误`);
184
- if (!field && message) error.push(`${message}`);
185
- });
186
- });
187
- throw new Error(error.join('<br>'));
188
- }
189
- },
190
- };
153
+ });
154
+ throw new Error(error.join('<br>'));
155
+ }
191
156
  },
192
157
  });
193
158
  </script>
@@ -1,171 +1,153 @@
1
1
  <template>
2
- <teleport to="body">
3
- <div class="m-form-dialog" v-show="dialogVisible">
4
- <el-dialog
5
- v-model="dialogVisible"
6
- top="20px"
7
- :title="title"
8
- :width="width"
9
- :fullscreen="fullscreen"
10
- :close-on-click-modal="false"
11
- @close="closeHandler"
12
- >
13
- <div class="m-dialog-body" :style="`max-height: ${bodyHeight}; overflow-y: auto; overflow-x: hidden;`">
14
- <m-form
15
- v-model="stepActive"
16
- ref="form"
17
- :size="size"
18
- :config="config"
19
- :init-values="values"
20
- :parent-values="parentValues"
21
- :label-width="labelWidth"
22
- @change="changeHandler"
23
- ></m-form>
24
- <slot></slot>
25
- </div>
26
-
27
- <template #footer>
28
- <el-row class="dialog-footer">
29
- <el-col :span="12" style="text-align: left">
30
- <div style="min-height: 1px">
31
- <slot name="left"></slot>
32
- </div>
33
- </el-col>
34
- <el-col :span="12">
35
- <slot name="footer">
36
- <el-button @click="cancel" size="small">取 消</el-button>
37
- <el-button v-if="hasStep && stepActive > 1" type="info" size="small" @click="preStep">上一步</el-button>
38
- <el-button v-if="hasStep && stepCount > stepActive" type="info" size="small" @click="nextStep"
39
- >下一步</el-button
40
- >
41
- <el-button v-else type="primary" size="small" :loading="saveFetch" @click="save">{{
42
- confirmText
43
- }}</el-button>
44
- </slot>
45
- </el-col>
46
- </el-row>
47
- </template>
48
- </el-dialog>
2
+ <TMagicDialog
3
+ v-model="dialogVisible"
4
+ class="m-form-dialog"
5
+ top="20px"
6
+ append-to-body
7
+ :title="title"
8
+ :width="width"
9
+ :zIndex="zIndex"
10
+ :fullscreen="fullscreen"
11
+ :close-on-click-modal="false"
12
+ @close="closeHandler"
13
+ >
14
+ <div
15
+ v-if="dialogVisible"
16
+ class="m-dialog-body"
17
+ :style="`max-height: ${bodyHeight}; overflow-y: auto; overflow-x: hidden;`"
18
+ >
19
+ <Form
20
+ v-model="stepActive"
21
+ ref="form"
22
+ :size="size"
23
+ :config="config"
24
+ :init-values="values"
25
+ :parent-values="parentValues"
26
+ :label-width="labelWidth"
27
+ @change="changeHandler"
28
+ ></Form>
29
+ <slot></slot>
49
30
  </div>
50
- </teleport>
31
+
32
+ <template #footer>
33
+ <TMagicRow class="dialog-footer">
34
+ <TMagicCol :span="12" style="text-align: left">
35
+ <div style="min-height: 1px">
36
+ <slot name="left"></slot>
37
+ </div>
38
+ </TMagicCol>
39
+ <TMagicCol :span="12">
40
+ <slot name="footer">
41
+ <TMagicButton @click="cancel" size="small">取 消</TMagicButton>
42
+ <TMagicButton v-if="hasStep && stepActive > 1" type="info" size="small" @click="preStep"
43
+ >上一步</TMagicButton
44
+ >
45
+ <TMagicButton v-if="hasStep && stepCount > stepActive" type="info" size="small" @click="nextStep"
46
+ >下一步</TMagicButton
47
+ >
48
+ <TMagicButton v-else type="primary" size="small" :loading="saveFetch" @click="save">{{
49
+ confirmText
50
+ }}</TMagicButton>
51
+ </slot>
52
+ </TMagicCol>
53
+ </TMagicRow>
54
+ </template>
55
+ </TMagicDialog>
51
56
  </template>
52
57
 
53
- <script lang="ts">
54
- import { computed, defineComponent, PropType, ref } from 'vue';
58
+ <script setup lang="ts" name="MFormDialog">
59
+ import { computed, ref } from 'vue';
60
+
61
+ import { TMagicButton, TMagicCol, TMagicDialog, TMagicRow } from '@tmagic/design';
55
62
 
56
63
  import Form from './Form.vue';
57
64
  import { FormConfig, StepConfig } from './schema';
58
65
 
59
- export default defineComponent({
60
- name: 'm-form-dialog',
61
-
62
- props: {
63
- values: {
64
- type: Object,
65
- default: () => ({}),
66
- },
67
-
68
- parentValues: {
69
- type: Object,
70
- },
71
-
72
- width: [Number, String],
73
-
74
- fullscreen: Boolean,
75
-
76
- title: String,
77
-
78
- config: {
79
- type: Array as PropType<FormConfig>,
80
- required: true,
81
- default: () => [],
82
- },
83
-
84
- labelWidth: [Number, String],
66
+ const props = withDefaults(
67
+ defineProps<{
68
+ config?: FormConfig;
69
+ values?: Object;
70
+ parentValues?: Object;
71
+ width?: string | number;
72
+ labelWidth?: string;
73
+ fullscreen?: boolean;
74
+ title?: string;
75
+ zIndex?: number;
76
+ size?: 'small' | 'default' | 'large';
77
+ confirmText?: string;
78
+ }>(),
79
+ {
80
+ config: () => [],
81
+ values: () => ({}),
82
+ confirmText: '确定',
83
+ },
84
+ );
85
+
86
+ const emit = defineEmits(['close', 'submit', 'error', 'change']);
87
+
88
+ const form = ref<InstanceType<typeof Form>>();
89
+ const dialogVisible = ref(false);
90
+ const saveFetch = ref(false);
91
+ const stepActive = ref(1);
92
+ const bodyHeight = ref(`${document.body.clientHeight - 194}px`);
93
+
94
+ const stepCount = computed(() => {
95
+ const { length } = props.config;
96
+ for (let index = 0; index < length; index++) {
97
+ if (props.config[index].type === 'step') {
98
+ return (props.config[index] as StepConfig).items.length;
99
+ }
100
+ }
101
+ return 0;
102
+ });
85
103
 
86
- size: String as PropType<'small' | 'default' | 'large'>,
104
+ const hasStep = computed(() => {
105
+ const { length } = props.config;
106
+ for (let index = 0; index < length; index++) {
107
+ if (props.config[index].type === 'step') {
108
+ return true;
109
+ }
110
+ }
87
111
 
88
- confirmText: {
89
- type: String,
90
- default: '确定',
91
- },
92
- },
112
+ return false;
113
+ });
93
114
 
94
- emits: ['close', 'submit', 'error', 'change'],
95
-
96
- setup(props, { emit }) {
97
- const form = ref<InstanceType<typeof Form>>();
98
- const dialogVisible = ref(false);
99
- const saveFetch = ref(false);
100
- const stepActive = ref(1);
101
- const bodyHeight = ref(`${document.body.clientHeight - 194}px`);
102
-
103
- const stepCount = computed(() => {
104
- const { length } = props.config;
105
- for (let index = 0; index < length; index++) {
106
- if (props.config[index].type === 'step') {
107
- return (props.config[index] as StepConfig).items.length;
108
- }
109
- }
110
- return 0;
111
- });
112
-
113
- const hasStep = computed(() => {
114
- const { length } = props.config;
115
- for (let index = 0; index < length; index++) {
116
- if (props.config[index].type === 'step') {
117
- return true;
118
- }
119
- }
120
-
121
- return false;
122
- });
123
-
124
- const cancel = () => {
125
- dialogVisible.value = false;
126
- };
127
-
128
- const closeHandler = () => {
129
- stepActive.value = 1;
130
- emit('close');
131
- };
132
-
133
- const save = async () => {
134
- try {
135
- const values = await form.value?.submitForm();
136
- emit('submit', values);
137
- } catch (e) {
138
- emit('error', e);
139
- }
140
- };
141
-
142
- const preStep = () => {
143
- stepActive.value -= 1;
144
- };
145
-
146
- const nextStep = () => {
147
- stepActive.value += 1;
148
- };
149
-
150
- const changeHandler = (value: any) => {
151
- emit('change', value);
152
- };
153
-
154
- return {
155
- form,
156
- saveFetch,
157
- stepActive,
158
- dialogVisible,
159
- bodyHeight,
160
- stepCount,
161
- hasStep,
162
- cancel,
163
- closeHandler,
164
- save,
165
- preStep,
166
- nextStep,
167
- changeHandler,
168
- };
169
- },
115
+ const cancel = () => {
116
+ dialogVisible.value = false;
117
+ };
118
+
119
+ const closeHandler = () => {
120
+ stepActive.value = 1;
121
+ emit('close');
122
+ };
123
+
124
+ const save = async () => {
125
+ try {
126
+ const values = await form.value?.submitForm();
127
+ emit('submit', values);
128
+ } catch (e) {
129
+ emit('error', e);
130
+ }
131
+ };
132
+
133
+ const preStep = () => {
134
+ stepActive.value -= 1;
135
+ };
136
+
137
+ const nextStep = () => {
138
+ stepActive.value += 1;
139
+ };
140
+
141
+ const changeHandler = (value: any) => {
142
+ emit('change', value);
143
+ };
144
+
145
+ defineExpose({
146
+ form,
147
+ saveFetch,
148
+ dialogVisible,
149
+
150
+ cancel,
151
+ save,
170
152
  });
171
153
  </script>