@tmagic/form 1.7.14-beta.2 → 1.7.14-beta.3
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/es/Form.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/containers/table-group-list/useAdd.js +1 -1
- package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CheckboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Date.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/DateTime.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Daterange.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Display.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +26 -9
- package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Timerange.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/index.js +3 -2
- package/dist/es/submitForm.js +87 -0
- package/dist/es/utils/form.js +2 -2
- package/dist/tmagic-form.umd.cjs +177 -66
- package/package.json +4 -4
- package/src/FormBox.vue +3 -1
- package/src/FormDialog.vue +4 -1
- package/src/FormDrawer.vue +4 -1
- package/src/containers/table-group-list/useAdd.ts +1 -1
- package/src/fields/Select.vue +35 -8
- package/src/index.ts +1 -0
- package/src/submitForm.ts +161 -0
- package/types/index.d.ts +91 -29
package/dist/tmagic-form.umd.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue"), require("
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue"), require("@tmagic/design"), require("@tmagic/utils"), require("@element-plus/icons-vue"), require("dayjs"), require("dayjs/plugin/utc"), require("@popperjs/core")) : typeof define === "function" && define.amd ? define([
|
|
3
3
|
"exports",
|
|
4
4
|
"vue",
|
|
5
|
-
"dayjs",
|
|
6
|
-
"dayjs/plugin/utc",
|
|
7
|
-
"@tmagic/utils",
|
|
8
5
|
"@tmagic/design",
|
|
6
|
+
"@tmagic/utils",
|
|
9
7
|
"@element-plus/icons-vue",
|
|
8
|
+
"dayjs",
|
|
9
|
+
"dayjs/plugin/utc",
|
|
10
10
|
"@popperjs/core"
|
|
11
|
-
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.TMagicForm = {}, global.Vue, global.
|
|
12
|
-
})(this, function(exports, vue,
|
|
11
|
+
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.TMagicForm = {}, global.Vue, global._tmagic_design, global._tmagic_utils, global._element_plus_icons_vue, global.dayjs, global.dayjs_plugin_utc, global._popperjs_core));
|
|
12
|
+
})(this, function(exports, vue, _tmagic_design, _tmagic_utils, _element_plus_icons_vue, dayjs, dayjs_plugin_utc, _popperjs_core) {
|
|
13
13
|
Object.defineProperties(exports, {
|
|
14
14
|
__esModule: { value: true },
|
|
15
15
|
[Symbol.toStringTag]: { value: "Module" }
|
|
@@ -2617,6 +2617,52 @@
|
|
|
2617
2617
|
return baseIsEqual(value, other);
|
|
2618
2618
|
}
|
|
2619
2619
|
//#endregion
|
|
2620
|
+
//#region packages/form/src/utils/useAddField.ts
|
|
2621
|
+
var useAddField = (prop) => {
|
|
2622
|
+
if (!prop) return;
|
|
2623
|
+
const mForm = (0, vue.inject)("mForm");
|
|
2624
|
+
const instance = (0, vue.getCurrentInstance)();
|
|
2625
|
+
(0, vue.watch)(() => instance?.proxy, (vm) => {
|
|
2626
|
+
if (vm) mForm?.setField(prop, vm);
|
|
2627
|
+
else mForm?.deleteField(prop);
|
|
2628
|
+
}, { immediate: true });
|
|
2629
|
+
};
|
|
2630
|
+
//#endregion
|
|
2631
|
+
//#region packages/form/src/fields/Hidden.vue
|
|
2632
|
+
var Hidden_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
2633
|
+
name: "MFormHidden",
|
|
2634
|
+
__name: "Hidden",
|
|
2635
|
+
props: {
|
|
2636
|
+
model: {},
|
|
2637
|
+
name: {},
|
|
2638
|
+
prop: {}
|
|
2639
|
+
},
|
|
2640
|
+
setup(__props) {
|
|
2641
|
+
useAddField(__props.prop);
|
|
2642
|
+
return (_ctx, _cache) => {
|
|
2643
|
+
return __props.model ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("input", {
|
|
2644
|
+
key: 0,
|
|
2645
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => __props.model[__props.name] = $event),
|
|
2646
|
+
type: "hidden"
|
|
2647
|
+
}, null, 512)), [[vue.vModelText, __props.model[__props.name]]]) : (0, vue.createCommentVNode)("v-if", true);
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
});
|
|
2651
|
+
//#endregion
|
|
2652
|
+
//#region packages/form/src/utils/config.ts
|
|
2653
|
+
var $MAGIC_FORM = {};
|
|
2654
|
+
var setConfig = (option) => {
|
|
2655
|
+
$MAGIC_FORM = option;
|
|
2656
|
+
};
|
|
2657
|
+
var getConfig = (key) => $MAGIC_FORM[key];
|
|
2658
|
+
var fieldRegistry = /* @__PURE__ */ new Map();
|
|
2659
|
+
var registerField = (tagName, component) => {
|
|
2660
|
+
if (fieldRegistry.has(tagName)) return;
|
|
2661
|
+
fieldRegistry.set(tagName, component);
|
|
2662
|
+
};
|
|
2663
|
+
var getField = (tagName) => fieldRegistry.get(tagName);
|
|
2664
|
+
var deleteField = (tagName) => fieldRegistry.delete(tagName);
|
|
2665
|
+
//#endregion
|
|
2620
2666
|
//#region packages/form/src/utils/form.ts
|
|
2621
2667
|
var TABLE_SELECT_TYPES = new Set(["table-select", "tableSelect"]);
|
|
2622
2668
|
var isTableSelect = (type) => typeof type === "string" && TABLE_SELECT_TYPES.has(type);
|
|
@@ -2786,52 +2832,6 @@
|
|
|
2786
2832
|
return `${[...itemPath, key].join(".")}`;
|
|
2787
2833
|
};
|
|
2788
2834
|
//#endregion
|
|
2789
|
-
//#region packages/form/src/utils/useAddField.ts
|
|
2790
|
-
var useAddField = (prop) => {
|
|
2791
|
-
if (!prop) return;
|
|
2792
|
-
const mForm = (0, vue.inject)("mForm");
|
|
2793
|
-
const instance = (0, vue.getCurrentInstance)();
|
|
2794
|
-
(0, vue.watch)(() => instance?.proxy, (vm) => {
|
|
2795
|
-
if (vm) mForm?.setField(prop, vm);
|
|
2796
|
-
else mForm?.deleteField(prop);
|
|
2797
|
-
}, { immediate: true });
|
|
2798
|
-
};
|
|
2799
|
-
//#endregion
|
|
2800
|
-
//#region packages/form/src/fields/Hidden.vue
|
|
2801
|
-
var Hidden_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
2802
|
-
name: "MFormHidden",
|
|
2803
|
-
__name: "Hidden",
|
|
2804
|
-
props: {
|
|
2805
|
-
model: {},
|
|
2806
|
-
name: {},
|
|
2807
|
-
prop: {}
|
|
2808
|
-
},
|
|
2809
|
-
setup(__props) {
|
|
2810
|
-
useAddField(__props.prop);
|
|
2811
|
-
return (_ctx, _cache) => {
|
|
2812
|
-
return __props.model ? (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("input", {
|
|
2813
|
-
key: 0,
|
|
2814
|
-
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => __props.model[__props.name] = $event),
|
|
2815
|
-
type: "hidden"
|
|
2816
|
-
}, null, 512)), [[vue.vModelText, __props.model[__props.name]]]) : (0, vue.createCommentVNode)("v-if", true);
|
|
2817
|
-
};
|
|
2818
|
-
}
|
|
2819
|
-
});
|
|
2820
|
-
//#endregion
|
|
2821
|
-
//#region packages/form/src/utils/config.ts
|
|
2822
|
-
var $MAGIC_FORM = {};
|
|
2823
|
-
var setConfig = (option) => {
|
|
2824
|
-
$MAGIC_FORM = option;
|
|
2825
|
-
};
|
|
2826
|
-
var getConfig = (key) => $MAGIC_FORM[key];
|
|
2827
|
-
var fieldRegistry = /* @__PURE__ */ new Map();
|
|
2828
|
-
var registerField = (tagName, component) => {
|
|
2829
|
-
if (fieldRegistry.has(tagName)) return;
|
|
2830
|
-
fieldRegistry.set(tagName, component);
|
|
2831
|
-
};
|
|
2832
|
-
var getField = (tagName) => fieldRegistry.get(tagName);
|
|
2833
|
-
var deleteField = (tagName) => fieldRegistry.delete(tagName);
|
|
2834
|
-
//#endregion
|
|
2835
2835
|
//#region packages/form/src/containers/FormLabel.vue?vue&type=script&setup=true&lang.ts
|
|
2836
2836
|
var _hoisted_1$15 = {
|
|
2837
2837
|
key: 0,
|
|
@@ -3537,6 +3537,90 @@
|
|
|
3537
3537
|
}
|
|
3538
3538
|
});
|
|
3539
3539
|
//#endregion
|
|
3540
|
+
//#region packages/form/src/submitForm.ts
|
|
3541
|
+
/**
|
|
3542
|
+
* 以命令式方式调用 Form.vue 完成一次表单校验/提交。
|
|
3543
|
+
*
|
|
3544
|
+
* 类似 ElMessage 的用法:传入 props(包含 `config`/`initValues` 等),函数内部会临时挂载
|
|
3545
|
+
* 一个不可见的 Form 组件实例,等待初始化完成后调用其 `submitForm` 方法,
|
|
3546
|
+
* 校验通过则 resolve 表单值,校验失败则 reject 错误信息,最后自动卸载实例。
|
|
3547
|
+
*
|
|
3548
|
+
* @example
|
|
3549
|
+
* ```ts
|
|
3550
|
+
* import { submitForm } from '@tmagic/form';
|
|
3551
|
+
*
|
|
3552
|
+
* try {
|
|
3553
|
+
* const values = await submitForm({
|
|
3554
|
+
* config: [...],
|
|
3555
|
+
* initValues: { name: 'foo' },
|
|
3556
|
+
* });
|
|
3557
|
+
* console.log(values);
|
|
3558
|
+
* } catch (e) {
|
|
3559
|
+
* console.error(e);
|
|
3560
|
+
* }
|
|
3561
|
+
* ```
|
|
3562
|
+
*/
|
|
3563
|
+
var submitForm = (options) => {
|
|
3564
|
+
const { native, appContext, timeout = 1e4, ...formProps } = options;
|
|
3565
|
+
return new Promise((resolve, reject) => {
|
|
3566
|
+
const container = document.createElement("div");
|
|
3567
|
+
container.style.display = "none";
|
|
3568
|
+
document.body.appendChild(container);
|
|
3569
|
+
let cleaned = false;
|
|
3570
|
+
let timer = null;
|
|
3571
|
+
const app = (0, vue.createApp)((0, vue.defineComponent)({
|
|
3572
|
+
name: "MFormSubmitWrapper",
|
|
3573
|
+
setup() {
|
|
3574
|
+
const formRef = (0, vue.ref)(null);
|
|
3575
|
+
const stop = (0, vue.watch)(() => formRef.value?.initialized, async (initialized) => {
|
|
3576
|
+
if (!initialized) return;
|
|
3577
|
+
stop();
|
|
3578
|
+
try {
|
|
3579
|
+
await (0, vue.nextTick)();
|
|
3580
|
+
resolve(await formRef.value.submitForm(native));
|
|
3581
|
+
} catch (err) {
|
|
3582
|
+
reject(err);
|
|
3583
|
+
} finally {
|
|
3584
|
+
cleanup();
|
|
3585
|
+
}
|
|
3586
|
+
}, {
|
|
3587
|
+
flush: "post",
|
|
3588
|
+
immediate: true
|
|
3589
|
+
});
|
|
3590
|
+
return () => (0, vue.h)(Form_default, {
|
|
3591
|
+
...formProps,
|
|
3592
|
+
ref: formRef
|
|
3593
|
+
});
|
|
3594
|
+
}
|
|
3595
|
+
}));
|
|
3596
|
+
if (appContext) Object.assign(app._context, appContext);
|
|
3597
|
+
const cleanup = () => {
|
|
3598
|
+
if (cleaned) return;
|
|
3599
|
+
cleaned = true;
|
|
3600
|
+
if (timer) {
|
|
3601
|
+
clearTimeout(timer);
|
|
3602
|
+
timer = null;
|
|
3603
|
+
}
|
|
3604
|
+
try {
|
|
3605
|
+
app.unmount();
|
|
3606
|
+
} catch {}
|
|
3607
|
+
container.parentNode?.removeChild(container);
|
|
3608
|
+
};
|
|
3609
|
+
if (timeout > 0) timer = setTimeout(() => {
|
|
3610
|
+
if (!cleaned) {
|
|
3611
|
+
reject(/* @__PURE__ */ new Error(`submitForm timeout after ${timeout}ms: form is not initialized.`));
|
|
3612
|
+
cleanup();
|
|
3613
|
+
}
|
|
3614
|
+
}, timeout);
|
|
3615
|
+
try {
|
|
3616
|
+
app.mount(container);
|
|
3617
|
+
} catch (err) {
|
|
3618
|
+
reject(err);
|
|
3619
|
+
cleanup();
|
|
3620
|
+
}
|
|
3621
|
+
});
|
|
3622
|
+
};
|
|
3623
|
+
//#endregion
|
|
3540
3624
|
//#region packages/form/src/FormDialog.vue?vue&type=script&setup=true&lang.ts
|
|
3541
3625
|
var _hoisted_1$13 = { style: { "min-height": "1px" } };
|
|
3542
3626
|
//#endregion
|
|
@@ -3578,7 +3662,8 @@
|
|
|
3578
3662
|
showCancel: {
|
|
3579
3663
|
type: Boolean,
|
|
3580
3664
|
default: true
|
|
3581
|
-
}
|
|
3665
|
+
},
|
|
3666
|
+
extendState: {}
|
|
3582
3667
|
},
|
|
3583
3668
|
emits: [
|
|
3584
3669
|
"close",
|
|
@@ -3728,6 +3813,7 @@
|
|
|
3728
3813
|
"label-position": __props.labelPosition,
|
|
3729
3814
|
inline: __props.inline,
|
|
3730
3815
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
3816
|
+
"extend-state": __props.extendState,
|
|
3731
3817
|
onChange: changeHandler
|
|
3732
3818
|
}, null, 8, [
|
|
3733
3819
|
"modelValue",
|
|
@@ -3739,7 +3825,8 @@
|
|
|
3739
3825
|
"label-width",
|
|
3740
3826
|
"label-position",
|
|
3741
3827
|
"inline",
|
|
3742
|
-
"prevent-submit-default"
|
|
3828
|
+
"prevent-submit-default",
|
|
3829
|
+
"extend-state"
|
|
3743
3830
|
]), (0, vue.renderSlot)(_ctx.$slots, "default")], 4)) : (0, vue.createCommentVNode)("v-if", true)]),
|
|
3744
3831
|
_: 3
|
|
3745
3832
|
}, 8, [
|
|
@@ -3782,7 +3869,8 @@
|
|
|
3782
3869
|
inline: { type: Boolean },
|
|
3783
3870
|
labelPosition: {},
|
|
3784
3871
|
preventSubmitDefault: { type: Boolean },
|
|
3785
|
-
beforeClose: {}
|
|
3872
|
+
beforeClose: {},
|
|
3873
|
+
extendState: {}
|
|
3786
3874
|
},
|
|
3787
3875
|
emits: [
|
|
3788
3876
|
"close",
|
|
@@ -3906,6 +3994,7 @@
|
|
|
3906
3994
|
"label-position": __props.labelPosition,
|
|
3907
3995
|
inline: __props.inline,
|
|
3908
3996
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
3997
|
+
"extend-state": __props.extendState,
|
|
3909
3998
|
onChange: changeHandler
|
|
3910
3999
|
}, null, 8, [
|
|
3911
4000
|
"size",
|
|
@@ -3916,7 +4005,8 @@
|
|
|
3916
4005
|
"label-width",
|
|
3917
4006
|
"label-position",
|
|
3918
4007
|
"inline",
|
|
3919
|
-
"prevent-submit-default"
|
|
4008
|
+
"prevent-submit-default",
|
|
4009
|
+
"extend-state"
|
|
3920
4010
|
]), (0, vue.renderSlot)(_ctx.$slots, "default")], 512)) : (0, vue.createCommentVNode)("v-if", true)]),
|
|
3921
4011
|
_: 3
|
|
3922
4012
|
}, 8, [
|
|
@@ -3950,7 +4040,8 @@
|
|
|
3950
4040
|
confirmText: { default: "确定" },
|
|
3951
4041
|
inline: { type: Boolean },
|
|
3952
4042
|
labelPosition: {},
|
|
3953
|
-
preventSubmitDefault: { type: Boolean }
|
|
4043
|
+
preventSubmitDefault: { type: Boolean },
|
|
4044
|
+
extendState: {}
|
|
3954
4045
|
},
|
|
3955
4046
|
emits: [
|
|
3956
4047
|
"change",
|
|
@@ -4012,6 +4103,7 @@
|
|
|
4012
4103
|
"label-position": __props.labelPosition,
|
|
4013
4104
|
inline: __props.inline,
|
|
4014
4105
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
4106
|
+
"extend-state": __props.extendState,
|
|
4015
4107
|
onChange: changeHandler
|
|
4016
4108
|
}, null, 8, [
|
|
4017
4109
|
"size",
|
|
@@ -4022,7 +4114,8 @@
|
|
|
4022
4114
|
"label-width",
|
|
4023
4115
|
"label-position",
|
|
4024
4116
|
"inline",
|
|
4025
|
-
"prevent-submit-default"
|
|
4117
|
+
"prevent-submit-default",
|
|
4118
|
+
"extend-state"
|
|
4026
4119
|
]), (0, vue.renderSlot)(_ctx.$slots, "default")]),
|
|
4027
4120
|
_: 3
|
|
4028
4121
|
})], 4), (0, vue.createElementVNode)("div", {
|
|
@@ -5666,7 +5759,7 @@
|
|
|
5666
5759
|
const addable = (0, vue.computed)(() => {
|
|
5667
5760
|
const modelName = props.name || props.config.name || "";
|
|
5668
5761
|
if (!modelName) return false;
|
|
5669
|
-
if (!props.model[modelName]
|
|
5762
|
+
if (!props.model[modelName]?.length) return true;
|
|
5670
5763
|
if (typeof props.config.addable === "function") return props.config.addable(mForm, {
|
|
5671
5764
|
model: props.model[modelName],
|
|
5672
5765
|
formValue: mForm?.values,
|
|
@@ -7078,6 +7171,18 @@
|
|
|
7078
7171
|
}
|
|
7079
7172
|
return value === v;
|
|
7080
7173
|
};
|
|
7174
|
+
const hasOption = (value) => {
|
|
7175
|
+
const { config } = props;
|
|
7176
|
+
if (Array.isArray(value) && !value.length) return true;
|
|
7177
|
+
if (config.group) {
|
|
7178
|
+
const groups = options.value;
|
|
7179
|
+
if (config.multiple && Array.isArray(value)) return value.every((v) => groups.some((group) => group.options.some((item) => equalValue(item.value, v))));
|
|
7180
|
+
return groups.some((group) => group.options.some((item) => equalValue(item.value, value)));
|
|
7181
|
+
}
|
|
7182
|
+
const opts = options.value;
|
|
7183
|
+
if (config.multiple && Array.isArray(value)) return value.every((v) => opts.some((item) => equalValue(item.value, v)));
|
|
7184
|
+
return opts.some((item) => equalValue(item.value, value));
|
|
7185
|
+
};
|
|
7081
7186
|
const mapOptions = (data) => {
|
|
7082
7187
|
const { option = {
|
|
7083
7188
|
text: "text",
|
|
@@ -7240,13 +7345,18 @@
|
|
|
7240
7345
|
else if (Array.isArray(props.config.options)) (0, vue.watchEffect)(() => {
|
|
7241
7346
|
setOptions(props.config.options);
|
|
7242
7347
|
});
|
|
7243
|
-
else if (props.config.option)
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7348
|
+
else if (props.config.option) {
|
|
7349
|
+
const initOption = async () => {
|
|
7350
|
+
if (!props.model) return;
|
|
7351
|
+
const v = props.model[props.name];
|
|
7352
|
+
if (Array.isArray(v) ? !v.length : typeof v === "undefined") return;
|
|
7353
|
+
if (typeof v === "undefined" || hasOption(v)) return;
|
|
7354
|
+
setOptions(await getInitOption());
|
|
7355
|
+
};
|
|
7356
|
+
(0, vue.watch)(() => props.model?.[props.name], () => {
|
|
7357
|
+
initOption();
|
|
7358
|
+
}, { immediate: true });
|
|
7359
|
+
}
|
|
7250
7360
|
if (props.config.remote) {
|
|
7251
7361
|
const unWatch = (0, vue.watch)(() => tMagicSelect.value?.scrollbarWrap, (scrollbarWrap) => {
|
|
7252
7362
|
if (!scrollbarWrap) return;
|
|
@@ -7741,6 +7851,7 @@
|
|
|
7741
7851
|
exports.registerFormField = registerField;
|
|
7742
7852
|
exports.sortArray = sortArray;
|
|
7743
7853
|
exports.sortChange = sortChange;
|
|
7854
|
+
exports.submitForm = submitForm;
|
|
7744
7855
|
exports.useAddField = useAddField;
|
|
7745
7856
|
var _tmagic_form_schema = require("@tmagic/form-schema");
|
|
7746
7857
|
Object.keys(_tmagic_form_schema).forEach(function(k) {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.7.14-beta.
|
|
2
|
+
"version": "1.7.14-beta.3",
|
|
3
3
|
"name": "@tmagic/form",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"vue": "^3.5.34",
|
|
54
54
|
"typescript": "^6.0.3",
|
|
55
|
-
"@tmagic/design": "1.7.14-beta.
|
|
56
|
-
"@tmagic/utils": "1.7.14-beta.
|
|
57
|
-
"@tmagic/form-schema": "1.7.14-beta.
|
|
55
|
+
"@tmagic/design": "1.7.14-beta.3",
|
|
56
|
+
"@tmagic/utils": "1.7.14-beta.3",
|
|
57
|
+
"@tmagic/form-schema": "1.7.14-beta.3"
|
|
58
58
|
},
|
|
59
59
|
"peerDependenciesMeta": {
|
|
60
60
|
"typescript": {
|
package/src/FormBox.vue
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
:label-position="labelPosition"
|
|
14
14
|
:inline="inline"
|
|
15
15
|
:prevent-submit-default="preventSubmitDefault"
|
|
16
|
+
:extend-state="extendState"
|
|
16
17
|
@change="changeHandler"
|
|
17
18
|
></Form>
|
|
18
19
|
<slot></slot>
|
|
@@ -40,7 +41,7 @@ import { computed, ref, watchEffect } from 'vue';
|
|
|
40
41
|
import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
|
|
41
42
|
|
|
42
43
|
import Form from './Form.vue';
|
|
43
|
-
import type { ContainerChangeEventData, FormConfig, FormValue } from './schema';
|
|
44
|
+
import type { ContainerChangeEventData, FormConfig, FormState, FormValue } from './schema';
|
|
44
45
|
|
|
45
46
|
defineOptions({
|
|
46
47
|
name: 'MFormBox',
|
|
@@ -60,6 +61,7 @@ const props = withDefaults(
|
|
|
60
61
|
inline?: boolean;
|
|
61
62
|
labelPosition?: string;
|
|
62
63
|
preventSubmitDefault?: boolean;
|
|
64
|
+
extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
63
65
|
}>(),
|
|
64
66
|
{
|
|
65
67
|
config: () => [],
|
package/src/FormDialog.vue
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
:label-position="labelPosition"
|
|
32
32
|
:inline="inline"
|
|
33
33
|
:prevent-submit-default="preventSubmitDefault"
|
|
34
|
+
:extend-state="extendState"
|
|
34
35
|
@change="changeHandler"
|
|
35
36
|
></Form>
|
|
36
37
|
<slot></slot>
|
|
@@ -68,7 +69,7 @@ import { computed, ref } from 'vue';
|
|
|
68
69
|
import { TMagicButton, TMagicCol, TMagicDialog, TMagicRow } from '@tmagic/design';
|
|
69
70
|
|
|
70
71
|
import Form from './Form.vue';
|
|
71
|
-
import { ContainerChangeEventData, FormConfig, FormValue, StepConfig } from './schema';
|
|
72
|
+
import { ContainerChangeEventData, FormConfig, FormState, FormValue, StepConfig } from './schema';
|
|
72
73
|
|
|
73
74
|
defineOptions({
|
|
74
75
|
name: 'MFormDialog',
|
|
@@ -95,6 +96,8 @@ const props = withDefaults(
|
|
|
95
96
|
destroyOnClose?: boolean;
|
|
96
97
|
showClose?: boolean;
|
|
97
98
|
showCancel?: boolean;
|
|
99
|
+
/** 透传给内部 `MForm`,用于扩展 `formState`(如注入 `$message` / `$store` 等) */
|
|
100
|
+
extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
98
101
|
}>(),
|
|
99
102
|
{
|
|
100
103
|
config: () => [],
|
package/src/FormDrawer.vue
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
:label-position="labelPosition"
|
|
29
29
|
:inline="inline"
|
|
30
30
|
:prevent-submit-default="preventSubmitDefault"
|
|
31
|
+
:extend-state="extendState"
|
|
31
32
|
@change="changeHandler"
|
|
32
33
|
></Form>
|
|
33
34
|
<slot></slot>
|
|
@@ -59,7 +60,7 @@ import { ref, watchEffect } from 'vue';
|
|
|
59
60
|
import { TMagicButton, TMagicCol, TMagicDrawer, TMagicRow } from '@tmagic/design';
|
|
60
61
|
|
|
61
62
|
import Form from './Form.vue';
|
|
62
|
-
import type { ContainerChangeEventData, FormConfig, FormValue } from './schema';
|
|
63
|
+
import type { ContainerChangeEventData, FormConfig, FormState, FormValue } from './schema';
|
|
63
64
|
|
|
64
65
|
defineOptions({
|
|
65
66
|
name: 'MFormDialog',
|
|
@@ -83,6 +84,8 @@ withDefaults(
|
|
|
83
84
|
preventSubmitDefault?: boolean;
|
|
84
85
|
/** 关闭前的回调,会暂停 Drawer 的关闭; done 是个 function type 接受一个 boolean 参数, 执行 done 使用 true 参数或不提供参数将会终止关闭 */
|
|
85
86
|
beforeClose?: (_done: (_cancel?: boolean) => void) => void;
|
|
87
|
+
/** 透传给内部 `MForm`,用于扩展 `formState`(如注入 `$message` / `$store` 等) */
|
|
88
|
+
extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
86
89
|
}>(),
|
|
87
90
|
{
|
|
88
91
|
closeOnPressEscape: true,
|
package/src/fields/Select.vue
CHANGED
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
</template>
|
|
79
79
|
|
|
80
80
|
<script lang="ts" setup>
|
|
81
|
-
import { inject, nextTick,
|
|
81
|
+
import { inject, nextTick, ref, watch, watchEffect } from 'vue';
|
|
82
82
|
|
|
83
83
|
import { getDesignConfig, TMagicSelect } from '@tmagic/design';
|
|
84
84
|
import { getValueByKeyPath } from '@tmagic/utils';
|
|
@@ -123,6 +123,26 @@ const equalValue = (value: any, v: any): boolean => {
|
|
|
123
123
|
return value === v;
|
|
124
124
|
};
|
|
125
125
|
|
|
126
|
+
const hasOption = (value: any): boolean => {
|
|
127
|
+
const { config } = props;
|
|
128
|
+
|
|
129
|
+
if (Array.isArray(value) && !value.length) return true;
|
|
130
|
+
|
|
131
|
+
if (config.group) {
|
|
132
|
+
const groups = options.value as SelectGroupOption[];
|
|
133
|
+
if (config.multiple && Array.isArray(value)) {
|
|
134
|
+
return value.every((v) => groups.some((group) => group.options.some((item) => equalValue(item.value, v))));
|
|
135
|
+
}
|
|
136
|
+
return groups.some((group) => group.options.some((item) => equalValue(item.value, value)));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const opts = options.value as SelectOption[];
|
|
140
|
+
if (config.multiple && Array.isArray(value)) {
|
|
141
|
+
return value.every((v) => opts.some((item) => equalValue(item.value, v)));
|
|
142
|
+
}
|
|
143
|
+
return opts.some((item) => equalValue(item.value, value));
|
|
144
|
+
};
|
|
145
|
+
|
|
126
146
|
const mapOptions = (data: any[]) => {
|
|
127
147
|
const {
|
|
128
148
|
option = {
|
|
@@ -392,15 +412,22 @@ if (typeof props.config.options === 'function') {
|
|
|
392
412
|
setOptions(props.config.options as SelectOption[] | SelectGroupOption[]);
|
|
393
413
|
});
|
|
394
414
|
} else if (props.config.option) {
|
|
395
|
-
|
|
415
|
+
const initOption = async () => {
|
|
396
416
|
if (!props.model) return;
|
|
397
417
|
const v = props.model[props.name];
|
|
398
|
-
if (Array.isArray(v) ? v.length : typeof v
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
418
|
+
if (Array.isArray(v) ? !v.length : typeof v === 'undefined') return;
|
|
419
|
+
if (typeof v === 'undefined' || hasOption(v)) return;
|
|
420
|
+
const data = await getInitOption();
|
|
421
|
+
setOptions(data);
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
watch(
|
|
425
|
+
() => props.model?.[props.name],
|
|
426
|
+
() => {
|
|
427
|
+
void initOption();
|
|
428
|
+
},
|
|
429
|
+
{ immediate: true },
|
|
430
|
+
);
|
|
404
431
|
}
|
|
405
432
|
|
|
406
433
|
if (props.config.remote) {
|