[백견불여일타/Vue.js] 4장 - 입력 폼 데이터 가져오기

🍿 핵심 키워드

  • v-model
  • 데이터 입력
  • checkbox
  • radio
  • select

🌷 개요

지난 장에서는 v-bind를 이용해서 HTML 태그 속성 값을 Vue로 다루는 법을 배웠습니다. 이번에는 사용자가 입력한 데이터를 Vue로 가져오는 법에 대해 다룹니다.

[01] V-model

웹 페이지에서 사용자가 입력한 데이터(텍스트, 선택값 등등)를 Vue로 읽어오려면 v-model 디렉티브를 사용하면 됩니다. 이를 양방향 바인딩이라고도 부릅니다. Vue 관점에서 봤을 때 웹 페이지로부터 데이터를 읽어오기도 하고 반대로 웹 페이지에 데이터를 표현도 하기 때문입니다.

서식

<태그명 v-model="프로퍼티명"></태그명>

텍스트 : input

먼저 input 태그를 이용해서 간단한 텍스트 값을 Vue로 읽어보겠습니다.

입력한 문자열을 표시하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2>입력한 문자열을 표시하는 예제</h2>
		<div id="app">
			<input v-model="myName" placeholder="이름을 입력하세요">
			<p>{{myName}}</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myName:''
				}
			})
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

짤을 보시면 아시겠지만 실시간 랜더링(?)이라서 입력하는 매 순간에 데이터가 출력됩니다.

복수행 텍스트 : textarea

입력한 문장과 문장수를 표시하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">입력한 문장과 문자수를 표시하는 예제</h2>
		<div id="app">
			<textarea v-model="myText"></textarea>
			<p>{{myText}}</p>
			<p>{{myText.length}}</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myText:''
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

참고로 length는 input 태그에서도 동작합니다.

체크박스 : input checkbox

체크박스의 ON/OFF를 확인하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">체크박스의 ON/OFF를 확인하는 예제</h2>
		<div id="app">
			<label><input type="checkbox" v-model="myCheck"></input>체크박스의 상태는 {{myCheck}}</label>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myCheck:false
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

복수의 체크박스의 ON을 배열로 만드는 예제

체크박스 태그의 프로퍼티명은 동일하게 사용하고, Vue에서 해당 프로퍼티명을 배열로 초기화하면 됩니다.
단, value값을 통해 꼭 각 체크박스를 구분해야 합니다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">복수 체크박스의 ON을 확인하는 예제</h2>
		<div id="app">
			<label><input type="checkbox" v-model="myChecks" value="green"></input>green</label>
			<label><input type="checkbox" v-model="myChecks" value="red"></input>red</label>
			<label><input type="checkbox" v-model="myChecks" value="blue"></input>blue</label>
			<p>체크박스의 상태는 {{myChecks}}</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myChecks:[]
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

동의에 체크하면 송신 버튼이 활성화되는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">동의에 체크하면 송신 버튼이 활성화 되는 예제</h2>
		<div id="app">
			<label><input type="checkbox" v-model="agreeStatus">동의합니다</label>
			<button :disabled="!agreeStatus">송신</button>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					agreeStatus:false
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

라디오버튼 : radio

라디오버튼 역시 동일한 프로퍼티명을 사용합니다.

선택한 라디오 버튼을 표시하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">선택한 라디오 버튼을 표시하는 예제</h2>
		<div id="app">
			<label><input type="radio" value="red" v-model="myPicked">red</label>
			<label><input type="radio" value="green" v-model="myPicked">green</label>
			<label><input type="radio" value="blue" v-model="myPicked">blue</label>
			<p>{{myPicked}}를 선택했습니다.</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myPicked:''
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

선택한 라디오 버튼에 따라 "myPicked" 값이 달라집니다.

결과

제가 녹화 영상을 잘라서 그렇지, 처음에는 아무 버튼도 선택하지 않았기 때문에 공백이 뜹니다.ㅎ;

이미지 출력을 라디오 버튼으로 변경하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">이미지 출력을 라디오버튼으로 변경하는 예제</h2>
		<div id="app">
			<label><input type="radio" value="face1.png" v-model="myPic">face1</label>
			<label><input type="radio" value="face2.png" v-model="myPic">face2</label>
			<br>
			<img :src="myPic"></img>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myPic:''
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

선택 :select

문자열이 선택한 색으로 변하는 예제

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">문자열이 선택한 색으로 변하는 예제</h2>
		<div id="app">
			<select v-model="mySelect">
			<option disabled value=''></option>
			<option>red</option>
			<option>green</option>
			<option>blue</option>
			<option>gray</option>
			</select>
			<p :style="{color:mySelect}">선택한 색상은 {{mySelect}} 입니다.</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					mySelect:''
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

결과

녹화한 영상을 보니 select box가 안보이네요...(원인 모름)
허공에 클릭질하는 애처럼 보이겠지만 아닙니다ㅎㅎ

수식어(예제 생략)

  • .lazy
  • .number
  • .trim

상당히 유용한 v-model 수식어입니다.

다 쓰고 나서 vue 인스턴스 데이터에 입력하고 싶을 때

<input v-model.lazy="myName">

위 예제에서 봤을 때 키보드를 누를 때마다 실시간으로 값을 받아오는데,
이게 싫을 때 쓰면 됩니다.
lazy 수식어를 사용하면 Enter키를 누르거나 포커스가 다른 곳으로 이동할 때 입력 데이터를 한꺼번에 모아서 가져갑니다.

입력 내용을 자동으로 수식으로 변경하고 싶을 때

<input v-model.number="myAge">
<p>(만) {{myAge - 1}}세 입니다.</p>

number 수식어를 사용하지 않은 상태로 위 코드를 실행하면 "-1" 부분이 그냥 문자열 자체로 출력됩니다.

앞 뒤 공백을 제거할 때

<input v-model.trim="myText">
<p>{{myText}}</p>

실습해봅시다

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Vue.js sample</title>
		<link rel="stylesheet" href="style.css" >
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	</head>
	<body>
		<h2 align="center">입력폼 활용</h2>
		<div id="app">
			<label>이름 : </label>
			<input v-model.lazy="myName" placeholder="이름을 입력하세요"><br>
			<label>좋아하는 색은 : </label><br>
			<input type="radio" value="red" v-model="myColor">빨강<br>
			<input type="radio" value="green" v-model="myColor">녹색<br>
			<input type="radio" value="blue" v-model="myColor">파랑색<br>
			<input type="radio" value="yellow" v-model="myColor">노란색<br>
			<input type="radio" value="gray" v-model="myColor">회색<br>
			<br>
			<p :style="{color:myColor}">내 이름은 {{myName}} 이고 좋아하는 색은 {{myColor}} 입니다.</p>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					myName:'',
					myColor:''
				}
			})	
		</script>
	</body>
</html>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.menu{
  background: darkslateblue;
  padding : 15px;
   border-radius: 5px;
}
.menu a{
  color: white;
  padding: 20px;
}
</style>

🎨후기

움짤이 너무 많아서 그런가 작성 시점에서 너무 버벅입니다.
움짤을 줄이던지 해야겠어요..
아니면 노트북을 바꾸라는건가~?

좋은 웹페이지 즐겨찾기