VueJS 3.0에서 vuelidate로 양식 오류 처리

소개



안녕 모두들!

오늘의 기사에서는 vuelidate 을 사용하여 VueJS 3.0에서 양식 오류를 처리하는 깔끔하고 간단한 접근 방식을 보여드리겠습니다. 또한 NuxtJS 3.0과 TypeScript는 최신 프런트엔드 환경에서 가장 선호하는 도구이기 때문에 사용할 것입니다.

동기 부여



Vuelidate는 유효성 검사 메시지를 표시하는 방법에 대한 몇 가지 예를 제공합니다.

<!-- Display all errors -->
<p
  v-for="error of v$.$errors"
  :key="error.$uid"
>
<strong> {{ error.$message }} </strong>
</p>

또는

<!-- Display all errors of an individual property -->
<p
  v-for="error of v$.name.$errors"
  :key="error.$uid"
>
<strong> {{ error.$message }} </strong>
</p>

마크업이 매우 단순하다면 괜찮지만 입력이 많거나 Vuetify's 텍스트 영역 구성 요소와 같은 오류 메시지 소품과 함께 제공되는 UI 프레임워크를 사용하는 경우에는 어떻게 됩니까? 여전히 관심이 있다면 탑승을 환영하고 양식 유효성 검사를 다시 훌륭하게 만들 수 있습니다!

코딩



다음과 같이 Vuetify 3.0을 사용하여 간단한 양식을 만들어 보겠습니다.

<!-- @/pages/index.vue -->

<v-form @submit.prevent="validate()" class="form">
  <v-container>
    <v-row>
      <v-col cols="12">
        <v-text-field v-model="v$.firstName.$model" label="First Name" variant="solo"/>
      </v-col>

      <v-col cols="12">
        <v-text-field v-model="v$.lastName.$model" solor label="Last Name" variant="solo" />
      </v-col>

      <v-col cols="12">
        <v-text-field v-model="v$.email.$model" label="E-mail" variant="solo"/>
      </v-col>

      <v-col cols="12">
        <v-textarea v-model="v$.message.$model" label="Message" variant="solo"/>
      </v-col>

      <v-col cols="12">
        <v-text-field v-model="v$.password.$model" label="Password" variant="solo"/>
      </v-col>

      <v-col cols="12">
        <v-btn type="submit" color="success">Submit</v-btn>
      </v-col>
    </v-row>
  </v-container>
</v-form>

및 aref는 다음과 같은 입력 값을 보유합니다.

// @/pages/index.vue

<script setup lang="ts">
import type { IForm } from '@/interface/form.interface'

const form = ref<IForm>({
  firstName: '',
  lastName: '',
  email: '',
  message: '',
  password: ''
})
</script>

TypeScript에 익숙하지 않은 경우 IForm는 유형 검사에 도움이 되는 interface입니다. JavaScript를 사용하는 경우 <IForm>를 제거하면 됩니다. TypeScript를 사용하는 사람들을 위해 내 인터페이스는 다음과 같습니다.

// @/interface/form.interface.ts

export interface IForm {
    firstName: string;
    lastName: string;
    email: string;
    message: string;
    password: string;
}

이제 사용자 지정 오류 메시지와 함께 vuelidate의 유효성 검사기를 가져오고 다음과 같은 유효성 검사 규칙을 사용하여 개체를 정의해 보겠습니다.

// @/pages/index.vue

<script setup lang="ts">
import { required, helpers, email } from '@vuelidate/validators'

import { FORM_INVALID_EMAIL, FORM_REQUIRED_FIELD } from '@/helpers/messages'

const rules = {
  firstName: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  lastName: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  email: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required),
    email: helpers.withMessage(FORM_INVALID_EMAIL, email)
  },
  message: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  password: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  }
}
</script>



// @/helpers/messages.ts
const FORM_REQUIRED_FIELD = 'This field is required'
const FORM_INVALID_EMAIL = 'This email is invalid'

export {
  FORM_REQUIRED_FIELD,
  FORM_INVALID_EMAIL
}


그리고 마지막으로 vuelidate 자체를 가져오고 규칙과 형식을 바인딩합니다.

// @/pages/index.vue
<script setup lang="ts">
import { useVuelidate } from '@vuelidate/core'

const v$ = useVuelidate(rules, form)
</script>

요약하면 코드는 다음과 같습니다.

<!-- @/pages/index.vue -->

<template>
  <main class="main">
    <v-form @submit.prevent="validate()" class="form">
      <v-container>
        <v-row>
          <v-col cols="12">
            <v-text-field v-model="v$.firstName.$model" label="First Name" variant="solo"/>
          </v-col>

          <v-col cols="12">
            <v-text-field v-model="v$.lastName.$model" solor label="Last Name" variant="solo" />
          </v-col>

          <v-col cols="12">
            <v-text-field v-model="v$.email.$model" label="E-mail" variant="solo"/>
          </v-col>

          <v-col cols="12">
            <v-textarea v-model="v$.message.$model" label="Message" variant="solo"/>
          </v-col>

          <v-col cols="12">
            <v-text-field v-model="v$.password.$model" label="Password" variant="solo"/>
          </v-col>

          <v-col cols="12">
            <v-btn type="submit" color="success">Submit</v-btn>
          </v-col>
        </v-row>
      </v-container>
    </v-form>
    </main>
</template>

<script setup lang="ts">
import { useVuelidate } from '@vuelidate/core'

import { required, helpers, email } from '@vuelidate/validators'

import { FORM_INVALID_EMAIL, FORM_REQUIRED_FIELD } from '@/helpers/messages'

import type { IForm } from '@/interface/form.interface'

const form = ref<IForm>({
  firstName: '',
  lastName: '',
  email: '',
  message: '',
  password: ''
})

const rules = {
  firstName: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  lastName: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  email: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required),
    email: helpers.withMessage(FORM_INVALID_EMAIL, email)
  },
  message: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  },
  password: {
    required: helpers.withMessage(FORM_REQUIRED_FIELD, required)
  }
}

const v$ = useVuelidate(rules, form)

const validate = async () => {
    const result = await v$.value.$validate() 

    if (!result) {
        return
    }

    alert('Success! Sending to API')
}
</script>

양식을 채우지 않고 제출 버튼을 누르고 Vue DevTools를 열면 v$ 객체에서 각 해당 입력에 대한 오류가 포함된 $errors 속성을 찾을 수 있습니다.




$errors 배열의 각 개체에는 $message에서 정의한 사용자 정의 오류 메시지가 있는 @/helpers/messages.ts 속성이 있습니다. 여기서 해야 할 일은 $errors 배열을 반복하고 오류 맵을 만드는 것입니다.

컴포저블useValidationErrors.ts을 생성해 보겠습니다. 이 함수는 vuelidate에서 오류 배열을 가져오고 reduce 메서드를 사용하여 키-값 쌍의 객체를 생성합니다. 여기서 우리key는 검증된 속성의 이름이고 우리value는 사용자 정의 메시지.

// @/composables/useValidationErrors.ts

import type { ErrorObject } from '@vuelidate/core'

export const useValidationErrors = <T extends Record<keyof T, string>>(errors: ErrorObject[]): Record<keyof T, string> => {
  return errors.reduce((acc, value) => {
    return { ...acc, [value.$property]: value.$message }
  }, {} as Record<keyof T, string>)
}

이 컴포저블의 자바스크립트 버전은 다음과 같습니다.

// @/composables/useValidationErrors.js

export const useValidationErrors = (errors) => {
  return errors.reduce((acc, value) => {
    return { ...acc, [value.$property]: value.$message }
  }, {})
}

이제 컴포저블을 계산된 속성errors으로 래핑해 보겠습니다.

// @/pages/index.vue

<script setup lang="ts">
const errors = computed(() => useValidationErrors<IForm>(v$.value.$errors))
</script>

  • 내 컴포저블을 어디에도 가져오지 않았습니다. Nuxt 3.0에서 자동으로 가져옵니다.
  • JavaScript 개발자: <IForm>에서 useValidationErrors를 제거하십시오.

  • 이제 Vue DevTools에서 제출 버튼을 다시 클릭하면 errors 계산 속성이 채워지는 것을 볼 수 있습니다.



    이메일을 입력하기 시작하면 오류가 변경됩니다.



    마지막으로 v-text-fielderror 소품으로 error-messages 구성 요소의 마크업을 업데이트해 보겠습니다.

    <v-form @submit.prevent="validate()" class="form">
          <v-container>
            <v-row>
              <v-col cols="12">
                <v-text-field
                  v-model="v$.firstName.$model"
                  label="First Name"
                  variant="solo"
                  :error="v$.firstName.$error"
                  :error-messages="errors.firstName"
                />
              </v-col>
    
              <v-col cols="12">
                <v-text-field
                  v-model="v$.lastName.$model"
                  label="Last Name"
                  variant="solo"
                  :error="v$.lastName.$error"
                  :error-messages="errors.lastName"
                />
              </v-col>
    
              <v-col cols="12">
                <v-text-field
                  v-model="v$.email.$model"
                  label="E-mail"
                  variant="solo"
                  :error="v$.email.$error"
                  :error-messages="errors.email"
                />
              </v-col>
    
              <v-col cols="12">
                <v-textarea
                  v-model="v$.message.$model"
                  label="Message"
                  variant="solo"
                  :error="v$.message.$error"
                  :error-messages="errors.message"
                />
              </v-col>
    
              <v-col cols="12">
                <v-text-field
                  v-model="v$.password.$model"
                  label="Password"
                  variant="solo"
                  :error="v$.password.$error"
                  :error-messages="errors.password"
                />
              </v-col>
    
              <v-col cols="12">
                <v-btn
                  type="submit"
                  color="success"
                >
                  Submit
                </v-btn>
              </v-col>
            </v-row>
          </v-container>
        </v-form>
    

    그리고 짜잔!

    최종 결과의 GIF는 here


    앤디누아르 / vuelidate-handling-errors






    Nuxt 3 최소 스타터


    자세한 내용은 nuxt 3 documentation을 참조하십시오.

    설정


    종속 항목을 설치해야 합니다.
    # yarn
    yarn install
    
    # npm
    npm install
    
    # pnpm
    pnpm install --shamefully-hoist

    개발 서버


    http://localhost:3000에서 개발 서버 시작
    npm run dev

    생산


    프로덕션용 애플리케이션 빌드:
    npm run build

    프로덕션 빌드를 로컬에서 미리 보기:
    npm run preview

    자세한 내용은 deployment documentation을 확인하십시오.


    View on GitHub


    학점



    이 기사를 쓰도록 영감을 준 그의 동료들에게 감사해야 합니다!

    좋은 웹페이지 즐겨찾기