6

我正在尝试按照官方 Vee-Validate 指南构建一个多步骤表单向导,它提供的示例可在此处找到。虽然这很有帮助,但我想将 Vuex 合并到其中,并且我使用自定义组件而不是 Vee-Validate 的默认组件<Form/><ErrorMessage/>组件。自定义组件内部不使用 Vee-Validate 默认组件。

然而,这样做给我带来了一些问题。我目前的问题是我不知道如何让我的 Vuex 状态进入 Vee-Validate reactively

我的主要组件中的文本输入是这样使用的:

    <text-input
        label="Name"
        name="name"
        v-model="name"
    />
    ...
computed: {
  ...mapGetters({
      businessFields: 'business/businessFields',
  }),
  name: {
      get () {
          return this.businessFields.name;
      },
      set (value) {
          this.$store.commit('business/setName', value)
      }
  },
},

这一切都是根据Vuex 在此处提供的双向计算属性指南

现在我正在尝试将这些字段合并到前面链接的 Vee-Validate 多表单向导中。我基本上已经将其更改为在重置并从 Vuex 来回而不是本地值时获取值。像这样:

<!-- FormWizard.vue (from the Vee-Validate example adapted to use Vuex) -->
<template>
  <form @submit="onSubmit">
    <slot />

    <div>
      <button v-if="hasPrevious" type="button" @click="goToPrev">
        Previous
      </button>
      <button type="submit">{{ isLastStep ? "Submit" : "Next" }}</button>
    </div>
  </form>
</template>

<script>
import { useForm } from "vee-validate";
import { useStore } from 'vuex';
import { ref, computed, provide } from "vue";

export default {
  name: "FormWizard",
  emits: ["next", "submit"],
  props: {
    validationSchema: {
      type: null,
      required: true,
    },
    formDataGetter: {
      type: String,
      required: true,
    }
  },
  setup(props, { emit }) {
    const store = useStore();
    const currentStepIdx = ref(0);

    // Injects the starting step, child <form-steps> will use this to generate their ids
    const stepCounter = ref(0);
    provide("STEP_COUNTER", stepCounter);
    // Inject the live ref of the current index to child components
    // will be used to toggle each form-step visibility
    provide("CURRENT_STEP_INDEX", currentStepIdx);

    // if this is the last step
    const isLastStep = computed(() => {
      return currentStepIdx.value === stepCounter.value - 1;
    });

    // If the `previous` button should appear
    const hasPrevious = computed(() => {
      return currentStepIdx.value > 0;
    });

    const { resetForm, handleSubmit } = useForm({
      validationSchema: props.validationSchema,
    });

    // We are using the "submit" handler to progress to next steps
    // and to submit the form if its the last step
    // parent can opt to listen to either events if interested
    const onSubmit = handleSubmit(() => {
      // Sets initial values for the values already filled
      // effectively fills the inputs when clicking on "previous"
      resetForm({
        values: {
          ...store.getters[props.formDataGetter]
        },
      });
      if (!isLastStep.value) {
        currentStepIdx.value++;
        emit("next", store.getters[props.formDataGetter]);

        return;
      }

      emit("submit");
    });

    function goToPrev() {
      if (currentStepIdx.value === 0) {
        return;
      }

      currentStepIdx.value--;
    }

    return {
      onSubmit,
      hasPrevious,
      isLastStep,
      goToPrev,
    };
  },
};
</script>

FormStep.vue步骤完全相同。当我像这样使用 FormWizard 时:

  <form-wizard :validationSchema="validationSchema" @submit="onSubmit" formDataGetter="setup/setupFields">
    <form-step>
      <business-form></business-form>
    </form-step>
  </form-wizard>

在我的主要组件中有一个setup()像这样容纳 FormWizard 的组件:

  setup() {
    const store = useStore();
    // You don't have to validate each step
    // vee-validate will only validate the fields rendered from the schema
    // fields not rendered errors will be ignored, so it all just works!
    const validationSchema = yup.object().shape({
      name: yup.string().required(),
    });

    /**
     * Only Called when the last step is submitted
     */
    const onSubmit = (values) => {
      console.log(values);
      alert(store.getters['business/businessFields'].name);
    };

    return {
      validationSchema,
      onSubmit,
    };
  },

事情是现在我要进入下一页,我收到一个需要名称的验证错误。这是因为没有使用 Vee-Validate 的useField()功能来容纳我的字段。useField()返回一个计算属性,您必须将其链接为v-model您的输入。这里出现的问题是我在使用 时无法更改 Vuex 字段useField(),也无法更改useFieldwith Vuex 的计算属性,因为这不是 Vee-Validate 中的选项。

现在我的问题是:如何实现 Vee-validate 3 和 Vuex 4,以允许useForm()仅使用一个计算属性更新我的 Vuex 存储和 Vee-Validate 字段?

或者有不同的方法吗?

4

0 回答 0