@leiyin/v-form-renderer 0.1.3-alpha.3 → 0.1.3-alpha.4

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/index.cjs.js CHANGED
@@ -3,18 +3,787 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var vue = require('vue');
6
+ var lodashEs = require('lodash-es');
6
7
 
7
- const _hoisted_1 = { class: "red-text" };
8
+ const vFormProps = {
9
+ content: {
10
+ type: Array,
11
+ required: true,
12
+ default: () => []
13
+ },
14
+ /** 统一label宽度 */
15
+ labelWidth: {
16
+ type: String,
17
+ default: '98px'
18
+ },
19
+ disabled: {
20
+ type: Boolean,
21
+ default: false
22
+ },
23
+ inline: {
24
+ type: Boolean,
25
+ default: true
26
+ },
27
+ readonly: {
28
+ type: Boolean,
29
+ default: false
30
+ }
31
+ };
8
32
 
9
- function render(_ctx, _cache) {
10
- return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, "222"))
33
+ const renderFormItemProps = {
34
+ data: {
35
+ type: Object,
36
+ default: () => { }
37
+ },
38
+ value: {
39
+ type: Object,
40
+ default: () => { }
41
+ },
42
+ disabled: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+ readonly: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ id: {
51
+ type: String,
52
+ default: ''
53
+ }
54
+ };
55
+
56
+ var RenderComponent = vue.defineComponent({
57
+ name: 'RenderComponent',
58
+ setup(_, context) {
59
+ if (!context.attrs.componentType) {
60
+ return () => null;
61
+ }
62
+ const plusComponent = vue.resolveComponent(`el-${context.attrs.componentType}`);
63
+ const buildSlots = () => {
64
+ const result = {};
65
+ // cascader 极联不使用默认插槽
66
+ if (context.attrs.componentType === 'cascader') {
67
+ return {};
68
+ }
69
+ // 如果用户定义了插槽对象,例如 { suffix: '元', default: '内容' }
70
+ if (context.attrs.slots && typeof context.attrs.slots === 'object') {
71
+ Object.entries(context.attrs.slots).forEach(([key, value]) => {
72
+ result[key] = () => (typeof value === 'function' ? value() : value);
73
+ });
74
+ }
75
+ else {
76
+ return context.slots;
77
+ }
78
+ return result;
79
+ };
80
+ return () => vue.h(plusComponent, context.attrs, buildSlots());
81
+ }
82
+ });
83
+
84
+ function noop() { }
85
+ function collect(content, key) {
86
+ return lodashEs.fromPairs(content
87
+ .map((item) => ({
88
+ id: item.id,
89
+ type: item.type,
90
+ value: item.type === 'group' && item.items ? collect(item.items, key) : item[key]
91
+ }))
92
+ .filter(({ type, value }) => value !== undefined || (type === 'group' && Object.keys(value).length))
93
+ .map(({ id, value }) => [id, value]));
94
+ }
95
+ /**
96
+ * 根据 content 中的 outputFormat 来处理 value;
97
+ * 如果 outputFormat 处理后的值是对象类型,会覆盖(Object.assign)到 value 上
98
+ */
99
+ function transformOutputValue(value, content) {
100
+ const newVal = {};
101
+ Object.keys(value).forEach((id) => {
102
+ const item = content.find((item) => item.id === id);
103
+ if (!item) {
104
+ return;
105
+ }
106
+ if (item.type !== 'group') {
107
+ if (item.outputFormat) {
108
+ const v = item.outputFormat(value[id], value);
109
+ if (lodashEs.isPlainObject(v)) {
110
+ Object.assign(newVal, v);
111
+ }
112
+ else {
113
+ newVal[id] = v;
114
+ }
115
+ }
116
+ else {
117
+ newVal[id] = value[id];
118
+ }
119
+ }
120
+ else {
121
+ newVal[id] = transformOutputValue(value[id], item.items || []);
122
+ }
123
+ });
124
+ return newVal;
125
+ }
126
+ /**
127
+ * 根据 content 中的 inputFormat 来处理 value
128
+ * inputFormat 接受的是当前层级的 value
129
+ * 复杂点在于,不管传入的 value 是否包含某表单项的 key,所有使用了 inputFormat 的项都有可能在这次 update 中被更新
130
+ */
131
+ function transformInputValue(value, content) {
132
+ const newVal = {};
133
+ content.forEach((item) => {
134
+ const { id } = item;
135
+ if (item.inputFormat) {
136
+ const v = item.inputFormat(value);
137
+ if (v !== undefined) {
138
+ newVal[id] = v;
139
+ }
140
+ }
141
+ else if (id in value) {
142
+ if (item.type !== 'group') {
143
+ newVal[id] = value[id];
144
+ }
145
+ else {
146
+ newVal[id] = transformInputValue(value[id], item.items || []);
147
+ }
148
+ }
149
+ });
150
+ return newVal;
151
+ }
152
+ /**
153
+ * 递归合并 oldV & newV,策略如下:
154
+ * 1. 过滤掉 newV 中不存在于 content 中的项
155
+ * 2. 如果该项的 type 不是 GROUP,直接覆盖合并到 oldV
156
+ * 3. 如果是,则递归执行步骤 1 到 3
157
+ */
158
+ function mergeValue(oldV, newV, content) {
159
+ Object.keys(newV).forEach((k) => {
160
+ const item = content.find((item) => item.id === k);
161
+ if (!item) {
162
+ return;
163
+ }
164
+ if (item.type !== 'group') {
165
+ oldV[k] = newV[k];
166
+ }
167
+ else {
168
+ mergeValue(oldV[k], newV[k], item.items || []);
169
+ }
170
+ });
171
+ }
172
+ /**
173
+ * 格式化树状结构数据
174
+ *
175
+ * @param {Array} orignData 数据
176
+ * @param {Object} params 配置项
177
+ * @param {String} params.label 按orignData,label取值设置label
178
+ * @param {String} params.value 按orignData,value取值设置value
179
+ * @param {String} params.children 按orignData,children取值设置children
180
+ * @returns {Array}
181
+ */
182
+ function transformTreeValue(orignData, params = {
183
+ label: 'label',
184
+ value: 'value',
185
+ children: 'children'
186
+ }) {
187
+ const { label, value, children } = params;
188
+ orignData.forEach((item) => {
189
+ let displayLabel;
190
+ let displayValue;
191
+ if (typeof label === 'function') {
192
+ displayLabel = label(item);
193
+ }
194
+ else {
195
+ displayLabel = item[label];
196
+ }
197
+ if (typeof value === 'function') {
198
+ displayValue = value(item);
199
+ }
200
+ else {
201
+ displayValue = item[value];
202
+ }
203
+ item.label = displayLabel;
204
+ item.value = displayValue;
205
+ const childrenData = transformTreeValue(item[children], params);
206
+ if (childrenData && childrenData.length) {
207
+ item.children = childrenData;
208
+ }
209
+ });
210
+ return orignData;
211
+ }
212
+
213
+ const useFormState = ({ props }) => {
214
+ const formPropsRef = vue.ref(lodashEs.cloneDeep(props));
215
+ /** 表单项数据 */
216
+ const formModel = vue.reactive({});
217
+ /** 表单默认数据 */
218
+ const defaultFormValues = vue.reactive({});
219
+ /** 表单options集合对象 */
220
+ const options = vue.ref({});
221
+ /** 表单实例 */
222
+ const elFormRef = vue.ref();
223
+ // 收集options
224
+ vue.watch(() => props.content, (val) => {
225
+ if (val) {
226
+ options.value = { ...options.value, ...collect(val, 'options') };
227
+ }
228
+ }, {
229
+ immediate: true,
230
+ deep: true
231
+ });
232
+ return {
233
+ elFormRef,
234
+ formModel,
235
+ defaultFormValues,
236
+ options,
237
+ formPropsRef,
238
+ contentRef: vue.computed(() => vue.unref(formPropsRef).content || [])
239
+ };
240
+ };
241
+
242
+ const useFormMethods = (formMethodsContext) => {
243
+ const { formModel, defaultFormValues, contentRef } = formMethodsContext;
244
+ /**
245
+ * 更新表单数据
246
+ * @param {String} options.id 表单ID
247
+ * @param {All} options.val 表单数据
248
+ */
249
+ const updateFormValue = ({ id, val }) => {
250
+ formModel[id] = val;
251
+ };
252
+ /**
253
+ * 初始化数据
254
+ * 没使用 v-model 时才从 default 采集数据
255
+ * default值没法考虑 inputFormat
256
+ */
257
+ const initFormValues = () => {
258
+ if (!contentRef.value.length) {
259
+ return;
260
+ }
261
+ const newValue = collect(contentRef.value, 'default');
262
+ if (!lodashEs.isEqual(formModel, newValue)) {
263
+ Object.entries(newValue).forEach(([key, value]) => {
264
+ formModel[key] = value;
265
+ defaultFormValues[key] = lodashEs.cloneDeep(value);
266
+ });
267
+ }
268
+ };
269
+ return {
270
+ updateFormValue,
271
+ initFormValues
272
+ };
273
+ };
274
+
275
+ const useFormEvents = (useFormEventsContext) => {
276
+ const { formModel, defaultFormValues, elFormRef, contentRef, options } = useFormEventsContext;
277
+ /**
278
+ * 返回表单结果
279
+ * @return {object}
280
+ */
281
+ function getFormValue() {
282
+ return transformOutputValue(formModel, contentRef.value);
283
+ }
284
+ /**
285
+ * 对整个表单的内容进行验证。 返回 Promise。
286
+ * @return {Promise}
287
+ */
288
+ async function validate() {
289
+ var _a;
290
+ return await ((_a = elFormRef.value) === null || _a === void 0 ? void 0 : _a.validate());
291
+ }
292
+ /**
293
+ * 之所以不用 el-form 的 resetFields 机制,有以下原因:
294
+ * - el-form 的 resetFields 无视 el-form-renderer 的自定义组件
295
+ * - el-form 的 resetFields 不会触发 input & change 事件,无法监听
296
+ * 0. 建议先在监听器 watch.value 里 console.log(v.name, oldV.name)
297
+ * 1. 打开 basic 示例
298
+ * 2. 在 label 为 name 的输入框里输入 1,此时 log:'1' ''
299
+ * 3. 点击 reset 按钮,此时 log 两条数据: '1' '1', '' ''
300
+ * 4. 因为 _isequal(v, oldV),所以没有触发 v-model 更新
301
+ */
302
+ async function resetFields() {
303
+ var _a;
304
+ Object.keys(formModel).forEach((key) => {
305
+ formModel[key] = lodashEs.cloneDeep(defaultFormValues[key]);
306
+ });
307
+ await vue.nextTick();
308
+ (_a = elFormRef.value) === null || _a === void 0 ? void 0 : _a.clearValidate();
309
+ }
310
+ /**
311
+ * 更新表单值
312
+ */
313
+ function updateForm(newValue) {
314
+ newValue = transformInputValue(newValue, contentRef.value);
315
+ const cloneFormModel = lodashEs.cloneDeep(formModel);
316
+ mergeValue(cloneFormModel, newValue, contentRef.value);
317
+ Object.keys(cloneFormModel).forEach((key) => {
318
+ formModel[key] = cloneFormModel[key];
319
+ });
320
+ }
321
+ /**
322
+ * 更新 options值
323
+ * @param {string} id
324
+ * @param {array} data
325
+ * @public
326
+ */
327
+ function setOptions(id, data) {
328
+ options.value[id] = data;
329
+ }
330
+ return {
331
+ getFormValue,
332
+ validate,
333
+ resetFields,
334
+ updateForm,
335
+ setOptions
336
+ };
337
+ };
338
+
339
+ const key = Symbol('v-form-renderer');
340
+ function createFormContext(instance) {
341
+ vue.provide(key, instance);
342
+ }
343
+ function useFormContext(formProps = {}) {
344
+ return vue.inject(key, formProps);
11
345
  }
12
346
 
13
- const script = {};
347
+ var script$2 = /*@__PURE__*/ vue.defineComponent({
348
+ __name: 'RenderFormItem',
349
+ props: /*@__PURE__*/ vue.mergeModels(renderFormItemProps, {
350
+ "itemValue": { type: null },
351
+ "itemValueModifiers": {},
352
+ }),
353
+ emits: /*@__PURE__*/ vue.mergeModels(['updateValue'], ["update:itemValue"]),
354
+ setup(__props, { emit: __emit }) {
355
+ const props = __props;
356
+ const itemValue = vue.useModel(__props, 'itemValue');
357
+ const emit = __emit;
358
+ const formContext = useFormContext();
359
+ const { data, value } = props;
360
+ const { hidden = () => false, disabled = () => false } = data;
361
+ const propsInner = vue.ref({});
362
+ // label标签是否为str
363
+ const _isLabelTypeStr = vue.computed(() => typeof data.label === 'string');
364
+ // 是否显示
365
+ const _show = vue.computed(() => !hidden(value, data));
366
+ // 是否禁用
367
+ const disabledStatus = vue.computed(() => disabled(value, data));
368
+ // 组件内options
369
+ const _options = vue.computed(() => {
370
+ // type类型为group时,需遍历索引获取到options数据
371
+ const keys = props.id.split('.');
372
+ let optionData = lodashEs.cloneDeep(formContext.options.value);
373
+ for (const k in keys) {
374
+ optionData = optionData[keys[k]];
375
+ if (!optionData) {
376
+ break;
377
+ }
378
+ }
379
+ return optionData || [];
380
+ });
381
+ // 只读
382
+ const readonly = vue.computed(() => props.readonly);
383
+ // 是否显示只读内容
384
+ const hasReadonlyContent = vue.computed(() => ['input', 'select'].includes(data.type || ''));
385
+ // 规则是否有失去焦点的触发
386
+ const isBlurTrigger = vue.computed(() => {
387
+ if (!data.rules) {
388
+ return false;
389
+ }
390
+ return data.rules.some((rule) => {
391
+ return rule.required && rule.trigger === 'blur';
392
+ });
393
+ });
394
+ // 组件属性
395
+ const componentProps = vue.computed(() => {
396
+ var _a;
397
+ return ({
398
+ options: _options.value || [], // 兼容cascader
399
+ formData: value, // 保存表单对象值
400
+ componentType: (_a = data.type) !== null && _a !== void 0 ? _a : '',
401
+ ...data.el,
402
+ ...propsInner.value
403
+ });
404
+ });
405
+ // 多选时,只读回显值
406
+ const multipleValue = vue.computed(() => {
407
+ const itemVals = vue.unref(itemValue);
408
+ const multipleSelectValue = lodashEs.get(data, 'el.multiple') && Array.isArray(itemVals) ? itemVals : [itemVals];
409
+ const multipleSelect = multipleSelectValue
410
+ .map((val) => (_options.value.find((op) => op.value === val) || {}).label)
411
+ .filter((item) => typeof item !== 'undefined');
412
+ return multipleSelect.length ? multipleSelect.join() : itemValue;
413
+ });
414
+ // 事件监听
415
+ const listeners = vue.computed(() => {
416
+ const { id, on = {}, on: { input: originOnInput = noop, change: originOnChange = noop } = {}, trim = true } = data;
417
+ return {
418
+ ...lodashEs.fromPairs(lodashEs.toPairs(on).map(([eName, handler]) => [eName, (...args) => handler(args, formContext.updateForm)])),
419
+ // 手动更新表单数据
420
+ input: (val, ...rest) => {
421
+ // 调用自定义input事件
422
+ originOnInput([val, ...rest], formContext.updateForm, formContext.setOptions);
423
+ // element 以下组件没有input事件,当调用原生input事件时,取值有问题,直接return
424
+ if (['radio-group', 'checkbox-group', 'select', 'tree-select'].includes(data.type || '')) {
425
+ return;
426
+ }
427
+ emit('updateValue', { id, val });
428
+ // 触发校验
429
+ triggerValidate();
430
+ },
431
+ change: (val, ...rest) => {
432
+ // 调用自定义change事件
433
+ originOnChange([val, ...rest], formContext.updateForm, formContext.setOptions);
434
+ // element 以下组件没有change事件,当调用原生change事件时,取值有问题,直接return
435
+ if (['tree-select'].includes(data.type || '')) {
436
+ return;
437
+ }
438
+ if (typeof val === 'string' && trim) {
439
+ val = val.trim();
440
+ }
441
+ emit('updateValue', { id, val });
442
+ // 触发校验
443
+ triggerValidate();
444
+ }
445
+ };
446
+ });
447
+ const triggerValidate = async () => {
448
+ var _a;
449
+ if (!data.rules || !data.rules.length) {
450
+ return;
451
+ }
452
+ if (isBlurTrigger.value) {
453
+ return;
454
+ }
455
+ (_a = formContext.elFormRef.value) === null || _a === void 0 ? void 0 : _a.validateField(props.id).catch(() => { });
456
+ };
457
+ const optionKey = (opt) => {
458
+ if (opt.value instanceof Object) {
459
+ if (!data.el || !data.el.valueKey) {
460
+ return;
461
+ }
462
+ return opt.value[data.el.valueKey];
463
+ }
464
+ else {
465
+ return opt.value;
466
+ }
467
+ };
468
+ // 收集options
469
+ vue.watch(() => data.remote, (v, oldV) => {
470
+ if (!v || !v.url) {
471
+ return;
472
+ }
473
+ if (oldV) {
474
+ if (v.url === oldV.url || v.request === oldV.request) {
475
+ return;
476
+ }
477
+ }
478
+ // 需要options的type类型组件
479
+ const isOptionsCase = ['select', 'checkbox-group', 'radio-group'].includes(data.type || '');
480
+ // 级联选择
481
+ const isCascader = data.type === 'cascader';
482
+ // 支持post
483
+ const { url, request = () => url(v.params || {}).then((resp) => resp), prop = 'options', // 默认处理 el-cascader 的情况
484
+ dataPath = '', onResponse = (resp) => {
485
+ // 根据索引找到数据
486
+ if (dataPath) {
487
+ resp = lodashEs.get(resp, dataPath);
488
+ }
489
+ if (isOptionsCase) {
490
+ return resp.map((item) => {
491
+ let displayLabel;
492
+ let displayValue;
493
+ if (typeof label === 'function') {
494
+ displayLabel = label(item);
495
+ }
496
+ else {
497
+ displayLabel = item[label];
498
+ }
499
+ if (typeof value === 'function') {
500
+ displayValue = value(item);
501
+ }
502
+ else {
503
+ displayValue = item[value];
504
+ }
505
+ return {
506
+ label: displayLabel,
507
+ value: displayValue
508
+ };
509
+ });
510
+ }
511
+ else if (isCascader) {
512
+ return transformTreeValue(resp, {
513
+ label,
514
+ value,
515
+ children
516
+ });
517
+ }
518
+ else {
519
+ return resp;
520
+ }
521
+ }, onError = (error) => console.error(error.message), label = 'label', value = 'value', children = 'children' } = v;
522
+ Promise.resolve(request())
523
+ .then(onResponse, onError)
524
+ .then((resp) => {
525
+ if (isOptionsCase) {
526
+ formContext.setOptions(props.id, resp);
527
+ }
528
+ else {
529
+ propsInner.value = {
530
+ [prop]: resp
531
+ };
532
+ }
533
+ });
534
+ }, {
535
+ immediate: true
536
+ });
537
+ return (_ctx, _cache) => {
538
+ const _component_el_input = vue.resolveComponent("el-input");
539
+ const _component_el_option = vue.resolveComponent("el-option");
540
+ const _component_el_checkbox = vue.resolveComponent("el-checkbox");
541
+ const _component_el_radio_button = vue.resolveComponent("el-radio-button");
542
+ const _component_el_radio = vue.resolveComponent("el-radio");
543
+ const _component_el_form_item = vue.resolveComponent("el-form-item");
544
+ return (_show.value)
545
+ ? (vue.openBlock(), vue.createBlock(_component_el_form_item, vue.mergeProps({ key: 0 }, vue.unref(data), {
546
+ label: _isLabelTypeStr.value ? vue.unref(data).label : '',
547
+ prop: props.id
548
+ }), vue.createSlots({
549
+ default: vue.withCtx(() => [
550
+ (readonly.value && hasReadonlyContent.value)
551
+ ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
552
+ (vue.unref(data).type === 'input')
553
+ ? (vue.openBlock(), vue.createBlock(_component_el_input, vue.mergeProps({ key: 0 }, componentProps.value, {
554
+ value: itemValue.value,
555
+ readonly: "",
556
+ placeholder: "--"
557
+ }), null, 16 /* FULL_PROPS */, ["value"]))
558
+ : (vue.unref(data).type === 'select')
559
+ ? (vue.openBlock(), vue.createBlock(_component_el_input, {
560
+ key: 1,
561
+ value: multipleValue.value,
562
+ readonly: "",
563
+ placeholder: "--"
564
+ }, null, 8 /* PROPS */, ["value"]))
565
+ : vue.createCommentVNode("v-if", true)
566
+ ], 64 /* STABLE_FRAGMENT */))
567
+ : (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(data).component || vue.unref(RenderComponent)), vue.mergeProps({ key: 1 }, componentProps.value, {
568
+ modelValue: itemValue.value,
569
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => ((itemValue).value = $event)),
570
+ disabled: props.disabled || disabledStatus.value || readonly.value
571
+ }, vue.toHandlers(listeners.value)), {
572
+ default: vue.withCtx(() => [
573
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_options.value, (opt, index) => {
574
+ var _a, _b;
575
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
576
+ (vue.unref(data).type === 'select')
577
+ ? (vue.openBlock(), vue.createBlock(_component_el_option, vue.mergeProps({
578
+ key: optionKey(opt) || index
579
+ }, { ref_for: true }, opt), null, 16 /* FULL_PROPS */))
580
+ : (vue.unref(data).type === 'checkbox-group')
581
+ ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
582
+ vue.createCommentVNode(" el-checkbox "),
583
+ (vue.openBlock(), vue.createBlock(_component_el_checkbox, vue.mergeProps({
584
+ key: opt.value
585
+ }, { ref_for: true }, opt, {
586
+ label: 'value' in opt ? opt.value : opt.label
587
+ }), {
588
+ default: vue.withCtx(() => [
589
+ vue.createTextVNode(vue.toDisplayString(opt.label), 1 /* TEXT */)
590
+ ]),
591
+ _: 2 /* DYNAMIC */
592
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["label"]))
593
+ ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
594
+ : (vue.unref(data).type === 'radio-group')
595
+ ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
596
+ vue.createCommentVNode(" WARNING: radio 用 label 属性来表示 value 的含义 "),
597
+ vue.createCommentVNode(" FYI: radio 的 value 属性可以在没有 radio-group 时用来关联到同一个 v-model "),
598
+ (((_b = (_a = vue.unref(data)) === null || _a === void 0 ? void 0 : _a.el) === null || _b === void 0 ? void 0 : _b.type) === 'button')
599
+ ? (vue.openBlock(), vue.createBlock(_component_el_radio_button, vue.mergeProps({ key: index }, { ref_for: true }, opt, {
600
+ label: 'value' in opt ? opt.value : opt.label
601
+ }), {
602
+ default: vue.withCtx(() => [
603
+ vue.createTextVNode(vue.toDisplayString(opt.label), 1 /* TEXT */)
604
+ ]),
605
+ _: 2 /* DYNAMIC */
606
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["label"]))
607
+ : (vue.openBlock(), vue.createBlock(_component_el_radio, vue.mergeProps({
608
+ key: opt.label
609
+ }, { ref_for: true }, opt, {
610
+ label: 'value' in opt ? opt.value : opt.label
611
+ }), {
612
+ default: vue.withCtx(() => [
613
+ vue.createTextVNode(vue.toDisplayString(opt.label), 1 /* TEXT */)
614
+ ]),
615
+ _: 2 /* DYNAMIC */
616
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["label"]))
617
+ ], 64 /* STABLE_FRAGMENT */))
618
+ : vue.createCommentVNode("v-if", true)
619
+ ], 64 /* STABLE_FRAGMENT */));
620
+ }), 256 /* UNKEYED_FRAGMENT */))
621
+ ]),
622
+ _: 1 /* STABLE */
623
+ }, 16 /* FULL_PROPS */, ["modelValue", "disabled"]))
624
+ ]),
625
+ _: 2 /* DYNAMIC */
626
+ }, [
627
+ (!_isLabelTypeStr.value)
628
+ ? {
629
+ name: "label",
630
+ fn: vue.withCtx(() => [
631
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(data).label)))
632
+ ]),
633
+ key: "0"
634
+ }
635
+ : undefined
636
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["label", "prop"]))
637
+ : vue.createCommentVNode("v-if", true);
638
+ };
639
+ }
640
+ });
641
+
642
+ script$2.__file = "src/components/RenderFormItem.vue";
643
+
644
+ var script$1 = /*@__PURE__*/ vue.defineComponent({
645
+ __name: 'RenderFormGroup',
646
+ props: /*@__PURE__*/ vue.mergeModels(renderFormItemProps, {
647
+ "itemValue": { type: null },
648
+ "itemValueModifiers": {},
649
+ }),
650
+ emits: /*@__PURE__*/ vue.mergeModels(['updateValue'], ["update:itemValue"]),
651
+ setup(__props, { emit: __emit }) {
652
+ const props = __props;
653
+ const itemValue = vue.useModel(__props, 'itemValue');
654
+ const emit = __emit;
655
+ const { data, value } = props;
656
+ const { hidden = () => false } = data;
657
+ // 是否显示
658
+ const _show = vue.computed(() => !hidden(value, data));
659
+ const updateValue = ({ id, val }) => {
660
+ emit('updateValue', {
661
+ id: data.id,
662
+ val: {
663
+ ...itemValue.value,
664
+ [id]: val
665
+ }
666
+ });
667
+ };
668
+ return (_ctx, _cache) => {
669
+ return (_show.value)
670
+ ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(vue.unref(data).items, (item, index) => {
671
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: index }, [
672
+ vue.renderSlot(_ctx.$slots, `id:${item.id}`),
673
+ vue.createVNode(script$2, {
674
+ itemValue: itemValue.value[item.id],
675
+ "onUpdate:itemValue": ($event) => ((itemValue.value[item.id]) = $event),
676
+ ref_for: true,
677
+ ref: `formItem-${item.id}`,
678
+ id: `${vue.unref(data).id}.${item.id}`,
679
+ data: item,
680
+ value: vue.unref(value),
681
+ disabled: _ctx.disabled,
682
+ readonly: _ctx.readonly,
683
+ zindex: index,
684
+ onUpdateValue: updateValue
685
+ }, null, 8 /* PROPS */, ["itemValue", "onUpdate:itemValue", "id", "data", "value", "disabled", "readonly", "zindex"])
686
+ ], 64 /* STABLE_FRAGMENT */));
687
+ }), 128 /* KEYED_FRAGMENT */))
688
+ : vue.createCommentVNode("v-if", true);
689
+ };
690
+ }
691
+ });
692
+
693
+ script$1.__file = "src/components/RenderFormGroup.vue";
694
+
695
+ const GROUP = 'group'; // 表单嵌套组
696
+ // 表单内部状态
697
+ var script = /*@__PURE__*/ vue.defineComponent({
698
+ ...{
699
+ name: 'VFormRenderer'
700
+ },
701
+ __name: 'v-form-renderer',
702
+ props: /*@__PURE__*/ vue.mergeModels(vFormProps, {
703
+ "model": {},
704
+ "modelModifiers": {},
705
+ }),
706
+ emits: /*@__PURE__*/ vue.mergeModels(['enter'], ["update:model"]),
707
+ setup(__props, { expose: __expose }) {
708
+ // 定义v-model指令
709
+ const model = vue.useModel(__props, 'model');
710
+ const props = __props;
711
+ const { labelWidth, content, disabled, readonly, inline } = vue.toRefs(props);
712
+ const formState = useFormState({ props });
713
+ const { formModel, elFormRef } = formState;
714
+ // 表单内部方法
715
+ const formMethods = useFormMethods({ ...formState });
716
+ const { updateFormValue, initFormValues } = formMethods;
717
+ // 表单事件
718
+ const formEvents = useFormEvents({ ...formState });
719
+ // 初始化表单默认值
720
+ initFormValues();
721
+ // 当前组件所有的状态和方法
722
+ const instance = {
723
+ ...formState,
724
+ ...formMethods,
725
+ ...formEvents
726
+ };
727
+ createFormContext(instance);
728
+ __expose({ ...formEvents });
729
+ vue.watch(formModel, (val) => {
730
+ // 如果表单未绑定v-model则不更新model的值
731
+ if (!model.value) {
732
+ return;
733
+ }
734
+ model.value = val;
735
+ }, { immediate: true });
736
+ vue.watch(model, (v, oldV) => {
737
+ if (!v || lodashEs.isEqual(v, oldV)) {
738
+ return;
739
+ }
740
+ formEvents.updateForm(lodashEs.cloneDeep(v));
741
+ }, { immediate: true });
742
+ return (_ctx, _cache) => {
743
+ const _component_el_form = vue.resolveComponent("el-form");
744
+ return (vue.openBlock(), vue.createElementBlock("div", null, [
745
+ vue.createVNode(_component_el_form, vue.mergeProps({
746
+ ref_key: "elFormRef",
747
+ ref: elFormRef,
748
+ inline: vue.unref(inline),
749
+ "label-width": vue.unref(labelWidth)
750
+ }, _ctx.$attrs, {
751
+ model: vue.unref(formModel),
752
+ class: "el-form-renderer",
753
+ onSubmit: _cache[0] || (_cache[0] = vue.withModifiers(() => { }, ["prevent"])),
754
+ onKeyup: _cache[1] || (_cache[1] = vue.withKeys(($event) => (_ctx.$emit('enter')), ["enter"]))
755
+ }), {
756
+ default: vue.withCtx(() => [
757
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(content), (item) => {
758
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
759
+ key: item.id
760
+ }, [
761
+ vue.renderSlot(_ctx.$slots, `id:${item.id}`),
762
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.type === GROUP ? script$1 : script$2), {
763
+ itemValue: vue.unref(formModel)[item.id],
764
+ "onUpdate:itemValue": ($event) => ((vue.unref(formModel)[item.id]) = $event),
765
+ ref_for: true,
766
+ ref: item.id,
767
+ data: item,
768
+ id: item.id,
769
+ value: vue.unref(formModel),
770
+ disabled: vue.unref(disabled),
771
+ readonly: vue.unref(readonly) || item.readonly,
772
+ onUpdateValue: vue.unref(updateFormValue)
773
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["itemValue", "onUpdate:itemValue", "data", "id", "value", "disabled", "readonly", "onUpdateValue"]))
774
+ ], 64 /* STABLE_FRAGMENT */));
775
+ }), 128 /* KEYED_FRAGMENT */)),
776
+ vue.renderSlot(_ctx.$slots, "default")
777
+ ]),
778
+ _: 3 /* FORWARDED */
779
+ }, 16 /* FULL_PROPS */, ["inline", "label-width", "model"])
780
+ ]));
781
+ };
782
+ }
783
+ });
14
784
 
15
- script.render = render;
16
785
  script.__scopeId = "data-v-3f4b8568";
17
786
  script.__file = "src/v-form-renderer.vue";
18
787
 
19
788
  exports.default = script;
20
- //# sourceMappingURL=index.cjs.js.map
789
+ exports.vFormProps = vFormProps;