frontend/vue.js

vue.js form 사용법

seul chan 2018. 1. 23. 10:13

Input data bind basic

input tag에 데이터를 바인딩 하기 위해서는 v-model이 필요하다. v-model을 사용하면 아주 쉽게 데이터를 바인딩 시킬 수 있다.

App.vue

App.vue에 email input 필드를 추가한 후, email 데이터를 만들고 v-model="email"로 해당 인풋 필드와 연결시켜준다.

<template>
<div>
	<label for="email">Email</label>
	<input type="text" id="email" v-model="email">
	<p>Mail: </p>
</div>

</template>

<script>
export default {
	data() {
		return {
			email: ""
		}
	}
}
</script>

이제 input 필드에 값을 입력하면 아래 `` 데이터에 바인딩 되는 것을 볼 수 있다.

v-model.lazy

v-model은 기본적으로 모든 key stroke가 발생할 때마다 값을 업데이트 시킨다. 이를 방지하고 싶다면 v-model.lazy를 사용하면 된다.

그러면 입력을 하다가 키를 떼거나 다른 부분을 클릭하면 그 때 값이 업데이트 된다.

<div>
	<label for="email">Email</label>
	<input type="text" id="email" v-model.lazy="email">
	<p>Mail: </p>
</div>

Pre-populated field

특정 값을 input에 미리 지정하고 싶다면, 해당 필드의 값을 추가하는 것이 아니라 vue의 data에 값을 지정해주면 된다. 그러면 vue가 자동으로 해당 필드를 pre-populate 해준다.

다음과 같이 작성하면 email input에 vue email data에 적은 test@test.com이 나타나는 것을 볼 수 있다.

<template>
<div>
	<label for="email">Email</label>
	<input type="text" id="email" v-model="email">
	<p>Mail: </p>
</div>

</template>

<script>
export default {
	data() {
		return {
			email: "test@test.com"
		}
	}
}
</script>

Textarea

기본적으로 linebreak가 설정이 안 되어있기 때문에 white-space:pre 스타일을 추가해주어야한다.

<template>
	<div>
		<textarea id="" name="" cols="30" rows="10" v-model="message"></textarea>
		<p style="white-space:pre"></p>
	</div>
</template>

<script>
export default {
	data() {
		return {
			message: ""
		}
	}
}
</script>

여러 checkbox 데이터를 array로 전달하기

어러 checkbox를 사용하려면 checkbox input field에 같은 v-model을 추가해주면 된다.

<temlapte>
<div>
	<label for="typeA">
		<input id="typeA" type="checkbox" v-model="checked">
	</label>
	<label for="typeB">
		<input id="typeB" type="checkbox" v-model="checked">
	</label>
	<ul>
		<li v-for="item in checked"></li>
	</ul>
</div>
</temlapte>

<script>
export default {
	data() {
		return {
			checked: []
		}
	}
}
</script>

Radio 데이터 전달하기

위의 checkbox와 동일하게 input에 v-model을 추가해주면 된다. 같은 v-model을 추가하면 vue가 자동으로 같은 radio라는 것을 알아채고 한개만 선택되게 만들어준다.

또한 radio의 value를 바로 vue의 해당 v-model 데이터에 전달해준다.

<temlpate>
<div>
	<label for="male">
		<input type="radio" id="male" value="Male" v-model="gender"> Male
	</label>
	<label for="female">
		<input type="radio" id="female" value="Female" v-model="gender"> Female
	</label>
	<p>Gender: </p>
</div>
</temlpate>

<script>
export default = {
	data() {
		return {
			gender: "Male"
		}
	}
}
</script>

Select의 옵션 데이터 전달하기

select도 v-model을 이용해서 간단하게 값을 전달해 줄 수 있다.

뿐만 아니라 옵션들 또한 vue의 데이터에 지정해 두고 v-for를 이용해 간단하게 만들 수 있다.

pre-populated는 select 태그 자체에 selectedData를 populated 시키는 방법과, option 태그에 selected를 v-bind 시키는 두가지 방법이 있다. (v-bind:selected="heigth == 'Medium'")

<temlpate>
	<div>
		<select id="height" name="height" v-model="selectedData">
			<option v-for="height in heights" v-bind:selected="height == 'Medium'"></option>
		</select>
	</div>
</temlpate>

<script>
export default {
	data() {
		return {
			selectedData: "High",
			heights: ["Low", "Medium", "High"]
		}
	}
}
</script>

v-model의 원리?

  1. v-bind:value="value" 로 value를 binding한다.
  2. v-on:input="email = $event.target.value" 로 값을 전달

위에서 본 email input을 직접 만들어 보면,

<temlpate>
	<div>
		<input type="text"
		v-bind:value="email"
		v-on:input="email = $event.target.value">
	</div>
</temlpate>

<script>
export default {
	data() {
		return {
			email: ""
		}
	}
}
</script>

위 코드는 v-model="email"과 동일하게 구현된다.

Creating custom input

위에서 살펴본 v-model의 원리를 토대로 custom input을 만들어보자.

스위치 on, off를 누르면 스위치들의 클래스가 바뀌는 간단한 Switch 컴포넌트를 만들어 보겠다.

해당 스위치를 클릭하면 Switch 컴포넌트 내의 isOn 데이터가 변경되는 방식이다.

Switch.vue

<template>
	<div>
		<div
			id="on"
			v-on:click="isOn = true"
			v-bind:class="{active: isOn}">On</div>
		<div
			id="off"
			v-on:click="isOn = False"
		    v-bind:class="{active: !isOn}">Off</div>
	</div>
</template>

<script>
export default {
 	data() {
 		return {
 			isOn: true
 		};
 	},
}
</script>

<style scoped>
#on, #off {
	width: 40px;
	height: 20px;
	background-color: lightgray;
	padding: 2px;
	display: inline-block;
	margin: 10px -2px;
	box-sizing: content-box;
	cursor: pointer;
	text-align: center;
}

#on:hover, #on.active {
	background-color: lightgreen;
}

#off:hover, #off.active {
	background-color: lightcoral;
}
</style>

위에서 만든 Switch 컴포넌트를 App.vue에 추가

App.vue

<temlpate>
	<app-switch v-model="dataSwitched"></app-switch>
	<p>
		Switched: 
	</p>
</temlpate>

<script>
import Switch from './Switch.vue';

export default {
	components: {
		appSwitch: Switch
	},
	data: function() {
		dataSwitched: true
	}
}
</script>

이를 App.vue 부모 컴포넌트에 있는 Switched 데이터와 연결시켜 보겠다.

우선 props로 value를 넘긴다 (v-bind의 원리에서 봤듯이 value값을 binding 하기 때문)

그리고 해당 버튼을 클릭하면 클릭 한 값을 $emit해 주는 switched() 메쏘드를 추가.

Switch.vue

<template>
	<div>
		<div
			id="on"
			v-on:click="switched(true)"
			v-bind:class="{active: value}">On</div>
		<div
			id="off"
			v-on:click="switched(false)"
		    v-bind:class="{active: !value}">Off</div>
	</div>
</template>

<script>
export default {
	props: ['value'],
	methods: {
		switched(isOn) {
			this.$emit('input', isOn);
		}
	}
}
</script>

<style scoped>
#on, #off {
	width: 40px;
	height: 20px;
	background-color: lightgray;
	padding: 2px;
	display: inline-block;
	margin: 10px -2px;
	box-sizing: content-box;
	cursor: pointer;
	text-align: center;
}

#on:hover, #on.active {
	background-color: lightgreen;
}

#off:hover, #off.active {
	background-color: lightcoral;
}
</style>

Submit 버튼 사용하기

기본적으로 form 안에 있는 버튼을 누르면 form의 데이터가 전달되기 때문에 이를 방지하기 위해서 prevent를 사용해준다. (v-on:click.prevent="")

submit 버튼을 누르면 위에 적은 데이터들을 아래 출력시키는 예제이다.

App.vue

<temlpate>
<div>
	<form action="">
		<input type="text" v-model="email">
		<input type="password" v-model="password">
		<button v-on:click.prevent="submitted">Submit</button>
		<div v-if="isSubmitted">
		Email: 
		Password: 
		</div>
	</form>
</div>
</temlpate>

<script>
export default {
	data: function() {
		email: "test@test.com",
		password: "secret",
		isSubmitted: false
	},
	methods: {
		submitted() {
			 this.isSubmitted = true;
		}
	}
}
</script>


'frontend > vue.js' 카테고리의 다른 글

vue.js Router: vue-router  (0) 2018.01.30
vue.js: http via Vue Resource  (0) 2018.01.26
vuejs: Filter, Mixins 심화  (0) 2018.01.22
vue.js custom Directives 만들기  (0) 2018.01.21
vue.js 동적 컴포넌트 사용법 (component, keep-alive)  (0) 2018.01.20