0

我创建了一个可组合的 vue 3 来验证不同类型的输入字段。但是,当有多个相同类型的字段时,我确实遇到了问题,好像其中一个有错误会显示在具有相同类型的所有输入下,例如在这个例子中,密码字段 a 我确实有 3 个.

知道如何解决吗?

可组合的验证器:

    import { ref } from 'vue'
    
    const errors = ref({ email: '', password: '' })
    
    const validEmail = (email) => {
      const regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
      return regex.test(email)
    }
    const types = {
      email: 'email',
      password: 'password',
    }
    
    const validate = (entry, type) => {
      if (types[type] === 'email') {
        if (!entry) {
          errors.value.email = 'Email required.'
        } else if (!validEmail(entry)) {
          errors.value.email = 'Valid email required.'
        } else errors.value.email = ''
      }
      if (types[type] === 'password') {
        if (!entry) {
          errors.value.password = 'Password required.'
        } else if (entry.length < 8) {
          errors.value.password = 'Password should be minimum 8 characters.'
        } else errors.value.password = ''
      }
    }
    
    const useValidator = () => ({ validate, errors })
    
    export default useValidator

我使用它的组件:

<template>
  <div
    id="account-details"
  >
    <div class="page px-8 relative">
      <title-with-button title="pages.settings.profile" />
      <div class="flex flex-col items-center my-12">
        <div class="w-full md:w-80">
          <div class="flex flex-col">
            <label>Email</label>
            <input
              v-model="email"
              type="text"
              placeholder="example@we.care"
              class="px-2 h-12 my-2 rounded-md"
              @input="validate(email, 'email');"
              @keyup.enter="handleSubmit()"
            >
            <div
              class="text-red-500 text-sm leading-3 h-3"
            >
              {{ errors.email }}
            </div>
          </div>
          <div class="flex flex-col">
            <label>{{ $t('labels.current_password') }}</label>
            <input
              v-model="currentPassword"
              type="password"
              placeholder="Min 8 characters"
              class="px-2 h-12 my-2 rounded-md"
              @input="validate(currentPassword, 'password')"
              @keyup.enter="handleSubmit()"
            >
            <div
              class="text-red-500 text-sm leading-3 h-3"
            >
              {{ errors.password }}
            </div>
          </div>
          <div class="flex flex-col">
            <label>{{ $t('labels.new_password') }}</label>
            <input
              v-model="newPassword"
              type="password"
              placeholder="Min 8 characters"
              class="px-2 h-12 my-2 rounded-md"
              @input="validate(newPassword, 'password')"
              @keyup.enter="handleSubmit()"
            >
            <div
              class="text-red-500 text-sm leading-3 h-3"
            >
              {{ errors.password }}
            </div>
          </div>
          <div class="flex flex-col">
            <label>{{ $t('labels.current_password_retype') }}</label>
            <input
              v-model="newPasswordCopy"
              type="password"
              placeholder="Min 8 characters"
              class="px-2 h-12 my-2 rounded-md"
              @input="validate(newPasswordCopy, 'password')"
              @keyup.enter="handleSubmit()"
            >
            <div
              class="text-red-500 text-sm leading-3 h-3"
            >
              {{ errors.password }}
            </div>
          </div>
        </div>
        <button
          class="cursor-pointer bg-gray-500 text-white text-base border-none no-underline
        px-5 py-3 mt-4 rounded-md"
          @click="handleSubmit()"
        >
          {{ $t('button.save') }}
        </button>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, computed } from 'vue'
import TitleWithButton from '../components/settings/TitleWithButton.vue'
import useValidator from '../composables/useValidator'
import useUpdateAccount from '../composables/useUpdateAccount'

export default {
  name: 'AccountDetails',
  components: {
    TitleWithButton,
  },
  setup() {
    const email = ref('')
    const currentPassword = ref('')
    const newPassword = ref('')
    const newPasswordCopy = ref('')
    const currentUser = JSON.parse(localStorage.getItem('user')).user
    email.value = currentUser.email
    const { validate, errors } = useValidator()
    const { updateAccount, error } = useUpdateAccount()
    const inValid = computed(() => {
      if ((errors.value.email || errors.value.password)
      || (newPassword.value !== newPasswordCopy.value)) {
        return true
      } return false
    })
    const handleSubmit = async () => {
      validate(email.value, 'email')
      validate(currentPassword.value, 'password')
      validate(newPassword.value, 'password')
      validate(newPasswordCopy.value, 'password')
      if (!inValid.value) {
        await updateAccount(email.value, currentPassword.value, newPassword.value)
      }
    }
    return {
      email, currentPassword, newPassword, newPasswordCopy, errors, handleSubmit, error, validate,
    }
  },
}
</script>
4

0 回答 0