@tmagic/form 1.0.0-beta.1

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 (94) hide show
  1. package/dist/style.css +161 -0
  2. package/dist/tmagic-form.es.js +3749 -0
  3. package/dist/tmagic-form.es.js.map +1 -0
  4. package/dist/tmagic-form.umd.js +3790 -0
  5. package/dist/tmagic-form.umd.js.map +1 -0
  6. package/dist/types/src/Form.vue.d.ts +304 -0
  7. package/dist/types/src/FormDialog.vue.d.ts +641 -0
  8. package/dist/types/src/containers/Container.vue.d.ts +69 -0
  9. package/dist/types/src/containers/Fieldset.vue.d.ts +56 -0
  10. package/dist/types/src/containers/GroupList.vue.d.ts +56 -0
  11. package/dist/types/src/containers/GroupListItem.vue.d.ts +72 -0
  12. package/dist/types/src/containers/Panel.vue.d.ts +41 -0
  13. package/dist/types/src/containers/Row.vue.d.ts +42 -0
  14. package/dist/types/src/containers/Step.vue.d.ts +45 -0
  15. package/dist/types/src/containers/Table.vue.d.ts +1401 -0
  16. package/dist/types/src/containers/Tabs.vue.d.ts +45 -0
  17. package/dist/types/src/fields/Cascader.vue.d.ts +1748 -0
  18. package/dist/types/src/fields/Checkbox.vue.d.ts +59 -0
  19. package/dist/types/src/fields/CheckboxGroup.vue.d.ts +56 -0
  20. package/dist/types/src/fields/Date.vue.d.ts +58 -0
  21. package/dist/types/src/fields/DateTime.vue.d.ts +57 -0
  22. package/dist/types/src/fields/Daterange.vue.d.ts +57 -0
  23. package/dist/types/src/fields/Display.vue.d.ts +3 -0
  24. package/dist/types/src/fields/DynamicField.vue.d.ts +76 -0
  25. package/dist/types/src/fields/Hidden.vue.d.ts +3 -0
  26. package/dist/types/src/fields/Link.vue.d.ts +1365 -0
  27. package/dist/types/src/fields/Number.vue.d.ts +59 -0
  28. package/dist/types/src/fields/RadioGroup.vue.d.ts +55 -0
  29. package/dist/types/src/fields/Select.vue.d.ts +975 -0
  30. package/dist/types/src/fields/Switch.vue.d.ts +59 -0
  31. package/dist/types/src/fields/Text.vue.d.ts +61 -0
  32. package/dist/types/src/fields/Textarea.vue.d.ts +56 -0
  33. package/dist/types/src/fields/Time.vue.d.ts +54 -0
  34. package/dist/types/src/index.d.ts +36 -0
  35. package/dist/types/src/schema.d.ts +495 -0
  36. package/dist/types/src/shims-vue.d.ts +6 -0
  37. package/dist/types/src/utils/config.d.ts +3 -0
  38. package/dist/types/src/utils/fieldProps.d.ts +21 -0
  39. package/dist/types/src/utils/form.d.ts +8 -0
  40. package/dist/types/src/utils/useAddField.d.ts +1 -0
  41. package/dist/types/src/vite-env.d.ts +1 -0
  42. package/package.json +51 -0
  43. package/src/Form.vue +188 -0
  44. package/src/FormDialog.vue +163 -0
  45. package/src/containers/Container.vue +263 -0
  46. package/src/containers/Fieldset.vue +138 -0
  47. package/src/containers/GroupList.vue +152 -0
  48. package/src/containers/GroupListItem.vue +159 -0
  49. package/src/containers/Panel.vue +106 -0
  50. package/src/containers/Row.vue +68 -0
  51. package/src/containers/Step.vue +82 -0
  52. package/src/containers/Table.vue +624 -0
  53. package/src/containers/Tabs.vue +176 -0
  54. package/src/fields/Cascader.vue +147 -0
  55. package/src/fields/Checkbox.vue +67 -0
  56. package/src/fields/CheckboxGroup.vue +44 -0
  57. package/src/fields/ColorPicker.vue +38 -0
  58. package/src/fields/Date.vue +51 -0
  59. package/src/fields/DateTime.vue +59 -0
  60. package/src/fields/Daterange.vue +75 -0
  61. package/src/fields/Display.vue +34 -0
  62. package/src/fields/DynamicField.vue +109 -0
  63. package/src/fields/Hidden.vue +29 -0
  64. package/src/fields/Link.vue +112 -0
  65. package/src/fields/Number.vue +53 -0
  66. package/src/fields/RadioGroup.vue +33 -0
  67. package/src/fields/Select.vue +393 -0
  68. package/src/fields/Switch.vue +65 -0
  69. package/src/fields/Text.vue +134 -0
  70. package/src/fields/Textarea.vue +62 -0
  71. package/src/fields/Time.vue +48 -0
  72. package/src/index.ts +127 -0
  73. package/src/schema.ts +638 -0
  74. package/src/shims-vue.d.ts +6 -0
  75. package/src/theme/date-time.scss +7 -0
  76. package/src/theme/fieldset.scss +24 -0
  77. package/src/theme/form-dialog.scss +13 -0
  78. package/src/theme/form.scss +30 -0
  79. package/src/theme/group-list.scss +23 -0
  80. package/src/theme/index.scss +9 -0
  81. package/src/theme/link.scss +3 -0
  82. package/src/theme/panel.scss +18 -0
  83. package/src/theme/select.scss +3 -0
  84. package/src/theme/table.scss +69 -0
  85. package/src/theme/tabs.scss +25 -0
  86. package/src/utils/config.ts +27 -0
  87. package/src/utils/containerProps.ts +50 -0
  88. package/src/utils/createForm.ts +25 -0
  89. package/src/utils/fieldProps.ts +39 -0
  90. package/src/utils/form.ts +266 -0
  91. package/src/utils/useAddField.ts +40 -0
  92. package/src/vite-env.d.ts +1 -0
  93. package/tsconfig.json +9 -0
  94. package/vite.config.ts +27 -0
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <fieldset
3
+ v-if="name ? model[name] : model"
4
+ class="m-fieldset"
5
+ :style="show ? 'padding: 15px 15px 0 5px;' : 'border: 0'"
6
+ >
7
+ <el-checkbox
8
+ v-if="!show && name"
9
+ v-model="model[name].value"
10
+ :prop="`${prop}${prop ? '.' : ''}${config.name}.value`"
11
+ :true-label="1"
12
+ :false-label="0"
13
+ @change="change"
14
+ ><span v-html="config.legend"></span><span v-if="config.extra" v-html="config.extra" class="m-form-tip"></span
15
+ ></el-checkbox>
16
+ <legend v-else-if="config.checkbox && name">
17
+ <el-checkbox
18
+ v-model="model[name].value"
19
+ :prop="`${prop}${prop ? '.' : ''}${config.name}.value`"
20
+ :true-label="1"
21
+ :false-label="0"
22
+ @change="change"
23
+ ><span v-html="config.legend"></span><span v-if="config.extra" v-html="config.extra" class="m-form-tip"></span
24
+ ></el-checkbox>
25
+ </legend>
26
+ <legend v-else>
27
+ <span v-html="config.legend"></span>
28
+ <span v-if="config.extra" v-html="config.extra" class="m-form-tip"></span>
29
+ </legend>
30
+
31
+ <div v-if="config.schematic && show" style="display: flex">
32
+ <div style="flex: 1">
33
+ <m-form-container
34
+ v-for="(item, index) in config.items"
35
+ :key="key(item, index)"
36
+ :model="name ? model[name] : model"
37
+ :rules="name ? rules[name] : []"
38
+ :config="item"
39
+ :prop="prop"
40
+ :labelWidth="lWidth"
41
+ :size="size"
42
+ @change="change"
43
+ ></m-form-container>
44
+ </div>
45
+
46
+ <img class="m-form-schematic" :src="config.schematic" />
47
+ </div>
48
+
49
+ <template v-else-if="show">
50
+ <m-form-container
51
+ v-for="(item, index) in config.items"
52
+ :key="key(item, index)"
53
+ :model="name ? model[name] : model"
54
+ :rules="name ? rules[name] : []"
55
+ :config="item"
56
+ :prop="prop"
57
+ :labelWidth="lWidth"
58
+ :size="size"
59
+ @change="change"
60
+ ></m-form-container>
61
+ </template>
62
+ </fieldset>
63
+ </template>
64
+
65
+ <script lang="ts">
66
+ import { computed, defineComponent, inject, PropType } from 'vue';
67
+
68
+ import { FieldsetConfig, FormState } from '../schema';
69
+
70
+ export default defineComponent({
71
+ name: 'm-form-fieldset',
72
+
73
+ props: {
74
+ labelWidth: String,
75
+
76
+ model: {
77
+ type: Object,
78
+ default: () => ({}),
79
+ },
80
+
81
+ config: {
82
+ type: Object as PropType<FieldsetConfig>,
83
+ default: () => ({}),
84
+ },
85
+
86
+ rules: {
87
+ type: Object,
88
+ default: () => ({}),
89
+ },
90
+
91
+ prop: {
92
+ type: String,
93
+ default: () => '',
94
+ },
95
+
96
+ size: String,
97
+ },
98
+
99
+ emits: ['change'],
100
+
101
+ setup(props, { emit }) {
102
+ const mForm = inject<FormState | undefined>('mForm');
103
+
104
+ const name = computed(() => props.config.name || '');
105
+
106
+ const show = computed(() => {
107
+ if (props.config.expand && name.value) {
108
+ return props.model[name.value]?.value;
109
+ }
110
+ return true;
111
+ });
112
+
113
+ const lWidth = computed(() => {
114
+ if (props.config.items) {
115
+ return props.config.labelWidth || props.labelWidth;
116
+ }
117
+ return props.config.labelWidth || props.labelWidth || (props.config.text ? null : '0');
118
+ });
119
+
120
+ const change = () => {
121
+ emit('change', props.model);
122
+ };
123
+
124
+ const key = (item: any, index: number) => item[mForm?.keyProp || '__key'] ?? index;
125
+
126
+ return {
127
+ show,
128
+ name,
129
+ mForm,
130
+ lWidth,
131
+ key,
132
+ change,
133
+ };
134
+ },
135
+ });
136
+ </script>
137
+
138
+ <style lang="scss"></style>
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <div class="m-fields-group-list">
3
+ <div v-if="config.extra" v-html="config.extra" style="color: rgba(0, 0, 0, 0.45)"></div>
4
+ <div v-if="!model[name] || !model[name].length" class="el-table__empty-block">
5
+ <span class="el-table__empty-text">暂无数据</span>
6
+ </div>
7
+
8
+ <m-fields-group-list-item
9
+ v-else
10
+ v-for="(item, index) in model[name]"
11
+ :key="index"
12
+ :model="item"
13
+ :config="config"
14
+ :prop="prop"
15
+ :index="index"
16
+ :label-width="labelWidth"
17
+ :size="size"
18
+ :group-model="model[name]"
19
+ @remove-item="removeHandler"
20
+ @swap-item="swapHandler"
21
+ @change="changeHandler"
22
+ ></m-fields-group-list-item>
23
+
24
+ <el-button @click="addHandler" size="small" v-if="addable">添加组</el-button>
25
+
26
+ <el-button icon="el-icon-s-grid" size="small" @click="toggleMode" v-if="config.enableToggleMode"
27
+ >切换为表格</el-button
28
+ >
29
+ </div>
30
+ </template>
31
+
32
+ <script lang="ts">
33
+ import { computed, defineComponent, inject, PropType } from 'vue';
34
+
35
+ import { FormState, GroupListConfig } from '../schema';
36
+ import { initValue } from '../utils/form';
37
+
38
+ import MFieldsGroupListItem from './GroupListItem.vue';
39
+
40
+ export default defineComponent({
41
+ name: 'm-form-group-list',
42
+
43
+ components: { MFieldsGroupListItem },
44
+
45
+ props: {
46
+ labelWidth: String,
47
+
48
+ model: {
49
+ type: Object,
50
+ default: () => ({}),
51
+ },
52
+
53
+ config: {
54
+ type: Object as PropType<GroupListConfig>,
55
+ default: () => ({}),
56
+ },
57
+
58
+ prop: {
59
+ type: String,
60
+ default: '',
61
+ },
62
+
63
+ size: String,
64
+
65
+ name: {
66
+ type: String,
67
+ default: '',
68
+ },
69
+ },
70
+
71
+ emits: ['change'],
72
+
73
+ setup(props, { emit }) {
74
+ const mForm = inject<FormState | undefined>('mForm');
75
+
76
+ const addable = computed(() => {
77
+ if (!props.name) return false;
78
+
79
+ if (typeof props.config.addable === 'function') {
80
+ return props.config.addable(mForm, {
81
+ model: props.model[props.name],
82
+ formValue: mForm?.values,
83
+ });
84
+ }
85
+
86
+ return typeof props.config.addable === 'undefined' ? true : props.config.addable;
87
+ });
88
+
89
+ const changeHandler = () => {
90
+ if (!props.name) return false;
91
+
92
+ emit('change', props.model[props.name]);
93
+ };
94
+
95
+ const addHandler = async () => {
96
+ if (!props.name) return false;
97
+
98
+ let initValues = {};
99
+
100
+ if (typeof props.config.defaultAdd === 'function') {
101
+ initValues = await props.config.defaultAdd(mForm, {
102
+ model: props.model[props.name],
103
+ formValue: mForm?.values,
104
+ });
105
+ } else if (props.config.defaultAdd) {
106
+ initValues = props.config.defaultAdd;
107
+ }
108
+
109
+ const groupValue = await initValue(mForm, {
110
+ config: props.config.items,
111
+ initValues,
112
+ });
113
+
114
+ props.model[props.name].push(groupValue);
115
+ };
116
+
117
+ const removeHandler = (index: number) => {
118
+ if (!props.name) return false;
119
+
120
+ props.model[props.name].splice(index, 1);
121
+ changeHandler();
122
+ };
123
+
124
+ const swapHandler = (idx1: number, idx2: number) => {
125
+ if (!props.name) return false;
126
+
127
+ const [currRow] = props.model[props.name].splice(idx1, 1);
128
+ props.model[props.name].splice(idx2, 0, currRow);
129
+ changeHandler();
130
+ };
131
+
132
+ const toggleMode = () => {
133
+ props.config.type = 'table';
134
+ props.config.groupItems = props.config.items;
135
+ props.config.items = (props.config.tableItems ||
136
+ props.config.items.map((item: any) => ({
137
+ ...item,
138
+ label: item.label || item.text,
139
+ text: null,
140
+ }))) as any;
141
+ };
142
+ return {
143
+ addable,
144
+ toggleMode,
145
+ removeHandler,
146
+ swapHandler,
147
+ changeHandler,
148
+ addHandler,
149
+ };
150
+ },
151
+ });
152
+ </script>
@@ -0,0 +1,159 @@
1
+ <template>
2
+ <div class="m-fields-group-list-item">
3
+ <div>
4
+ <el-icon style="margin-right: 7px" @click="expandHandler"
5
+ ><caret-bottom v-if="expand" /><caret-right v-else
6
+ /></el-icon>
7
+
8
+ <el-button type="text" @click="expandHandler">{{ title }}</el-button>
9
+
10
+ <el-button
11
+ v-show="showDelete(parseInt(String(index)))"
12
+ type="text"
13
+ :icon="Delete"
14
+ style="color: #f56c6c"
15
+ @click="removeHandler"
16
+ ></el-button>
17
+
18
+ <template v-if="movable()">
19
+ <el-button v-show="index !== 0" type="text" size="small" @click="changeOrder(-1)"
20
+ >上移<el-icon><CaretRight /></el-icon
21
+ ></el-button>
22
+ <el-button v-show="index !== length - 1" type="text" size="small" @click="changeOrder(1)"
23
+ >下移<el-icon><CaretBottom /></el-icon
24
+ ></el-button>
25
+ </template>
26
+
27
+ <span v-if="itemExtra" v-html="itemExtra" class="m-form-tip"></span>
28
+ </div>
29
+
30
+ <m-form-container
31
+ v-if="expand"
32
+ :config="rowConfig"
33
+ :model="model"
34
+ :labelWidth="labelWidth"
35
+ :prop="`${prop}${prop ? '.' : ''}${String(index)}`"
36
+ :size="size"
37
+ @change="changeHandler"
38
+ ></m-form-container>
39
+ </div>
40
+ </template>
41
+
42
+ <script lang="ts">
43
+ import { computed, defineComponent, inject, PropType, ref, watchEffect } from 'vue';
44
+ import { CaretBottom, CaretRight, Delete } from '@element-plus/icons';
45
+
46
+ import { FormState, GroupListConfig } from '../schema';
47
+ import { filterFunction } from '../utils/form';
48
+
49
+ export default defineComponent({
50
+ name: 'm-form-group-list-item',
51
+
52
+ components: { CaretRight, CaretBottom },
53
+
54
+ props: {
55
+ labelWidth: String,
56
+
57
+ model: {
58
+ type: Object,
59
+ default: () => ({}),
60
+ },
61
+
62
+ config: {
63
+ type: Object as PropType<GroupListConfig>,
64
+ default: () => ({}),
65
+ },
66
+
67
+ prop: String,
68
+
69
+ size: String,
70
+
71
+ index: {
72
+ type: [Number, String, Symbol],
73
+ default: 0,
74
+ },
75
+
76
+ groupModel: {
77
+ type: Array,
78
+ default: () => [],
79
+ },
80
+ },
81
+
82
+ emits: ['swap-item', 'remove-item', 'change'],
83
+
84
+ setup(props, { emit }) {
85
+ const mForm = inject<FormState | undefined>('mForm');
86
+ const expand = ref(false);
87
+
88
+ watchEffect(() => {
89
+ expand.value = !props.index;
90
+ });
91
+
92
+ const rowConfig = computed(() => ({
93
+ type: 'row',
94
+ span: props.config.span || 24,
95
+ items: props.config.items,
96
+ labelWidth: props.config.labelWidth,
97
+ [mForm?.keyProp || '__key']: `${props.config[mForm?.keyProp || '__key']}${String(props.index)}`,
98
+ }));
99
+
100
+ const title = computed(() => {
101
+ if (props.config.titleKey && props.model[props.config.titleKey]) {
102
+ return props.model[props.config.titleKey];
103
+ }
104
+
105
+ return `组 ${String(props.index)}`;
106
+ });
107
+
108
+ const length = computed(() => props.groupModel?.length || 0);
109
+
110
+ const itemExtra = computed(() => filterFunction(mForm, props.config.itemExtra, props));
111
+
112
+ const removeHandler = () => emit('remove-item', props.index);
113
+
114
+ const changeHandler = () => emit('change');
115
+
116
+ const expandHandler = () => {
117
+ expand.value = !expand.value;
118
+ };
119
+
120
+ // 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
121
+ const showDelete = (index: number) => {
122
+ const deleteFunc = props.config.delete;
123
+ if (deleteFunc && typeof deleteFunc === 'function') {
124
+ return deleteFunc(props.model, index, mForm?.values);
125
+ }
126
+ return true;
127
+ };
128
+
129
+ // 调换顺序
130
+ const changeOrder = (offset = 0) => emit('swap-item', props.index, `${String(props.index)}${offset}`);
131
+
132
+ const movable = () => {
133
+ const { movable } = props.config;
134
+
135
+ // 没有设置时,默认可移动
136
+ if (movable === undefined) return true;
137
+ if (typeof movable === 'function') {
138
+ return movable(mForm, props.index || 0, props.model, props.groupModel);
139
+ }
140
+ return movable;
141
+ };
142
+
143
+ return {
144
+ expand,
145
+ expandHandler,
146
+ title,
147
+ showDelete,
148
+ removeHandler,
149
+ movable,
150
+ changeOrder,
151
+ itemExtra,
152
+ rowConfig,
153
+ changeHandler,
154
+ length,
155
+ Delete,
156
+ };
157
+ },
158
+ });
159
+ </script>
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <el-card
3
+ v-if="items && items.length"
4
+ class="box-card m-form-panel"
5
+ :body-style="{ display: expand ? 'block' : 'none' }"
6
+ >
7
+ <template #header>
8
+ <div class="clearfix">
9
+ <a href="javascript:" style="width: 100%; display: block" @click="expand = !expand">
10
+ <el-icon><caret-bottom v-if="expand" /><caret-right v-else /></el-icon> {{ filter(config.title) }}
11
+ <span v-if="config && config.extra" v-html="config.extra" class="m-form-tip"></span>
12
+ </a>
13
+ </div>
14
+ </template>
15
+
16
+ <div>
17
+ <slot></slot>
18
+
19
+ <div v-if="config.schematic" style="display: flex">
20
+ <div style="flex: 1">
21
+ <m-form-container
22
+ v-for="(item, index) in items"
23
+ :key="item[mForm?.keyProp || '__key'] ?? index"
24
+ :config="item"
25
+ :model="name ? model[name] : model"
26
+ :prop="prop"
27
+ :size="size"
28
+ :label-width="config.labelWidth || labelWidth"
29
+ @change="changeHandler"
30
+ ></m-form-container>
31
+ </div>
32
+
33
+ <img class="m-form-schematic" :src="config.schematic" />
34
+ </div>
35
+
36
+ <template v-else>
37
+ <m-form-container
38
+ v-for="(item, index) in items"
39
+ :key="item[mForm?.keyProp || '__key'] ?? index"
40
+ :config="item"
41
+ :model="name ? model[name] : model"
42
+ :prop="prop"
43
+ :size="size"
44
+ :label-width="config.labelWidth || labelWidth"
45
+ @change="changeHandler"
46
+ ></m-form-container>
47
+ </template>
48
+ </div>
49
+ </el-card>
50
+ </template>
51
+
52
+ <script lang="ts">
53
+ import { computed, defineComponent, inject, PropType, ref } from 'vue';
54
+ import { CaretBottom, CaretRight } from '@element-plus/icons';
55
+
56
+ import { FormState, PanelConfig } from '../schema';
57
+ import { filterFunction } from '../utils/form';
58
+
59
+ export default defineComponent({
60
+ name: 'm-form-panel',
61
+
62
+ components: { CaretBottom, CaretRight },
63
+
64
+ props: {
65
+ labelWidth: String,
66
+
67
+ model: {
68
+ type: Object,
69
+ default: () => ({}),
70
+ },
71
+
72
+ config: {
73
+ type: Object as PropType<PanelConfig>,
74
+ default: () => ({}),
75
+ },
76
+
77
+ prop: String,
78
+
79
+ size: String,
80
+
81
+ name: String,
82
+ },
83
+
84
+ emits: ['change'],
85
+
86
+ setup(props, { emit }) {
87
+ const mForm = inject<FormState | undefined>('mForm');
88
+
89
+ const expand = ref(props.config.expand !== false);
90
+
91
+ const items = computed(() => props.config.items);
92
+
93
+ const filter = (config: any) => filterFunction(mForm, config, props);
94
+
95
+ const changeHandler = () => emit('change', props.model);
96
+
97
+ return {
98
+ mForm,
99
+ expand,
100
+ items,
101
+ filter,
102
+ changeHandler,
103
+ };
104
+ },
105
+ });
106
+ </script>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <el-row :gutter="10">
3
+ <el-col
4
+ v-for="(col, index) in config.items"
5
+ :style="!display(col) || col.type === 'hidden' ? 'display: none' : ''"
6
+ :key="col[mForm?.keyProp || '__key'] ?? index"
7
+ :span="col.span || config.span || 24 / config.items.length"
8
+ >
9
+ <m-form-container
10
+ :model="name ? model[name] : model"
11
+ :config="col"
12
+ :prop="prop"
13
+ :label-width="config.labelWidth || labelWidth"
14
+ :expand-more="expandMore"
15
+ :size="size"
16
+ @change="changeHandler"
17
+ ></m-form-container>
18
+ </el-col>
19
+ </el-row>
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ import { defineComponent, inject, PropType } from 'vue';
24
+
25
+ import { FormState, RowConfig } from '../schema';
26
+ import { display as displayFunction } from '../utils/form';
27
+
28
+ export default defineComponent({
29
+ name: 'm-form-row',
30
+
31
+ props: {
32
+ labelWidth: String,
33
+ expandMore: Boolean,
34
+
35
+ model: {
36
+ type: Object,
37
+ default: () => ({}),
38
+ },
39
+
40
+ config: {
41
+ type: Object as PropType<RowConfig>,
42
+ default: () => ({}),
43
+ },
44
+
45
+ prop: String,
46
+
47
+ name: String,
48
+
49
+ size: String,
50
+ },
51
+
52
+ emits: ['change'],
53
+
54
+ setup(props, { emit }) {
55
+ const mForm = inject<FormState | undefined>('mForm');
56
+
57
+ const changeHandler = () => emit('change', props.name ? props.model[props.name] : props.model);
58
+
59
+ return {
60
+ mForm,
61
+ display(config: any) {
62
+ return displayFunction(mForm, config.display, props);
63
+ },
64
+ changeHandler,
65
+ };
66
+ },
67
+ });
68
+ </script>
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <div>
3
+ <el-steps :active="active" align-center :space="config.space">
4
+ <el-step
5
+ v-for="(item, index) in config.items"
6
+ :key="item.__key"
7
+ :title="item.title"
8
+ :active="active"
9
+ @click="stepClick(index)"
10
+ ></el-step>
11
+ </el-steps>
12
+
13
+ <template v-for="(step, index) in config.items">
14
+ <template v-for="item in step.items">
15
+ <m-form-container
16
+ v-if="item"
17
+ v-show="active - 1 === index"
18
+ :key="item[mForm?.keyProp || '__key']"
19
+ :config="item"
20
+ :model="step.name ? model[step.name] : model"
21
+ :prop="step.name"
22
+ :size="size"
23
+ :label-width="config.labelWidth || labelWidth"
24
+ @change="changeHandler"
25
+ ></m-form-container>
26
+ </template>
27
+ </template>
28
+ </div>
29
+ </template>
30
+
31
+ <script lang="ts">
32
+ import { defineComponent, inject, PropType, ref, watchEffect } from 'vue';
33
+
34
+ import { FormState, StepConfig } from '../schema';
35
+
36
+ export default defineComponent({
37
+ name: 'm-form-step',
38
+
39
+ props: {
40
+ model: {
41
+ type: Object,
42
+ default: () => ({}),
43
+ },
44
+
45
+ config: {
46
+ type: Object as PropType<StepConfig>,
47
+ default: () => ({}),
48
+ },
49
+
50
+ stepActive: {
51
+ type: Number,
52
+ default: () => 1,
53
+ },
54
+
55
+ size: String,
56
+
57
+ labelWidth: String,
58
+ },
59
+
60
+ emits: ['change'],
61
+
62
+ setup(props, { emit }) {
63
+ const mForm = inject<FormState | undefined>('mForm');
64
+ const active = ref(1);
65
+
66
+ watchEffect(() => {
67
+ active.value = props.stepActive;
68
+ });
69
+
70
+ const stepClick = (index: number) => {
71
+ active.value = index + 1;
72
+ mForm?.$emit('update:stepActive', active.value);
73
+ };
74
+
75
+ const changeHandler = () => {
76
+ emit('change', props.model);
77
+ };
78
+
79
+ return { mForm, active, stepClick, changeHandler };
80
+ },
81
+ });
82
+ </script>