데이터 바인딩 템플릿 문법
Vue js는 양방향 데이터를 지원하기 때문에 모델에서 데이터를 정의한 후 뷰와 연결하면 어느 한쪽에 변경이 일어났을 때 다른 한쪽에 자동으로 반영이 됨.
Model에서 정의한 데이터를 View에서 이중 중괄호를 이용하여 데이터 바인딩
1. 문자열 데이터 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<template>
<h1> hello, {{title}}!</h1>
</template>
<script>
export default {
data(){
return{
title:'world'
};
}
}
</script>
|
cs |
2. HTML 태그 바인딩
HTML 태그를 바인딩 할 때는 문자열 바인딩처럼 이중 중괄호를 사용하면 텍스트로 인식하기 때문에 HTML로 출력되기 위해서는 "v-html" 디렉티브를 사용해야 함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<template>
<div>
<div>{{htmlString}}</div>
<div v-html="htmlString"></div>
</div>
</template>
<script>
export default {
data(){
return{
htmlString:'<p style="color:red;">This is a red String</p>'
};
}
}
</script>
|
cs |
3. Form 입력 데이터 바인딩
Input type, Textarea, Select, checkbox, radio 등의 Form Element 필드는 "v-model" 디렉티브를 사용하여 양방향 데이터 바인딩을 생성할 수 있음.
- input type="text" : HTML에서 입력받은 데이터는 value에 저장되는데, "v-model"은 내부적으로 이 value 속성을 사용하여 data와 value속성을 바인딩 시킴.
- input type="number" : 숫자를 입력할 시에는 "v-model.number" 디렉티브를 사용할 수 있음.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<template>
<div>
<input type="text" v-model="valueModel"/><br>
<input type="number" v-model.number="numberModel"/>
</div>
</template>
<script>
export default {
data(){
return{
valueModel:'South Korea',
numberModel: 38
};
}
}
</script>
|
cs |
- Textarea: Textarea 속성은 "v-model"을 사용하여 바인딩 함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<template>
<div>
<textarea v-model="message"></textarea>
</div>
</template>
<script>
export default {
data(){
return{
message:"텍스트 입력 창입니다."
};
}
}
</script>
|
cs |
- Select : input type=text와 동일하게 "v-model"은 내부적으로 select의 value속성을 사용하여 양방향 데이터 바인딩.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<template>
<div>
<select v-model="city">
<option value="02">서울</option>
<option value="031">경기</option>
<option value="064">제주</option>
</select>
</div>
</template>
<script>
export default {
data(){
return{
city:"064"
};
}
}
</script>
|
cs |
- input type="checkbox" : input type=text, select와 다르게 v-model은 내부적으로 체크박스의 value속성이 아닌 checked속성을 사용하므로 value속성에 데이터 바인딩 시 "v-bind:value"를 사용함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<template>
<div>
<label><input type="checkbox" value="서울" v-model="checked">서울</label>
<label><input type="checkbox" value="부산" v-model="checked">부산</label>
<label><input type="checkbox" value="제주" v-model="checked">제주</label>
<br>
<span>체크한 지역:{{checked}}</span>
</div>
</template>
<script>
export default {
data(){
return{
checked:[]
};
}
}
</script>
|
cs |
- input type="radio" : 체크박스와 마찬가지로 v-model이 내부적으로 checked속성과 바인딩이 이루어지므로, value속성에 바인딩을 하려면 "v-bind:value"를 사용함.
4. HTML 속성 바인딩
value을 제외한 HTML 객체 속성에 데이터를 바인딩 하기 위해서 "v-bind:" 디렉티브를 사용함. "v-bind"를 생략하고 ':' (콜론)으로 단독 사용할 수도 있음.
- Img객체의 src : 제품 이미지, 사용자 프로필 사진처럼 이미지의 주소를 img객체의 src에 바인딩 할 수 있음.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<template>
<div>
<img v-bind:src="imgSrc"/>
</div>
</template>
<script>
export default {
data(){
return{
imgSrc:"https://kr.vuejs.org/images/logo.png"
};
}
}
</script>
|
cs |
- 버튼 객체의 disabled : 버튼에서 disabled 속성이 true로 되어 있으면 버튼은 비활성화 되고 클릭 이벤트가 발생 되지 않음. "v-model"는 내부적으로 value 속성과 바인딩이 이루어지고 "v-bind"는 disabled속성과 바인딩이 이루어짐.
5. 클래스 바인딩
HTML에서 사용하는 방식처럼 class 속성에 클래스 명을 입력하여 사용할 수 있고, 조건에 따라 바인딩 할 경우 "v-bind:class"를 이용해서 추가적으로 정의해서 사용할 수 있음.
앞서 살펴본 HTML속성 바인딩과 다르게 클래스 바인딩은 아래와 같이 기본 클래스와 데이터 바인딩 처리를 하는 클래스를 공존해서 사용할 수 있음.
- 배열을 사용한 클래스 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<template>
<div class="container" v-bind:class="[
activeClass,errorClass]">Class Binding
</div>
</template>
<script>
export default {
data(){
return{
activeClass:'active',
errorClass:'text-red'
};
}
}
</script>
<style scoped>
.container{
width: 100%;
height: 500px;
}
.active{
background-color: yellow;
font-weight:bold;
}
.text-red{
color:red;
}
</style>
|
cs |
- 인라인 스타일 클래스 바인딩: 데이터를 오브젝트로 선언해서 바인딩할 수 있음.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<template>
<div v-bind:style="styleObject">인라인 스타일 바인딩</div>
</template>
<script>
export default {
data() {
return {
styleObject: {
color: 'red',
fontSize: '13px'
}
};
}
}
</script>
|
cs |
리스트 랜더링(v-for)
v-for 디렉티브를 사용하여 반복적으로 다중 데이터들을 처리할 수 있음. v-for="(item, index) in items 형식을 사용하며 items는 배열을 의미하고 v-for을 통해 배열을 하나씩 읽어와서 배열의 각 아이템을item으로, 배열의 현재 index를 index로 반환해 줌.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<template>
<div>
<table>
<thead>
<tr>
<th>제품명</th>
<th>가격</th>
<th>카테고리</th>
<th>배송료</th>
</tr>
</thead>
<tbody>
<tr :key="i" v-for="(product,i) in productList">
<td>{{product.product_name}}</td>
<td>{{product.price}}</td>
<td>{{product.category}}</td>
<td>{{product.delivery_price}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
productList: [
{"product_name":"기계식키보드","price":25000,"category":"노트북/태블릿","delivery_price":5000},
{"product_name":"무선마우스","price":12000,"category":"노트북/태블릿","delivery_price":5000},
{"product_name":"아이패드","price":725000,"category":"노트북/태블릿","delivery_price":5000},
{"product_name":"태블릿거치대","price":32000,"category":"노트북/태블릿","delivery_price":5000},
{"product_name":"무선충전기","price":42000,"category":"노트북/태블릿","delivery_price":5000}
]
};
}
}
</script>
<style scoped>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 50%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
</style>
|
cs |
조건부 랜더링
Vue 컴포넌트에서 조건에 따라 랜더링을 하는 방법은 v-if 디렉티브와 v-show 디렉티브를 사용하는 방법이 있음.
- v-if
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<template>
<div>
<h1 v-if="type=='A'">A</h1>
<h1 v-else-if="type=='B'">B</h1>
<h1 v-else>C</h1>
</div>
</template>
<script>
export default {
data() {
return {
type: 'A'
};
}
}
</script>
|
cs |
- v-show: v-if 대신에 v-show를 사용하면 되고 else if, else는 지원 하지 않음
- v-if와 v-show의 차이점
- v-if는 조건을 만족하면 그 순간에 html 블록이 생성되고, 조건에 만족하지 않으면 html블록은 삭제됨.
- v-show는 조건 만족 여부에 상관없이 무조건 랜더링 되어 DOM에 남아있게 됨. 조건 만족 시 css의 display CSS속성을 이용해 화면에 보여지고, 조건을 만족하지 않으면 화면에서 숨기도록 처리됨.
- html 블록이 화면 내에서 자주 toggle되면 v-show를 사용하고, toggle이 일어나는 빈도가 적으면 v-if를 사용하는 것이 좋음.
이벤트 처리
- 클릭 이벤트: vue컴포넌트에서 이벤트를 처리할 때 "v-on" 디렉티브를 사용하고, "v-on:"을 '@'로 대체할 수 있음.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<div>
<button type="button" @click="increaseCounter">Add 1</button>
<p>The counter is : {{counter}} </p>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0
};
},
methods: {
increaseCounter(){
this.counter = this.counter + 1;
}
}
}
</script>
|
cs |
- Change 이벤트: select속성에서 자주 사용되며 사용자가 select에서 옵션을 바꿀 때 마다 change이벤트가 발생.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<select v-model="selectedValue" @change="changeSelect">
<option value="서울">서울</option>
<option value="부산">부산</option>
<option value="제주">제주</option>
</select>
</template>
<script>
export default {
data() {
return {
selectedValue: ''
};
},
methods: {
changeSelect(){
alert(this.selectedValue);
}
}
}
|
cs |
Computed와 Watch
Computed와 Watch 둘 다 Vue 인스턴스 내의 정의된 데이터 값에 변경이 일어나는지를 감시하고 , 변경될 때 마다 정의된 함수가 실행되는 속성
- Computed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<template>
<h1>Full Name:{{fullName}}</h1>
</template>
<script>
export default {
data() {
return {
firstName:'JeongHwan',
lastName:'Kim'
};
},
computed: {
fullName(){
return this.firstName+' '+this.lastName;
}
}
}
</script>
|
cs |
Computed는 Vue 인스턴스 내에 정의된 데이터 값과 연관된 새 데이터를 정의해서 사용할 수 있도록 해줌.
위 코드에서 함수 이름인 fullName은 함수이자 동시에 Vue 인스턴스의 데이터(새로 정의된)를 의미함. fullName함수가 실행되면 데이터 fullName에 firstName과 lastName을 합친 값이 할당되고 두 값 중 하나라도 변경이 일어나면 fullName함수가 자동으로 실행되고 값이 갱신됨.
-> Computed는 함수이자 Vue 인스턴스의 데이터
- Watch: Computed처럼 vue 인스턴스에 정의된 데이터 값에 변경이 일어나는지를 감시하고 변경이 일어나면 지정된 함수를 실행시킬 수 있는 점은 같지만 다음과 같은 차이가 있음.
- Computed: 기존에 정의된 데이터 값을 기반으로 새로운 데이터 값을 활용하기 위해 사용됨.
- Watch는 Watch에 정의된 데이터 값 하나만을 감시하기 위한 용도로 사용되고 Computed와 다르게 실제 데이터 변경이 일어나기 전까지 함수가 실행되지 않고 반드시 초기 값이 변경되어야 실행됨.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<template>
<div>
<h1>Full Name:{{fullName}}</h1>
<button type="button" @click="changeName">변경</button>
</div>
</template>
<script>
export default {
data() {
return {
firstName:'JeongHwan',
lastName:'Kim',
fullName:''
};
},
watch:{
firstName(){
this.fullName=this.firstName+this.lastName;
},
lastName(){
this.fullName=this.firstName+this.lastName;
}
},
methods:{
changeName(){
this.firstName='kevin';
}
}
}
</script>
|
cs |
- firstName과 lastName의 각각의 상태변화를 감시하기 위해 watch구문에 2개의 함수를 정의.
- 버튼 클릭 전 까지는 값에 변동이 없으므로 출력되지 않음→ changeName()함수가 실행되면(초기 firstName과 같으면 출력X) 변경 값이 출력됨.