Vue.js form 작성

강정우·2023년 4월 4일
0

vue.js

목록 보기
22/72
post-thumbnail
post-custom-banner

v-model

  • 앞서 작성했던 포스팅을 보충하고자 추가적으로 작성함.

  • v-model을 사용하면 양방향 바인딩이 가능해서 양식 리셋에도 도움이 된다.
    또한 양방향 바인딩을 통해 사용자가 입력한 데이터만 수신하는 게 아니라 form에 있는 데이터를 덮어쓸 수도 있다.
    게다가 input 요소에 저장된 값도 바꿀 수 있다.

  <form @submit.prevent="submitForm">
      <input id="user-name" name="user-name" type="text" v-model.trim="userName" @blur="validateInput" />
      ...
  • 위 코드와같이 v-model에 .trim 디렉션을 붙일 수 있다.

input type

  • 만약 위 코드처럼 작성한다면 type 상관없이 항상 String일 것이다. 하지만 Vue가 자동으로 입력한 데이터를 페칭하고 문자열 => 숫자로 변환해준다.

  • 이때 number의 초기값은 0도 빈문자열''도 아닌 null로 초기화를 해주어야한다.

  • 만약 ref를 쓴다면 자동으로 페칭이 안 이루어지는데 이 또한 modifier로 자동으로 바꿔줄 수 있다.

<input id="age" name="age" type="number" v-model.number="userAge" ref="ageInput" />

즉, 만약 당신이 v-model이 아닌 ref를 사용한다면 type값이 number이다 하더라도 이는 항상 문자열로 받는다.

.lazy

  • 모든 키 입력에 적용하거나 일부 입력에만 적용하면 낮은 빈도로 업데이트하는 기능

.trim

  • 만약 마크업단에서 v-model.trim을 갈겼다면 이후에 사용되는 v-model 값에대해서는 추가적인 .trim()를 할 필요가 없다.

<select>

  • v-model은 <select>에서도 똑같이 동작한다.

<input type="checkbox">

  • 마찬가지로 v-model을 적용할 수 있다. 하지만 이때 초기값 설정이 중요하다.
    만약 초기값 설정을 null로 해버리면
<template>
	<input id="interest-news" name="interest" type="checkbox" value="news" v-model="interest" />
    <input id="interest-news" name="interest" type="checkbox" value="tutorials" v-model="interest" />
</template>

<script>
	data(){
    	return {
        	interest:null (X)
            interest:[]   (O)
        }
    }
</script>
  • 다음과 같다고 할 때 하나를 선택하면 v-model이 같은 값인게 한큐에 선택되어버린다. 그래서 초기화할 때 초기값을 array로 해주는 것이 좋다.
  • 단, 단일 v-model이라면 그냥 true 혹은 false 로 초기화를 해주면 된다. 체크박스는 0, 1이기 때문.

<input type="radio">

<div>
	<input id="how-video" name="how" type="radio" value="video" v-model="how" />
	<label for="how-video">Video Courses</label>
</div>
<div>
	<input id="how-blogs" name="how" type="radio" value="blogs" v-model="how" />
	<label for="how-blogs">Blogs</label>
</div>
<div>
	<input id="how-other" name="how" type="radio" value="other" v-model="how" />
	<label for="how-other">Other</label>
</div>

... 

data () {
	return {
    	how:null
    }
}

@Blur event

  • react에서 배웠던 것 과 같이 focus, blur 이벤트이다.
<input id="user-name" name="user-name" type="text" v-model.trim="userName" @blur="validateInput" />
  • 이렇게 사용자가 input에 blur 이벤트가 일어났을 때 뭔가 로직을 돌릴 수 있다.
    즉, @blur에 이벤트를 넣고 돌리고 그 결과값을 data 속성값에 넣어주고 해당 속성값으로 마크업 단에 v-if를 줘서 사용자에게 알람이 가도록 로직을 구현하면 된다.

<button>

  • 만약 당신이 button을 만드는데 form 태그 안에 있어도 전송하고싶지 않다면 type을 button으로 주면 그만이다.

modelValue

  • 작업을 하다보면 부-자 컴포넌트간 데이터를 변경 뿐만 아니라 추적하거나 자식단에서 props을 직접 수정하는 경우가 생긴다. 이를 해결하고자 나온 개념이 modelValue이다.
<input v-model="searchText" />

혹은

<CustomInput v-model="searchText" />
  • 우리가 위 같이 작성하면 컴파일러가
<input
  :value="searchText"
  @input="searchText = $event.target.value"
/>

혹은

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>
  • 변환시킨다. 이를 부모 컴포넌트는 컴파일링 해주지만 자식 컴포넌트에서는 이를 추적, 구현해주어야한다.
<!-- CustomInput.vue -->

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
  <li :class="{active: modelValue === 'great'}">
      <button type="button" @click="activate('great')">Great</button>
  </li>
</template>

<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue'],
  methods :{
  	activate(option) {
      this.$emit('update:modelValue', option);
    },
  }
}
</script>
  • 자식 컴포넌트에서는 위와같이 사용하면 되고 emits의 이벤트 이름은 마음대로 설정해도 되지만 전통적으로 update:modelValue라고 쓰인다.

+조건식

  • 만약 당신이 3항 연산자를 사용하여 ? 조건에 따라 class를 부여하고 싶다면
invalid ? userNameValidity === 'invalid' : ''
  • 이렇게 써도 되지만
invalid: userNameValidity === 'invalid'
  • 이렇게 쓰면 더 좋다.
profile
智(지)! 德(덕)! 體(체)!
post-custom-banner

0개의 댓글