치춘짱베리굿나이스
Vue 에서 Form input 관리하기 본문
Form 다루기
처음엔 그냥 무식하게 (?) ref 로 관리했는데
ref 들이 너무 많아지니까 이게 맞나 싶어서 찾아봤기도 하고 동료분께 조언을 얻었따.
전부 ref로 관리하기
<template>
<form @submit.prevent="handleSubmitAllRef">
<input type="text" v-model="name" />
<input type="number" v-model="age" />
<button type="submit">Submit</button>
</form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const name = ref('');
const age = ref(0);
function handleSubmitAllRef() {
console.log({ name: name.value, age: age.value });
}
</script>
그냥 모든 값을 ref
로 관리하는 방법이다
구현이 쉽고 따로 형변환을 해줄 필요도 없이 모든 데이터가 잘 들어간다
단 폼이 길고 복잡해질 경우 모든 범주에 대해 ref
를 추가해 주어야 한다는 사실이 매우 애매하다
FormData 활용하기
<template>
<form @submit.prevent="handleSubmitFormData">
<input type="text" name="name" />
<input type="number" name="age" />
<button type="submit">Submit</button>
</form>
</template>
<script setup lang="ts">
function handleSubmitFormData(e: Event) {
const formData = new FormData(e.target as HTMLFormElement);
console.log({ name: formData.get('name'), age: formData.get('age') });
}
</script>
JavaScript API인 FormData
를 사용해서 이벤트를 FormData
객체로 변환해주는 방법이다
reactive
, ref
등을 전혀 사용하지 않기 때문에 코드가 매우 짧아진다는 장점이 있다
단 FormData
내부 값들을 getter 로 가져와야 하기 때문에 데이터 후처리 과정이 조금 복잡하다
또한 getter 로 가져온 값이 File | string
타입이기 때문에 number
로 형변환이 조금 귀찮다
reactive 객체 활용하기
<template>
<form @submit.prevent="handleSubmitReactive">
<input type="text" v-model="obj.name" />
<input type="number" v-model="obj.age" />
</form>
</template>
<script setup lang="ts">
import {reactive} from 'vue';
interface ReactiveObj {
name: string;
age: number;
}
const obj = reactive<ReactiveObj>({ name: '', age: 0 });
function handleSubmitReactive() {
console.log(obj); // form data handling 로직
}
</script>
reactive
객체 (사실 ref
도 내부적으로 reactive
를 사용하므로 크게 상관없다) 를 활용해서 폼 데이터를 관리하는 방법이다
reactive
객체는 데이터의 변경을 깊이 관찰하므로 내부 속성들의 변화도 감지할 수 있다
따라서 input
등의 태그에 v-model
바인딩으로 reactive
객체의 내부 속성들을 걸어주면 폼 데이터를 속성별로 ref
를 하나하나 걸어줄 필요 없이 - 하나의 객체로 관리할 수 있다
참고 자료
'ClientSide > Vue' 카테고리의 다른 글
Vue를 먹자 3 - 반응형 API (0) | 2023.10.24 |
---|---|
Vue를 먹자 2 - template (0) | 2023.10.20 |
Vue를 먹자 1 (0) | 2023.10.20 |
Comments