mirror of
https://github.com/imdap/ruoyi-plus-vben5.git
synced 2026-04-23 00:38:34 +08:00
fix: fix lint and add new form-ui features
feat(form-ui): 在 dependencies 里提供访问extendApi的能力
This commit is contained in:
@@ -1,19 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { CollapsibleParamSchema } from '@vben-core/shadcn-ui';
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { Page, useVbenModal, z } from '@vben/common-ui';
|
||||
|
||||
import { VbenCollapsibleParams } from '@vben-core/shadcn-ui';
|
||||
|
||||
import {
|
||||
NButton,
|
||||
NCard,
|
||||
NRadioButton,
|
||||
NRadioGroup,
|
||||
useMessage,
|
||||
} from 'naive-ui';
|
||||
import { NButton, NCard, useMessage } from 'naive-ui';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getAllMenusApi } from '#/api';
|
||||
@@ -22,111 +10,6 @@ import modalDemo from './modal.vue';
|
||||
|
||||
const message = useMessage();
|
||||
|
||||
const layouts = [
|
||||
{ label: 'Vertical', value: 'vertical' },
|
||||
{ label: 'Horizontal', value: 'horizontal' },
|
||||
{ label: 'Inline', value: 'inline' },
|
||||
];
|
||||
const layout = ref(layouts[0].value);
|
||||
|
||||
function getNumberValidator(key: string, limit?: [number, number]) {
|
||||
let validator = z.number({
|
||||
required_error: `${key} 值不能为空`,
|
||||
invalid_type_error: `${key} 值只能为数字`,
|
||||
});
|
||||
|
||||
if (limit) {
|
||||
validator = validator
|
||||
.min(limit[0], { message: `${key} 值不在区间范围内` })
|
||||
.max(limit[1], { message: `${key} 值不在区间范围内` });
|
||||
}
|
||||
|
||||
return validator.default(null);
|
||||
}
|
||||
|
||||
const paramsSchema = [
|
||||
{
|
||||
key: 'micro_batch_size',
|
||||
description: `批次大小,代表模型训练过程中,模型更新模型参数的数据步长,可理解为模型每看多少数据即更新一次模型参数,
|
||||
一般建议的批次大小为16/32,表示模型每看16或32条数据即更新一次参数`,
|
||||
// defaultValue: 8,
|
||||
option: {
|
||||
min: 8,
|
||||
max: 1024,
|
||||
step: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'learning_rate',
|
||||
description:
|
||||
'学习率,代表每次更新数据的增量参数权重,学习率数值越大参数变化越大,对模型影响越大',
|
||||
// defaultValue: 1e-5,
|
||||
option: {
|
||||
step: 1e-4,
|
||||
type: 'exponential',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'eval_steps',
|
||||
description:
|
||||
'验证步数,训练阶段针模型的验证间隔步长,用于阶段性评估模型训练准确率、训练损失',
|
||||
// defaultValue: 50,
|
||||
option: {
|
||||
min: 1,
|
||||
max: 2_147_483_647,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'num_train_epochs',
|
||||
description:
|
||||
'循环次数,代表模型训练过程中模型学习数据集的次数,可理解为看几遍数据,一般建议的范围是1-3遍即可,可依据需求进行调整',
|
||||
// defaultValue: 3,
|
||||
option: {
|
||||
min: 1,
|
||||
max: 200,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'max_length',
|
||||
description: `序列长度,单个训练数据样本的最大长度,超出配置长度将丢弃`,
|
||||
// defaultValue: 32_768,
|
||||
option: {
|
||||
min: 500,
|
||||
max: 131_072,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'warmup_ratio',
|
||||
description: '学习率预热比例,学习率预热阶段占总训练步数的比例',
|
||||
// defaultValue: 0.05,
|
||||
option: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'save_steps',
|
||||
description: 'Checkpoint保存间隔',
|
||||
// defaultValue: 50,
|
||||
option: {
|
||||
min: 1,
|
||||
max: 2_147_483_647,
|
||||
},
|
||||
},
|
||||
] as CollapsibleParamSchema[];
|
||||
|
||||
const paramsValidator = z.object({
|
||||
micro_batch_size: getNumberValidator('micro_batch_size', [8, 1024]),
|
||||
learning_rate: getNumberValidator('learning_rate'),
|
||||
eval_steps: getNumberValidator('eval_steps', [1, 2_147_483_647]),
|
||||
num_train_epochs: getNumberValidator('num_train_epochs', [1, 200]),
|
||||
max_length: getNumberValidator('max_length', [1, 131_072]),
|
||||
warmup_ratio: getNumberValidator('warmup_ratio', [0, 1]),
|
||||
save_steps: getNumberValidator('save_steps', [1, 2_147_483_647]),
|
||||
});
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
commonConfig: {
|
||||
// 所有表单项
|
||||
@@ -260,17 +143,6 @@ const [Form, formApi] = useVbenForm({
|
||||
},
|
||||
collapsible: true,
|
||||
},
|
||||
{
|
||||
component: VbenCollapsibleParams,
|
||||
componentProps: {
|
||||
params: paramsSchema,
|
||||
},
|
||||
modelPropName: 'value',
|
||||
fieldName: 'params',
|
||||
label: '参数配置',
|
||||
formItemClass: 'col-span-2',
|
||||
rules: paramsValidator,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -282,27 +154,12 @@ function setFormValues() {
|
||||
radioButton: 'C',
|
||||
checkbox: ['A', 'C'],
|
||||
date: Date.now(),
|
||||
params: {
|
||||
micro_batch_size: 8,
|
||||
learning_rate: 1e-5,
|
||||
eval_steps: 50,
|
||||
num_train_epochs: 3,
|
||||
max_length: 32_768,
|
||||
warmup_ratio: 0.05,
|
||||
save_steps: 50,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
connectedComponent: modalDemo,
|
||||
});
|
||||
|
||||
function onLayoutChange(layout: string) {
|
||||
formApi.setState({
|
||||
layout,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Page
|
||||
@@ -311,14 +168,6 @@ function onLayoutChange(layout: string) {
|
||||
>
|
||||
<NCard title="基础表单" header-extra-class="gap-4">
|
||||
<template #header-extra>
|
||||
<NRadioGroup v-model:value="layout" @update:value="onLayoutChange">
|
||||
<NRadioButton
|
||||
v-for="layoutItem in layouts"
|
||||
:key="layoutItem.value"
|
||||
:value="layoutItem.value"
|
||||
:label="layoutItem.label"
|
||||
/>
|
||||
</NRadioGroup>
|
||||
<NButton type="primary" @click="setFormValues">设置表单值</NButton>
|
||||
<NButton type="primary" @click="modalApi.open()" class="ml-2">
|
||||
打开弹窗
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import type {
|
||||
ExtendedFormApi,
|
||||
FormItemDependencies,
|
||||
FormSchemaRuleType,
|
||||
MaybeComponentProps,
|
||||
} from '../types';
|
||||
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, isRef, ref, watch } from 'vue';
|
||||
|
||||
import { get, isBoolean, isFunction } from '@vben-core/shared/utils';
|
||||
|
||||
import { useFormValues } from 'vee-validate';
|
||||
|
||||
import { resolveFieldNamePath } from '../field-name';
|
||||
import { injectFormProps } from '../use-form-context';
|
||||
import { injectRenderFormProps } from './context';
|
||||
|
||||
/**
|
||||
@@ -37,6 +39,13 @@ export default function useDependencies(
|
||||
const values = useFormValues();
|
||||
|
||||
const formRenderProps = injectRenderFormProps();
|
||||
const [extendApi] = injectFormProps();
|
||||
|
||||
// 在 dependencies 里提供访问extendApi的能力
|
||||
const controller: ExtendedFormApi = isRef(extendApi)
|
||||
? (extendApi.value.formApi as ExtendedFormApi)
|
||||
: (extendApi.formApi as ExtendedFormApi);
|
||||
|
||||
const formApi = formRenderProps.form;
|
||||
|
||||
if (!formApi) {
|
||||
@@ -92,7 +101,7 @@ export default function useDependencies(
|
||||
const formValues = values.value;
|
||||
|
||||
if (isFunction(whenIf)) {
|
||||
isIf.value = !!(await whenIf(formValues, formApi));
|
||||
isIf.value = !!(await whenIf(formValues, formApi, controller));
|
||||
// 不渲染
|
||||
if (!isIf.value) return;
|
||||
} else if (isBoolean(whenIf)) {
|
||||
@@ -102,31 +111,35 @@ export default function useDependencies(
|
||||
|
||||
// 2. 判断show,如果show为false,则隐藏
|
||||
if (isFunction(show)) {
|
||||
isShow.value = !!(await show(formValues, formApi));
|
||||
isShow.value = !!(await show(formValues, formApi, controller));
|
||||
} else if (isBoolean(show)) {
|
||||
isShow.value = show;
|
||||
}
|
||||
|
||||
if (isFunction(componentProps)) {
|
||||
dynamicComponentProps.value = await componentProps(formValues, formApi);
|
||||
dynamicComponentProps.value = await componentProps(
|
||||
formValues,
|
||||
formApi,
|
||||
controller,
|
||||
);
|
||||
}
|
||||
|
||||
if (isFunction(rules)) {
|
||||
dynamicRules.value = await rules(formValues, formApi);
|
||||
dynamicRules.value = await rules(formValues, formApi, controller);
|
||||
}
|
||||
|
||||
if (isFunction(disabled)) {
|
||||
isDisabled.value = !!(await disabled(formValues, formApi));
|
||||
isDisabled.value = !!(await disabled(formValues, formApi, controller));
|
||||
} else if (isBoolean(disabled)) {
|
||||
isDisabled.value = disabled;
|
||||
}
|
||||
|
||||
if (isFunction(required)) {
|
||||
isRequired.value = !!(await required(formValues, formApi));
|
||||
isRequired.value = !!(await required(formValues, formApi, controller));
|
||||
}
|
||||
|
||||
if (isFunction(trigger)) {
|
||||
trigger(formValues, formApi);
|
||||
trigger(formValues, formApi, controller);
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
|
||||
@@ -3,6 +3,7 @@ export { setupVbenForm } from './config';
|
||||
export type {
|
||||
BaseFormComponentType,
|
||||
ExtendedFormApi,
|
||||
FormLayout,
|
||||
VbenFormProps,
|
||||
FormSchema as VbenFormSchema,
|
||||
} from './types';
|
||||
|
||||
@@ -85,16 +85,19 @@ export type FormSchemaRuleType =
|
||||
type FormItemDependenciesCondition<T = boolean | PromiseLike<boolean>> = (
|
||||
value: Partial<Record<string, any>>,
|
||||
actions: FormActions,
|
||||
controller: ExtendedFormApi, // 在 dependencies 里提供访问extendApi的能力
|
||||
) => T;
|
||||
|
||||
type FormItemDependenciesConditionWithRules = (
|
||||
value: Partial<Record<string, any>>,
|
||||
actions: FormActions,
|
||||
controller: ExtendedFormApi, // 在 dependencies 里提供访问extendApi的能力
|
||||
) => FormSchemaRuleType | PromiseLike<FormSchemaRuleType>;
|
||||
|
||||
type FormItemDependenciesConditionWithProps = (
|
||||
value: Partial<Record<string, any>>,
|
||||
actions: FormActions,
|
||||
controller: ExtendedFormApi, // 在 dependencies 里提供访问extendApi的能力
|
||||
) => MaybeComponentProps | PromiseLike<MaybeComponentProps>;
|
||||
|
||||
export interface FormItemDependencies {
|
||||
@@ -147,6 +150,7 @@ type ComponentProps =
|
||||
export interface FormCommonConfig {
|
||||
/**
|
||||
* 是否可折叠的
|
||||
* @default false
|
||||
*/
|
||||
collapsible?: boolean;
|
||||
/**
|
||||
|
||||
@@ -49,6 +49,27 @@ const FieldComponent = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const limitDisplay = computed(() => {
|
||||
if (
|
||||
props.data.option.min !== null &&
|
||||
props.data.option.min !== undefined &&
|
||||
props.data.option.max !== null &&
|
||||
props.data.option.max !== undefined
|
||||
) {
|
||||
return `[${props.data.option.min},${props.data.option.max}]`;
|
||||
}
|
||||
|
||||
if (props.data.option.min !== null && props.data.option.min !== undefined) {
|
||||
return `min:${props.data.option.min}`;
|
||||
}
|
||||
|
||||
if (props.data.option.max !== null && props.data.option.max !== undefined) {
|
||||
return `max:${props.data.option.max}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
function reset() {
|
||||
modelValue.value = props.data.defaultValue;
|
||||
}
|
||||
@@ -78,8 +99,8 @@ defineExpose({
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center flex-none text-muted-foreground pl-2 gap-2">
|
||||
<span v-if="data.option.min && data.option.max">
|
||||
[{{ data.option.min }},{{ data.option.max }}]
|
||||
<span v-if="limitDisplay">
|
||||
{{ limitDisplay }}
|
||||
</span>
|
||||
<span v-if="data.option.step && data.option.step !== 1">
|
||||
step:{{ data.option.step }}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Recordable } from '@vben-core/typings';
|
||||
|
||||
import type { CollapsibleParamSchema } from './type';
|
||||
|
||||
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
|
||||
@@ -29,7 +31,10 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
const emits = defineEmits<{ 'update:value': [any, string] }>();
|
||||
|
||||
const modelValue = defineModel('value');
|
||||
const modelValue = defineModel('value', {
|
||||
default: {} as Recordable<CollapsibleParamSchema['defaultValue']>,
|
||||
});
|
||||
|
||||
const visibleRefs = useTemplateRef('visibleRefs');
|
||||
const collapsibleRefs = useTemplateRef('collapsibleRefs');
|
||||
|
||||
@@ -59,11 +64,13 @@ const bodyStyle = computed(() => {
|
||||
});
|
||||
|
||||
function init(force = false) {
|
||||
const nextValue = { ...modelValue.value };
|
||||
const nextValue: Recordable<CollapsibleParamSchema['defaultValue']> = {
|
||||
...modelValue.value,
|
||||
};
|
||||
|
||||
for (const param of props.params) {
|
||||
if (force || nextValue[param.key] === undefined) {
|
||||
nextValue[param.key] = param.defaultValue ?? null;
|
||||
nextValue[param.key] = param.defaultValue ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,25 +81,40 @@ function toggleCollapsed() {
|
||||
open.value = !open.value;
|
||||
}
|
||||
|
||||
async function onParamValueChange(value: any, key: string) {
|
||||
async function onParamValueChange(_: any, key: string) {
|
||||
await nextTick();
|
||||
emits('update:value', modelValue.value, key);
|
||||
}
|
||||
|
||||
function resetValue() {
|
||||
function resetValues() {
|
||||
if (visibleRefs.value)
|
||||
for (const rowRef of visibleRefs.value) {
|
||||
rowRef.reset();
|
||||
rowRef?.reset();
|
||||
}
|
||||
|
||||
if (collapsibleRefs.value)
|
||||
for (const rowRef of collapsibleRefs.value) {
|
||||
rowRef.reset();
|
||||
rowRef?.reset();
|
||||
}
|
||||
|
||||
init(true);
|
||||
}
|
||||
|
||||
function updateValues(
|
||||
values: Recordable<CollapsibleParamSchema['defaultValue']>,
|
||||
) {
|
||||
const newValue = {} as Recordable<CollapsibleParamSchema['defaultValue']>;
|
||||
|
||||
for (const key in values) {
|
||||
if (!Object.hasOwn(values, key)) continue;
|
||||
if (!Object.hasOwn(modelValue.value, key)) continue;
|
||||
|
||||
newValue[key] = values[key];
|
||||
|
||||
modelValue.value = { ...modelValue.value, ...newValue };
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.params,
|
||||
() => init(),
|
||||
@@ -101,7 +123,8 @@ watch(
|
||||
|
||||
defineExpose({
|
||||
toggleCollapsed,
|
||||
resetValue,
|
||||
resetValues,
|
||||
updateValues,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"file": "file",
|
||||
"crop-image": "Crop image",
|
||||
"upload-image": "Click to upload image",
|
||||
"collapsible": "Collapsible FormItem Content"
|
||||
"collapsible": "Collapsible Form Field"
|
||||
},
|
||||
"vxeTable": {
|
||||
"title": "Vxe Table",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { FormLayout } from '@vben/common-ui';
|
||||
|
||||
import type { CollapsibleParamSchema } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { ref } from 'vue';
|
||||
@@ -13,22 +15,32 @@ import { useVbenForm, z } from '#/adapter/form';
|
||||
|
||||
import DocButton from '../doc-button.vue';
|
||||
|
||||
const layouts = [
|
||||
const layouts: { label: string; value: FormLayout }[] = [
|
||||
{ label: 'Vertical', value: 'vertical' },
|
||||
{ label: 'Horizontal', value: 'horizontal' },
|
||||
];
|
||||
const layout = ref(layouts[0].value);
|
||||
|
||||
function getNumberValidator(key: string, limit?: [number, number]) {
|
||||
const layout = ref(layouts[0]?.value ?? 'vertical');
|
||||
|
||||
function getNumberValidator(key: string, limit?: [number?, number?]) {
|
||||
let validator = z.number({
|
||||
required_error: `${key} 值不能为空`,
|
||||
invalid_type_error: `${key} 值只能为数字`,
|
||||
});
|
||||
|
||||
// validator.default(null);
|
||||
|
||||
if (limit) {
|
||||
validator = validator
|
||||
.min(limit[0], { message: `${key} 值不在区间范围内` })
|
||||
.max(limit[1], { message: `${key} 值不在区间范围内` });
|
||||
if (limit[0] !== undefined) {
|
||||
validator = validator.min(limit[0], {
|
||||
message: `${key} 值不能小于${limit[0]}`,
|
||||
});
|
||||
}
|
||||
if (limit[1] !== undefined) {
|
||||
validator = validator.max(limit[1], {
|
||||
message: `${key} 值不能大于${limit[0]}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return validator.default(null);
|
||||
@@ -107,12 +119,13 @@ const paramsValidator = z.object({
|
||||
learning_rate: getNumberValidator('learning_rate'),
|
||||
eval_steps: getNumberValidator('eval_steps', [1, 2_147_483_647]),
|
||||
num_train_epochs: getNumberValidator('num_train_epochs', [1, 200]),
|
||||
max_length: getNumberValidator('max_length', [1, 131_072]),
|
||||
max_length: getNumberValidator('max_length', [500, 131_072]),
|
||||
warmup_ratio: getNumberValidator('warmup_ratio', [0, 1]),
|
||||
save_steps: getNumberValidator('save_steps', [1, 2_147_483_647]),
|
||||
});
|
||||
|
||||
const [BaseForm, baseFormApi] = useVbenForm({
|
||||
showDefaultActions: false,
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
commonConfig: {
|
||||
// 在label后显示一个冒号
|
||||
@@ -129,6 +142,17 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||
// 水平布局,label和input在同一行
|
||||
layout: 'vertical',
|
||||
schema: [
|
||||
{
|
||||
component: 'Switch',
|
||||
fieldName: 'qat',
|
||||
componentProps: {
|
||||
checkedChildren: '开',
|
||||
unCheckedChildren: '关',
|
||||
class: 'w-auto',
|
||||
},
|
||||
label: 'QAT',
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
component: VbenCollapsibleParams,
|
||||
componentProps: {
|
||||
@@ -138,20 +162,70 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||
modelPropName: 'value',
|
||||
fieldName: 'params',
|
||||
label: '参数配置',
|
||||
formItemClass: 'col-span-2 items-baseline',
|
||||
formItemClass: 'col-span-8 items-baseline col-start-1',
|
||||
dependencies: {
|
||||
triggerFields: ['qat'],
|
||||
componentProps(values) {
|
||||
return {
|
||||
params: values.qat
|
||||
? [
|
||||
{
|
||||
key: 'calib_steps',
|
||||
description: `校准步数;校准的数据集大小 = 校准步数 * 训练的batch_size`,
|
||||
option: {
|
||||
min: 1,
|
||||
},
|
||||
},
|
||||
...paramsSchema,
|
||||
]
|
||||
: paramsSchema,
|
||||
};
|
||||
},
|
||||
trigger(values, __, controller) {
|
||||
const paramsRef =
|
||||
controller.getFieldComponentRef<typeof VbenCollapsibleParams>(
|
||||
'params',
|
||||
);
|
||||
if (values.qat) {
|
||||
paramsRef?.updateValues?.({
|
||||
calib_steps: 10,
|
||||
micro_batch_size: 32,
|
||||
learning_rate: 4e-5,
|
||||
eval_steps: 80,
|
||||
num_train_epochs: 3,
|
||||
max_length: 32_768,
|
||||
warmup_ratio: 0.1,
|
||||
save_steps: 80,
|
||||
});
|
||||
} else {
|
||||
paramsRef?.updateValues?.({ calib_steps: null });
|
||||
}
|
||||
},
|
||||
rules(values) {
|
||||
if (values.qat) {
|
||||
return paramsValidator.extend({
|
||||
calib_steps: getNumberValidator('calib_steps', [1]),
|
||||
});
|
||||
}
|
||||
return paramsValidator;
|
||||
},
|
||||
},
|
||||
rules: paramsValidator,
|
||||
// defaultValue: {
|
||||
// micro_batch_size: 24,
|
||||
// },
|
||||
},
|
||||
{
|
||||
component: 'RichEditor',
|
||||
fieldName: 'richEditor',
|
||||
label: '富文本',
|
||||
formItemClass: 'col-span-3 items-baseline',
|
||||
formItemClass: 'col-span-12 items-baseline',
|
||||
collapsible: true,
|
||||
defaultCollapsed: false, // 默认false
|
||||
},
|
||||
],
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
||||
wrapperClass: 'grid-cols-12',
|
||||
});
|
||||
|
||||
function onSubmit(values: Record<string, any>) {
|
||||
@@ -160,6 +234,12 @@ function onSubmit(values: Record<string, any>) {
|
||||
});
|
||||
}
|
||||
|
||||
function onLayoutChange(layout: FormLayout) {
|
||||
baseFormApi.setState({
|
||||
layout,
|
||||
});
|
||||
}
|
||||
|
||||
function handleSetFormValue() {
|
||||
baseFormApi.setFieldValue('params', {
|
||||
micro_batch_size: 8,
|
||||
@@ -172,10 +252,16 @@ function handleSetFormValue() {
|
||||
});
|
||||
}
|
||||
|
||||
function onLayoutChange(layout: string) {
|
||||
baseFormApi.setState({
|
||||
layout,
|
||||
});
|
||||
function handleResetFormValue() {
|
||||
baseFormApi.resetForm(undefined, { force: true });
|
||||
}
|
||||
|
||||
async function handleSubmitFormValue() {
|
||||
const { valid } = await baseFormApi.validate();
|
||||
|
||||
if (valid) {
|
||||
baseFormApi.submitForm();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -201,10 +287,16 @@ function onLayoutChange(layout: string) {
|
||||
option-type="button"
|
||||
v-model:value="layout"
|
||||
@update:value="onLayoutChange"
|
||||
>
|
||||
/>
|
||||
<Button type="primary" @click="handleSetFormValue">
|
||||
设置表单值
|
||||
</RadioGroup>
|
||||
<Button type="primary" @click="handleSetFormValue">设置表单值</Button>
|
||||
</Button>
|
||||
<Button type="primary" @click="handleSubmitFormValue">
|
||||
提交表单
|
||||
</Button>
|
||||
<Button type="primary" @click="handleResetFormValue">
|
||||
重置表单
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-full overflow-hidden">
|
||||
|
||||
Reference in New Issue
Block a user