In einer aktuellen Web-App hatten wir viele Formulare mit der gleichen Einreichungsstruktur:
isSubmitting
VariablenYup
)isSubmitting
设置回 false + 设置并在输入字段上显示 validationErrors
wieder auf „false“ setzen + validationErrors
festlegen und im Eingabefeld anzeigenIch habe versucht, einige Vorgänge mit der Kompositions-API in Vue 3 durchzuführen.
Login.vue
<template> <div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8"> <div class="sm:mx-auto sm:w-full sm:max-w-md"> <h1 class="text-3xl text-center text-gray-900">{{ t('sign_in_account', 1) }}</h1> </div> <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> <div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10"> <form @submit.prevent="handleSubmit"> <fieldset :disabled="isSubmitting" class="space-y-6"> <MessageBox v-if="errors.general" :title="errors.general" :messages="errors.messages" /> <Input :label="t('email', 1)" type="text" id="email" v-model="user.email" :error="errors.email" /> <Password :label="t('password', 1)" type="password" id="password" v-model="user.password" :error="errors.password" /> <div class="text-sm text-right"> <router-link class="font-medium text-indigo-600 hover:text-indigo-500" :to="forgotPassword">{{ t('forgot_password', 1) }}</router-link> </div> <SubmitButton class="w-full" :label="t('sign_in', 1)" :submittingLabel="t('sign_in_loader', 1)" :isSubmitting="isSubmitting" /> </fieldset> </form> </div> </div> </div> </template> <script> import { ref } from 'vue'; import { useStore } from 'vuex'; import { useI18n } from 'vue-i18n'; import useForm from '@/use/useForm'; import { validateEmail, LoginValidationSchema } from '@/utils/validators'; export default { setup() { const store = useStore(); const { t } = useI18n({ useScope: 'global' }); const user = ref({ email: '', password: '', }); const { handleSubmit, isSubmitting, errors } = useForm(user, LoginValidationSchema, handleLogin); async function handleLogin(values) { try { return await store.dispatch('auth/login', values); } catch (error) { if (error.response) { console.log(error.reponse); if (error.response.status == 422) { errors.value = { general: `${t('unable_to_login', 1)}<br /> ${t('fix_and_retry', 1)}`, messages: Object.values(error.response.data.errors).flat(), }; } else if (error.response.data.message) { errors.value = { general: error.response.data.message, }; } else { errors.value = { general: `${t('unknown_error', 1)}<br /> ${t('please_try_agin', 1)}`, }; } } else if (error.request) { console.log(error.request); errors.value = { general: `${t('unknown_error', 1)}<br /> ${t('please_try_agin', 1)}`, }; } else { errors.value = { general: `${t('unknown_error', 1)}<br /> ${t('please_try_agin', 1)}`, }; } return; } } return { t, user, handleSubmit, isSubmitting, errors }; }, computed: { forgotPassword() { return validateEmail(this.user.email) ? { name: 'forgotPassword', query: { email: this.user.email } } : { name: 'forgotPassword' }; }, }, }; </script>
useForm.js
import { ref, watch } from 'vue'; export default function useForm(initialValues, validationSchema, callback) { let values = ref(initialValues); let isSubmitting = ref(false); let errors = ref({}); async function handleSubmit() { try { errors.value = {}; await validationSchema.validate(values.value, { abortEarly: false }); isSubmitting.value = true; } catch (err) { console.log('In the catch'); isSubmitting.value = false; err.inner.forEach((error) => { errors.value = { ...errors.value, [error.path]: error.message }; }); } } watch(isSubmitting, () => { if (Object.keys(errors.value).length === 0 && isSubmitting.value) { callback(values); isSubmitting.value = false; } else { isSubmitting.value = false; } }); return { handleSubmit, isSubmitting, errors }; }
Das funktioniert einigermaßen, aber mir fehlen zwei Dinge. In useForm
möchte ich warten, bis der Rückruf abgeschlossen ist (Erfolg oder Misserfolg), bevor ich useForm
中,我想等到回调完成(成功或失败)才能将 isSubmitting
设置回 false。承诺是做到这一点的好方法吗?还有更好的方法吗?其次,我想要一种可重用的方法来处理 Login.vue
wieder auf „false“ zurücksetze. Ist Engagement ein guter Weg, dies zu tun? Gibt es einen besseren Weg? Zweitens möchte ich eine wiederverwendbare Möglichkeit zur Behandlung von Fehlern in Login.vue
. Irgendwelche Vorschläge, wie mit diesem Problem umgegangen werden kann?
关于你的第一个问题 -
try..catch
语句有第三个名为finally
的语句,该语句始终在try
语句块完成后执行。
回答你的第二个问题 - 承诺是处理异步逻辑的好方法,包括你发送请求的 API 返回错误响应的情况,然后你可以决定如何处理这种情况下的用户体验。
我不太清楚以可重用的方式处理
Login.vue
中的错误是什么意思,但也许您可以简单地将一个空数组道具传递给名为formErrors
的useForm
并让您的useForm.js
发出一个update:modelValue
事件以获得双向绑定。