我正在尝试按照官方 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()
,也无法更改useField
with Vuex 的计算属性,因为这不是 Vee-Validate 中的选项。
现在我的问题是:如何实现 Vee-validate 3 和 Vuex 4,以允许useForm()
仅使用一个计算属性更新我的 Vuex 存储和 Vee-Validate 字段?
或者有不同的方法吗?