Front-End프로그래밍

[Vue3, TypeScript] vee-validate + pinia 연동 방법 예제 총정리

vee-validatepinia를 연동하면 폼 상태를 전역 상태 관리(store)와 연결해서 아래와 같은 유용한 패턴을 만들 수 있습니다


주요 목적

  • pinia로 폼 데이터를 저장하거나 복구
  • 유효성 통과한 값만 store에 저장
  • 여러 페이지(step form 등)에서 공유

예제 시나리오

  • 사용자 가입 폼
  • pinia store에 저장된 값으로 기본값 설정
  • 제출 시 유효성 통과한 값만 store에 저장

1. pinia store 정의

// stores/userForm.ts
import { defineStore } from 'pinia';

export const useUserFormStore = defineStore('userForm', {
  state: () => ({
    formData: {
      name: '',
      email: '',
    }
  }),
  actions: {
    updateFormData(payload: Partial<typeof this.formData>) {
      this.formData = { ...this.formData, ...payload };
    },
    resetFormData() {
      this.formData = { name: '', email: '' };
    }
  }
});

2. vee-validate 폼 구성 + store 초기값 연동

<template>
  <Form @submit="onSubmit">
    <div>
      <label>이름</label>
      <Field name="name" rules="required" />
      <ErrorMessage name="name" />
    </div>
    <div>
      <label>이메일</label>
      <Field name="email" rules="required|email" />
      <ErrorMessage name="email" />
    </div>
    <button type="submit">저장</button>
  </Form>
</template>

<script setup lang="ts">
import { useForm, Field, Form, ErrorMessage } from 'vee-validate';
import { useUserFormStore } from '@/stores/userForm';
import { storeToRefs } from 'pinia';
import * as yup from 'yup';

const formStore = useUserFormStore();
const { formData } = storeToRefs(formStore);

const schema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required()
});

const { handleSubmit } = useForm({
  validationSchema: schema,
  initialValues: formData.value // pinia 초기값 사용
});

const onSubmit = handleSubmit((values) => {
  formStore.updateFormData(values); // 유효성 통과된 값 저장
  console.log('저장됨:', values);
});
</script>

3. 다음 페이지 또는 컴포넌트에서 불러오기

const formStore = useUserFormStore();
console.log(formStore.formData.name); // 이전 페이지에서 저장된 값

추가 패턴: 실시간으로 pinia에 반영

만약 유효성 여부와 관계없이 입력값이 바뀔 때마다 store에 반영하고 싶다면, watch()를 사용합니다.

import { watch } from 'vue';
import { useForm } from 'vee-validate';
import { useUserFormStore } from '@/stores/userForm';

const store = useUserFormStore();

const { values } = useForm({ initialValues: store.formData });

watch(values, (newVal) => {
  store.updateFormData(newVal);
}, { deep: true });

✅ 요약

목적구현 방식
초기값을 pinia에서 불러오기initialValues: store.formData
유효성 통과된 값 저장onSubmit(values => store.updateFormData(values))
실시간 저장watch(values, val => store.updateFormData(val))
리셋store.resetFormData() + resetForm()

[관련자료]

[Vue3, TypeScript] vee-validate에서 입력 필드 마스킹/포맷팅방법

JavaScript/TypeScript 기본 문법: Spread, Rest, Map 사용법 예제 총정리

[Vue3, TypeScript] vee-validate와 yup에 대한 예제 총정리

error: Content is protected !!