@ebiz/designer-components 0.0.25 → 0.0.27
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.
- package/dist/designer-components.css +1 -1
- package/dist/index.mjs +41661 -37304
- package/package.json +1 -1
- package/src/apiService/simpleDataService.js +1 -1
- package/src/components/Button.vue +1 -1
- package/src/components/EbizSForm.vue +398 -0
- package/src/components/EbizSFormItem.vue +587 -0
- package/src/components/EbizTdesignButtonDialog.vue +360 -0
- package/src/index.js +9 -1
- package/src/router/index.js +12 -0
- package/src/views/EbizSFormDemo.vue +327 -0
- package/src/views/EbizTdesignButtonDialogExample.vue +438 -0
- package/src/views/Home.vue +3 -1
package/package.json
CHANGED
@@ -0,0 +1,398 @@
|
|
1
|
+
<template>
|
2
|
+
<t-form
|
3
|
+
ref="formRef"
|
4
|
+
:class="['ebiz-s-form', className]"
|
5
|
+
:colon="colon"
|
6
|
+
:data="data"
|
7
|
+
:disabled="disabled"
|
8
|
+
:label-align="labelAlign"
|
9
|
+
:label-width="labelWidth"
|
10
|
+
:layout="layout"
|
11
|
+
:reset-type="resetType"
|
12
|
+
:reset-on-semi-controlled="resetOnSemiControlled"
|
13
|
+
:rules="rules"
|
14
|
+
:scroll-to-first-error="scrollToFirstError"
|
15
|
+
:show-error-message="showErrorMessage"
|
16
|
+
:status-icon="statusIcon"
|
17
|
+
:style="customStyle"
|
18
|
+
@reset="handleReset"
|
19
|
+
@submit="handleSubmit"
|
20
|
+
@validate="handleValidate"
|
21
|
+
>
|
22
|
+
<slot></slot>
|
23
|
+
<template v-if="$slots.footer" #footer>
|
24
|
+
<slot name="footer"></slot>
|
25
|
+
</template>
|
26
|
+
<div class="form-buttons" v-if="showButtons">
|
27
|
+
<t-space>
|
28
|
+
<t-button v-if="showCancelButton" :theme="cancelButtonTheme" @click="handleCancel">{{ cancelButtonText }}</t-button>
|
29
|
+
<t-button v-if="showSubmitButton" theme="primary" :loading="loading" @click="handleFormSubmit">{{ submitButtonText }}</t-button>
|
30
|
+
</t-space>
|
31
|
+
</div>
|
32
|
+
</t-form>
|
33
|
+
</template>
|
34
|
+
|
35
|
+
<script>
|
36
|
+
/**
|
37
|
+
* @displayName PC端表单
|
38
|
+
* @description PC端表单组件,基于TDesign Form封装,支持表单验证、API提交等功能
|
39
|
+
* @category 表单组件
|
40
|
+
* @name EbizSForm
|
41
|
+
*/
|
42
|
+
export default {
|
43
|
+
name: "EbizSForm"
|
44
|
+
}
|
45
|
+
</script>
|
46
|
+
|
47
|
+
<script setup>
|
48
|
+
import { defineProps, defineEmits, ref, reactive, computed } from 'vue';
|
49
|
+
import { Form as TForm, Button as TButton, Space as TSpace, MessagePlugin } from 'tdesign-vue-next';
|
50
|
+
import dataService from "../apiService/simpleDataService";
|
51
|
+
|
52
|
+
const props = defineProps({
|
53
|
+
/**
|
54
|
+
* 表单数据对象
|
55
|
+
*/
|
56
|
+
data: {
|
57
|
+
type: Object,
|
58
|
+
default: () => ({})
|
59
|
+
},
|
60
|
+
/**
|
61
|
+
* 表单域标签的位置
|
62
|
+
* @options left|right|top
|
63
|
+
*/
|
64
|
+
labelAlign: {
|
65
|
+
type: String,
|
66
|
+
default: 'right',
|
67
|
+
validator: (val) => ['left', 'right', 'top'].includes(val)
|
68
|
+
},
|
69
|
+
/**
|
70
|
+
* 表单布局
|
71
|
+
* @options vertical|inline
|
72
|
+
*/
|
73
|
+
layout: {
|
74
|
+
type: String,
|
75
|
+
default: 'vertical',
|
76
|
+
validator: (val) => ['vertical', 'inline'].includes(val)
|
77
|
+
},
|
78
|
+
/**
|
79
|
+
* 是否显示必填标记
|
80
|
+
*/
|
81
|
+
colon: {
|
82
|
+
type: Boolean,
|
83
|
+
default: false
|
84
|
+
},
|
85
|
+
/**
|
86
|
+
* 是否禁用整个表单
|
87
|
+
*/
|
88
|
+
disabled: {
|
89
|
+
type: Boolean,
|
90
|
+
default: false
|
91
|
+
},
|
92
|
+
/**
|
93
|
+
* 表单域标签的宽度
|
94
|
+
*/
|
95
|
+
labelWidth: {
|
96
|
+
type: [String, Number],
|
97
|
+
default: '100px'
|
98
|
+
},
|
99
|
+
/**
|
100
|
+
* 表单校验规则
|
101
|
+
*/
|
102
|
+
rules: {
|
103
|
+
type: Object,
|
104
|
+
default: () => ({})
|
105
|
+
},
|
106
|
+
/**
|
107
|
+
* 是否显示校验错误信息
|
108
|
+
*/
|
109
|
+
showErrorMessage: {
|
110
|
+
type: Boolean,
|
111
|
+
default: true
|
112
|
+
},
|
113
|
+
/**
|
114
|
+
* 是否显示校验图标
|
115
|
+
*/
|
116
|
+
statusIcon: {
|
117
|
+
type: Boolean,
|
118
|
+
default: false
|
119
|
+
},
|
120
|
+
/**
|
121
|
+
* 表单重置时的方式
|
122
|
+
* @options empty|initial
|
123
|
+
*/
|
124
|
+
resetType: {
|
125
|
+
type: String,
|
126
|
+
default: 'empty',
|
127
|
+
validator: (val) => ['empty', 'initial'].includes(val)
|
128
|
+
},
|
129
|
+
/**
|
130
|
+
* 重置时是否清空所有非受控字段
|
131
|
+
*/
|
132
|
+
resetOnSemiControlled: {
|
133
|
+
type: Boolean,
|
134
|
+
default: false
|
135
|
+
},
|
136
|
+
/**
|
137
|
+
* 表单校验不通过时,是否自动定位到第一个错误字段
|
138
|
+
*/
|
139
|
+
scrollToFirstError: {
|
140
|
+
type: Boolean,
|
141
|
+
default: true
|
142
|
+
},
|
143
|
+
/**
|
144
|
+
* 自定义样式
|
145
|
+
*/
|
146
|
+
customStyle: {
|
147
|
+
type: [String, Object],
|
148
|
+
default: ''
|
149
|
+
},
|
150
|
+
/**
|
151
|
+
* 自定义类名
|
152
|
+
*/
|
153
|
+
className: {
|
154
|
+
type: String,
|
155
|
+
default: ''
|
156
|
+
},
|
157
|
+
/**
|
158
|
+
* 是否显示表单按钮(提交和取消)
|
159
|
+
*/
|
160
|
+
showButtons: {
|
161
|
+
type: Boolean,
|
162
|
+
default: true
|
163
|
+
},
|
164
|
+
/**
|
165
|
+
* 是否显示提交按钮
|
166
|
+
*/
|
167
|
+
showSubmitButton: {
|
168
|
+
type: Boolean,
|
169
|
+
default: true
|
170
|
+
},
|
171
|
+
/**
|
172
|
+
* 提交按钮文字
|
173
|
+
*/
|
174
|
+
submitButtonText: {
|
175
|
+
type: String,
|
176
|
+
default: '提交'
|
177
|
+
},
|
178
|
+
/**
|
179
|
+
* 是否显示取消按钮
|
180
|
+
*/
|
181
|
+
showCancelButton: {
|
182
|
+
type: Boolean,
|
183
|
+
default: true
|
184
|
+
},
|
185
|
+
/**
|
186
|
+
* 取消按钮文字
|
187
|
+
*/
|
188
|
+
cancelButtonText: {
|
189
|
+
type: String,
|
190
|
+
default: '取消'
|
191
|
+
},
|
192
|
+
/**
|
193
|
+
* 取消按钮主题
|
194
|
+
*/
|
195
|
+
cancelButtonTheme: {
|
196
|
+
type: String,
|
197
|
+
default: 'default'
|
198
|
+
},
|
199
|
+
/**
|
200
|
+
* API配置,用于表单提交
|
201
|
+
*/
|
202
|
+
apiConfig: {
|
203
|
+
type: Object,
|
204
|
+
default: () => null
|
205
|
+
},
|
206
|
+
/**
|
207
|
+
* 是否在提交成功后重置表单
|
208
|
+
*/
|
209
|
+
resetOnSuccess: {
|
210
|
+
type: Boolean,
|
211
|
+
default: false
|
212
|
+
},
|
213
|
+
/**
|
214
|
+
* 提交成功后的消息提示
|
215
|
+
*/
|
216
|
+
successMessage: {
|
217
|
+
type: String,
|
218
|
+
default: '提交成功'
|
219
|
+
},
|
220
|
+
/**
|
221
|
+
* 提交失败后的消息提示
|
222
|
+
*/
|
223
|
+
errorMessage: {
|
224
|
+
type: String,
|
225
|
+
default: '提交失败'
|
226
|
+
},
|
227
|
+
/**
|
228
|
+
* 是否显示提交结果消息
|
229
|
+
*/
|
230
|
+
showResultMessage: {
|
231
|
+
type: Boolean,
|
232
|
+
default: true
|
233
|
+
}
|
234
|
+
});
|
235
|
+
|
236
|
+
const emit = defineEmits([
|
237
|
+
'reset',
|
238
|
+
'submit',
|
239
|
+
'validate',
|
240
|
+
'success',
|
241
|
+
'error',
|
242
|
+
'cancel'
|
243
|
+
]);
|
244
|
+
|
245
|
+
const formRef = ref(null);
|
246
|
+
const loading = ref(false);
|
247
|
+
|
248
|
+
/**
|
249
|
+
* 提交表单
|
250
|
+
*/
|
251
|
+
const handleFormSubmit = async () => {
|
252
|
+
if (!formRef.value) return;
|
253
|
+
|
254
|
+
const validateResult = await formRef.value.validate();
|
255
|
+
if (validateResult !== true) {
|
256
|
+
return;
|
257
|
+
}
|
258
|
+
|
259
|
+
emit('submit', props.data);
|
260
|
+
|
261
|
+
if (props.apiConfig) {
|
262
|
+
await submitFormData();
|
263
|
+
}
|
264
|
+
};
|
265
|
+
|
266
|
+
/**
|
267
|
+
* 调用API提交表单数据
|
268
|
+
*/
|
269
|
+
const submitFormData = async () => {
|
270
|
+
try {
|
271
|
+
loading.value = true;
|
272
|
+
|
273
|
+
const { url, method, headers, params } = props.apiConfig;
|
274
|
+
const response = await dataService.request({
|
275
|
+
url,
|
276
|
+
method: method || 'post',
|
277
|
+
data: props.data,
|
278
|
+
params,
|
279
|
+
headers
|
280
|
+
});
|
281
|
+
|
282
|
+
if (props.showResultMessage) {
|
283
|
+
MessagePlugin.success(props.successMessage);
|
284
|
+
}
|
285
|
+
|
286
|
+
emit('success', response);
|
287
|
+
|
288
|
+
if (props.resetOnSuccess && formRef.value) {
|
289
|
+
formRef.value.reset();
|
290
|
+
}
|
291
|
+
|
292
|
+
return response;
|
293
|
+
} catch (error) {
|
294
|
+
if (props.showResultMessage) {
|
295
|
+
MessagePlugin.error(props.errorMessage || error.message || '提交失败');
|
296
|
+
}
|
297
|
+
|
298
|
+
emit('error', error);
|
299
|
+
return null;
|
300
|
+
} finally {
|
301
|
+
loading.value = false;
|
302
|
+
}
|
303
|
+
};
|
304
|
+
|
305
|
+
/**
|
306
|
+
* 表单重置
|
307
|
+
* @param {Object} context 表单上下文
|
308
|
+
*/
|
309
|
+
const handleReset = (context) => {
|
310
|
+
emit('reset', context);
|
311
|
+
};
|
312
|
+
|
313
|
+
/**
|
314
|
+
* 表单验证
|
315
|
+
* @param {Object} result 表单验证结果
|
316
|
+
*/
|
317
|
+
const handleValidate = (result) => {
|
318
|
+
emit('validate', result);
|
319
|
+
};
|
320
|
+
|
321
|
+
/**
|
322
|
+
* 取消按钮点击事件
|
323
|
+
*/
|
324
|
+
const handleCancel = () => {
|
325
|
+
emit('cancel');
|
326
|
+
};
|
327
|
+
|
328
|
+
/**
|
329
|
+
* 表单提交事件,由内置的HTML表单submit事件触发
|
330
|
+
*/
|
331
|
+
const handleSubmit = (context) => {
|
332
|
+
// 这里只做转发,实际提交逻辑在handleFormSubmit中
|
333
|
+
emit('submit', context);
|
334
|
+
};
|
335
|
+
|
336
|
+
// 暴露方法给父组件
|
337
|
+
defineExpose({
|
338
|
+
/**
|
339
|
+
* 提交表单方法
|
340
|
+
*/
|
341
|
+
submit: handleFormSubmit,
|
342
|
+
/**
|
343
|
+
* 重置表单方法
|
344
|
+
*/
|
345
|
+
reset: () => {
|
346
|
+
if (formRef.value) {
|
347
|
+
formRef.value.reset();
|
348
|
+
}
|
349
|
+
},
|
350
|
+
/**
|
351
|
+
* 校验表单方法
|
352
|
+
* @returns {Promise} 校验结果Promise
|
353
|
+
*/
|
354
|
+
validate: async () => {
|
355
|
+
if (formRef.value) {
|
356
|
+
return await formRef.value.validate();
|
357
|
+
}
|
358
|
+
return false;
|
359
|
+
},
|
360
|
+
/**
|
361
|
+
* 校验特定字段
|
362
|
+
* @param {Array|String} fields 字段名称或字段名称数组
|
363
|
+
* @returns {Promise} 校验结果Promise
|
364
|
+
*/
|
365
|
+
validateFields: async (fields) => {
|
366
|
+
if (formRef.value) {
|
367
|
+
return await formRef.value.validateFields(fields);
|
368
|
+
}
|
369
|
+
return false;
|
370
|
+
},
|
371
|
+
/**
|
372
|
+
* 清除校验结果
|
373
|
+
* @param {Array|String} fields 字段名称或字段名称数组,不传则清除所有
|
374
|
+
*/
|
375
|
+
clearValidate: (fields) => {
|
376
|
+
if (formRef.value) {
|
377
|
+
formRef.value.clearValidate(fields);
|
378
|
+
}
|
379
|
+
},
|
380
|
+
/**
|
381
|
+
* 获取表单DOM元素
|
382
|
+
*/
|
383
|
+
getFormElement: () => formRef.value
|
384
|
+
});
|
385
|
+
</script>
|
386
|
+
|
387
|
+
<style scoped>
|
388
|
+
.ebiz-s-form {
|
389
|
+
width: 100%;
|
390
|
+
}
|
391
|
+
|
392
|
+
.form-buttons {
|
393
|
+
margin-top: 24px;
|
394
|
+
padding: 8px 0;
|
395
|
+
display: flex;
|
396
|
+
justify-content: center;
|
397
|
+
}
|
398
|
+
</style>
|