Skip to content

Bug: formApi.getValues() 无法获取 defaultValue #6213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
5 tasks done
dingdayu opened this issue May 16, 2025 · 2 comments
Open
5 tasks done

Bug: formApi.getValues() 无法获取 defaultValue #6213

dingdayu opened this issue May 16, 2025 · 2 comments

Comments

@dingdayu
Copy link
Contributor

dingdayu commented May 16, 2025

Version

Vben Admin V5

Describe the bug?

useVbenForm 了一个 表单,在 useVbenModal 的 onOpened 时 update 的 schema,在 onConfirm 中无法 formApi.getValues() 到 defaultValue,设置过 select 后可以获得值,否则,有对应的 schema 但是 Value 是 undefined.

defaultValue 在 componentProps 里外都尝试过,按照 useVbenForm 设计, defaultValue 应该在 FormSchema 中,但是 预览效果中无法显示默认值,在 componentProps 中,可以渲染,但着都不能出现在 formApi.getValues() 的输出里;这可能是另外的问题,此处不作讨论。

推断可能是 formApi.setState({schema: newSchema}); 时的问题。

代码是 5.5.6 版本 tag 后合并进我的项目的,检查过之后的 commit 没有 form 相关的更新。

Reproduction

代码如下

<script setup lang="ts">
import type { VbenFormSchema } from '@vben/common-ui';

import type { TaskArgsResponse } from '#/api';

import { ref, watchEffect } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import { useVbenForm } from '#/adapter/form';
import { getTaskArgsApi } from '#/api';
import CodeEditor from '#/components/code-editor/index.vue';

const emit = defineEmits(['run']);

const taskId = ref<number>(0);
const currentStep = ref(0);
const code = ref<string>(''); // 用于存储代码内容

const [Form, formApi] = useVbenForm({
  commonConfig: {
    labelWidth: -1,
    labelAlign: 'left',
    wrapperAlign: 'left',
  },
  handleSubmit: onSubmit,
  schema: [],
  showDefaultActions: false,
});

const [Modal, modalApi] = useVbenModal({
  destroyOnClose: true,
  fullscreenButton: false,
  confirmText: '下一步',
  confirmDisabled: true,
  onCancel() {
    if (currentStep.value === 0 || currentStep.value === 2) {
      modalApi.close();
      return;
    }
    // 返回上一步
    currentStep.value -= 1;
  },
  onConfirm: async () => {
    if (currentStep.value === 0) {
      // 第一步:填写表单
      // await modalApi.setState({
      //   confirmLoading: true,
      // });
      // 生成代码
      const vals = await formApi.getValues(); // 这里无法获得值,只能得到 {task_id: undefined} 这种,debug 了 form 的 values 里面代理的对象确实都是 undefined
      console.log('表单值:', vals);
    }
    // 第二步:预览代码
    if (currentStep.value === 2) {
      await modalApi.setState({
        confirmLoading: true,
      });
      // 提交表单
      formApi.validateAndSubmitForm().finally(() => {
        modalApi.setState({
          confirmLoading: false,
        });
      });
      // 执行任务
      return;
    }

    // 前进到下一步
    currentStep.value += 1;
  },
  onOpened: () => {
    // 初始化时重置步骤
    currentStep.value = 0;

    taskId.value = modalApi.getData<{ id: number }>().id;

    // loading
    modalApi.setState({
      loading: true,
      confirmDisabled: false,
    });
    getTaskArgsApi(taskId.value)
      .then((response: TaskArgsResponse) => {
        // 遍历 response.form,构建新的 schema
        const newSchema: VbenFormSchema[] = [
          {
            component: 'Input',
            fieldName: 'task_id',
            componentProps: {
              disabled: true,
              defaultValue: taskId.value,
            },
            label: '任务ID',
          },
        ];

        // 使用 Object.entries 遍历
        Object.entries(response.form).forEach(([key, value]) => {
          newSchema.push({
            component: 'Select',
            componentProps: {
              allowClear: true,
              filterOption: true,
              options: value.options.map((option) => {
                return {
                  label: option,
                  value: option,
                };
              }),
              placeholder: '请选择',
              showSearch: true,
              class: 'w-full',
              defaultValue: value.default,
            },
            fieldName: key,
            label: key,
            defaultValue: value.default,
          });
        });

        formApi.setState({
          schema: newSchema,
        });
      })
      .catch((error) => {
        formApi.setState({
          schema: [
            {
              component: 'Input',
              fieldName: 'task_id',
              componentProps: {
                disabled: true,
                defaultValue: taskId.value,
              },
              label: '任务ID',
              defaultValue: taskId.value,
            },
          ],
        });
        modalApi.setState({
          confirmDisabled: true,
        });
        console.error('Error fetching task args:', error);
      })
      .finally(() => {
        modalApi.setState({
          loading: false,
        });
      });
  },
  title: '触发任务执行',
});

watchEffect(() => {
  // 每次 currentStep 变化时更新按钮状态
  switch (currentStep.value) {
    case 0: {
      // 第一步:填写表单
      modalApi.setState({
        confirmText: '下一步',
        confirmDisabled: false,
        cancelText: '取消',
      });
      break;
    }
    case 1: {
      // 第二步:预览代码
      modalApi.setState({
        confirmText: '执行',
        confirmDisabled: false,
        cancelText: '上一步',
      });
      break;
    }
    case 2: {
      // 第三步:执行中
      modalApi.setState({
        confirmText: '执行中',
        confirmDisabled: false,
        cancelText: '关闭',
        confirmLoading: true,
      });
      break;
    }
  }
});

async function onSubmit(values: Record<string, any>) {
  setTimeout(() => {
    emit('run', values);
    modalApi.close();
  }, 1000);
}
</script>

<template>
  <Modal>
    <a-steps :current="currentStep" size="small" style="margin-bottom: 16px">
      <a-step title="填写表单" />
      <a-step title="预览代码" />
      <a-step title="执行中" />
    </a-steps>
    <div v-if="currentStep === 0">
      <Form />
    </div>

    <div v-else-if="currentStep === 1">
      <div class="flex min-h-0 flex-1 flex-col">
        <CodeEditor v-model="code" language="log" height="100%" />
      </div>
    </div>

    <div v-else-if="currentStep === 2">
      <a-result title="任务已启动" />
    </div>
  </Modal>
</template>

System Info

node: v23.11.0

Chrome: 136.0.7103.93

Relevant log output

Validations

@dingdayu
Copy link
Contributor Author

根据 #5070 得知 需要 setValues 或者 formApi.resetForm(); 尝试 formApi.resetForm(); 没有效果,不行,只能 setValues 了

@dingdayu
Copy link
Contributor Author

没办法,只能先如此了:

const fields: Record<string, any> = { task_id: taskId.value };
// 遍历 response.form,构建新的 schema
const newSchema: VbenFormSchema[] = [
  {
    component: 'Input',
    fieldName: 'task_id',
    componentProps: {
      disabled: true,
    },
    label: '任务ID',
    rules: 'required',
    defaultValue: taskId.value,
  },
];

// 使用 Object.entries 遍历
Object.entries(response.form).forEach(([key, value]) => {
  fields[key] = value.default;
  newSchema.push({
    component: 'Select',
    componentProps: {
      allowClear: true,
      filterOption: true,
      options: value.options.map((option) => {
        return {
          label: option,
          value: option,
        };
      }),
      placeholder: '请选择',
      showSearch: true,
      class: 'w-full',
    },
    fieldName: key,
    label: key,
    defaultValue: value.default,
    rules: 'required',
  });
});

formApi.setState({
  schema: newSchema,
});
formApi.setValues(fields);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant