Dans une application web récente, nous avions beaucoup de formulaires avec la même structure de soumission :
isSubmitting
variablesYup
)isSubmitting
设置回 false + 设置并在输入字段上显示 validationErrors
sur false + set et affichez validationErrors
dans le champ de saisieJ'ai essayé de faire quelques opérations en utilisant l'API de composition dans la vue 3.
Connexion.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 }; }
Cela fonctionne dans une certaine mesure, mais il me manque deux choses. Dans useForm
, je souhaite attendre la fin du rappel (succès ou échec) avant de redéfinir useForm
中,我想等到回调完成(成功或失败)才能将 isSubmitting
设置回 false。承诺是做到这一点的好方法吗?还有更好的方法吗?其次,我想要一种可重用的方法来处理 Login.vue
sur false. L’engagement est-il un bon moyen d’y parvenir ? Existe-t-il une meilleure façon ? Deuxièmement, je veux un moyen réutilisable de gérer les erreurs dans Login.vue
. Des suggestions sur la façon de résoudre ce problème ?
Concernant votre première question -
try..catch
语句有第三个名为finally
的语句,该语句始终在try
le bloc d'instructions est exécuté une fois terminé.
Pour répondre à votre deuxième question : les promesses sont un excellent moyen de gérer la logique asynchrone, y compris les situations dans lesquelles l'API à laquelle vous envoyez la requête renvoie une réponse d'erreur, et vous pouvez ensuite décider comment gérer l'expérience utilisateur dans ce cas.
Je ne suis pas sûr de ce que vous entendez par gérer les erreurs dans
useForm nommé 🎜formErrors code> et demandez à votre 🎜useForm.js d'émettre un événement 🎜update:modelValue pour obtenir une liaison bidirectionnelle. 🎜Login.vue
中的错误是什么意思,但也许您可以简单地将一个空数组道具传递给名为formErrors
的useForm
并让您的useForm.js
发出一个update:modelValue
Login.vue de manière réutilisable, mais peut-être pourriez-vous simplement transmettre un accessoire de tableau vide au