使用Vue3组合API验证同一表单中的多个输入字段

7vhp5slm  于 2023-06-24  发布在  Vue.js
关注(0)|答案(1)|浏览(208)

在我的应用程序中,我创建了自定义验证和验证器来验证不同的表单字段。提交按钮将被禁用,直到所有输入不为空。
我创建了这样的验证器添加规则。
//validator.js

export default function validators() {
      const isEmpty = (fieldName, fieldValue) => (!fieldValue ? `This ${fieldName} can not be empty` : '');
      const minLength = (fieldName, fieldValue, min) => (fieldValue.length < min ? `The ${fieldName} must be atleast ${min} characters long` : '');
      return {
        isEmpty,
        minLength,
      };
    }

使用此验证器进入输入和文本区域,电子邮件等验证逻辑,如下所示。//formValidation

import { reactive } from 'vue';
import Validators from './validators';

const errors = reactive({});
const {
  minLength, isEmpty
} = Validators();
export default function formValidation() {
  const validateInputField = (fieldName, fieldValue) => {
    errors[fieldName] = !fieldValue
      ? isEmpty(fieldName, fieldValue) : minLength(fieldName, fieldValue, 2);
  };
  return {
    errors,
    validateInputField,
  };
}

现在,我已经创建了自定义按钮验证状态如下。它是计算的财产。

按钮状态

import { computed } from 'vue';

export default function submitButtonState(field, errors) {
  const isButtonDisabled = computed(() => {
    let disabled = true;
    // eslint-disable-next-line no-restricted-syntax
    for (const prop in field) {
      if (Object.hasOwn(field, prop)) {
        if (!field[prop] || errors[prop]) {
          disabled = true;
          break;
        }
        disabled = false;
      }
    }
    return disabled;
  });
  return {
    isButtonDisabled,
  };
}

现在,在我的组件中,我将所有输入变量存储到pinia store中。输入后,存储这些变量工作正常,但按钮状态始终禁用。它根本没有更新。

组件代码如下:

<template>
 <div> 
  <span>Forms Description</span>
  <p>
  <my-textarea
        :message-type="errors.address ? 'negative' : ''"
        :validation-message ="errors.address"
        max-length="100"
      >
        <textarea
          v-model="formResponses.txtArea1"
          @blur="validate1stInput"
          @keypress="validate1stInput"
          slot="textarea"
          maxlength="100"
        ></textarea>
        <label slot="label" for="textarea"
          >Address</label
        >
   </my-textarea>
  </p>
  <p>
  <my-textarea
        :message-type="errors.comments? 'negative' : ''"
        :validation-message ="errors.comments"
        max-length="100"
      >
        <textarea
          v-model="formResponses.txtArea2"
          @blur="validate1stInput2"
          @keypress="validate1stInput2"
          slot="textarea"
          maxlength="100"
        ></textarea>
        <label slot="label" for="textarea"
          >Comments</label
        >
   </my-textarea>
  </p>
  <p><button class="myButton" @click.prevent="submit" :disabled="isButtonDisabled"</p>
</div>
</template>

<script setup>
import UserStore from '@/store/userStore';  // pinia store variables are using to store input data
import FormValidation from '@/utilities/useFormValidation';
import SubmitButtonState from '@/utilities/SubmitButtonState';
import { ref, reactive, watch } from 'vue';
import { storeToRefs } from 'pinia';

const { form1 } = storeToRefs(UserStore());
const formResponses = reactive({ ...form1.value });

const { validateInputField, errors } = FormValidation();

const { isButtonDisabled } = SubmitButtonState(formResponses, errors); // It is giving value true always after inputting correct value in field

const validate1stInput = () => {
  validateInputField('address', formResponses.txtArea1);
};
const validate1stInput2 = () => {
  validateInputField('comments', formResponses.txtArea2);
};

watch(() => errors, { immediate: true });

</script>

按钮状态未更新,我不确定它是否未获得更新的错误状态。如何解决多个输入的问题?

我已经做了一个可行的codesandbox,但在我的情况下,在应用程序'formResponse'变量返回空,所以按钮状态总是被禁用(true)。

Codesandbox链接-https://codesandbox.io/s/priceless-diffie-ymgtur?file=/src/utilities/FormValidation.js

ymdaylpp

ymdaylpp1#

你需要通过一个computed属性(这里是typescript)来观察状态的变化:

const isButtonDisabled: ComputedRef<boolean> = computed((): boolean => SubmitButtonState(formResponses, errors) );

相关问题