728x90
★ 보간법
- mount하고 있는 9행 id가 app인 div요소
- {{ }} : 콧수염 모양을 닮았다해서, 콧수염 표현식이라고도 부르며, 보간법이라고 불릅니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03-01</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var model = { message:"Hello Vue3!" };
var vm = Vue.createApp({
name : "App",
data() {
return model;
}
}).mount('#app')
</script>
</body>
</html>
★ 기본 디렉티브
1. v-text, v-html 디렉티브
- Vue 디렉티브는 템플릿 안에 사용하는 v-로 시작하는 속성이며, 이것을 이용해 HTML 요소와 관련된 작업을 지정할 수 있습니다.
- v-text : {{message}} 와 같은 동일한 기능을 수행한다.
- 즉, inner Text 속성에 연결됨. 태그 문자열을 HTML 인코딩하여 나타나기 때문에 화면에는 태그 문자열이 그대로 나타남.
<div id="app">
<h2 v-text="message"></h2>
</div>
- v-html : innerHTML 속성을 변경하는 것.
- innerHTML 속성에 연결됨. 태그 문자열을 파싱하여 화면에 나타냄
<div id="app">
<h2 v-html="message"></h2>
</div>
2. v-bind 디렉티브
- 요소(Element)의 속성을 바인딩하기 위해 사용한다.
- v-bind 디렉티브를 통해서 HTML 요소 객체의 속성이 변경됨.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ex03-3</title>
</head>
<body>
<div id="app">
<input id="a" type="text" v-bind:value="message">
<br>
<img v-bind:src="imagePath"/>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "app",
data() {
return {
message : "v-bind 디렉티브",
imagePath : "https://contactsvc.bmaster.kro.kr/photos/18.jpg"
};
}
}).mount('#app')
</script>
</body>
</html>
- 생략 가능 : v-bind를 생략할 수 있다.
v-bind:src -> :src
- v-bind 디렉티브는 단방향으로만 데이터 바인딩을 수행. 즉, Vue 인스턴스의 데이터나 속성이 바뀌면 UI를 갱신.
- 반대로 화면의 바인딩된 요소에서 값을 변경하더라도, 데이터가 바뀌지 않는다.
3. v-model 디렉티브
- v-text, v-html, v-bind가 모두 단방향 데이터 바인딩을 지원.
- 하지만, v-model은 양방향 데이터 바인딩을 지원
<div id="app">
<input id="a" type="text" v-model="name">
입력하신 이름 : <span>{{name}}</span>
</div>
<script>
var vm = Vue.createApp({
name : "App",
data() {
return { name : "" };
}
}).mount("#app")
</script>
- v-model 디렉티브를 이용한 양방향 데이터 바인딩은 checkbox, select, radio button 등에도 적용 가능.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ex03-05</title>
</head>
<body>
<div id="app">
<div>
<h2>취미생활</h2>
<input type="checkbox" id="hobbyA" value="A" v-model="hobby">
<label for="hobbyA">운동</label><br>
<input type="checkbox" id="hobbyB" value="B" v-model="hobby">
<label for="hobbyB">독서</label><br>
<input type="checkbox" id="hobbyC" value="C" v-model="hobby">
<label for="hobbyC">음악</label><br>
<input type="checkbox" id="hobbyD" value="D" v-model="hobby">
<label for="hobbyD">댄스</label><br>
<input type="checkbox" id="hobbyE" value="E" v-model="hobby">
<label for="hobbyE">역사</label>
</div>
<div>
<h2>상품 분류 선택</h2>
<select v-model="category">
<option value="">---- 상품 분류를 선택하세요 ----</option>
<option value="C01">레저</option>
<option value="C02">가전</option>
<option value="C03">음식</option>
<option value="C04">도서</option>
<option value="C05">주방</option>
</select>
</div>
<hr>
<div>
선택한 취미 : {{hobby.join(',')}} <br>
선택한 상품 분류 : {{category}}
</div>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
hobby : [],
category : ""
};
}
}).mount('#app')
</script>
</body>
</html>
- 다중 선택의 경우는 배열을 이용해야 하여, hobby : []
- 단일 선택은 문자열로 값을 받아내기 때문에, category : ""
- checkbox,radio와 같이 input 요소를 사용하는 경우는 각각의 input 요소마다 v-model 디렉티브를 적용하지만,
- select와 같이 값을 선택하는 요소를 감싸는 부모 요소가 있다면, 부모 요소인 select에 v-model 디렉티브를 한 번만 적용한다는 점도 주의해야 한다.
- checkbox로 선택, 미선택으로 구분하여 값을 전달하는 경우
<div id="app">
위의 내용에 동의하십니까?
<input type="checkbox" v-model="agree" true-value="yes" false-value="no" />
<hr>
<span> 선택된 값 : {{agree}} </span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data : {
return {
agree : "no"
};
}
}).mount('#app')
</script>
4. 수식어
- v-model 디렉티브는 몇 가지의 수식어를 지원한다.
- v-model에서 사용할 수 있는 수식어는 다음과 같다.
- 1. lazy : 입력폼에서 다른 요소로 포커스가 이동하는 이벤트가 발생할 때, 입력한 값을 데이터와 동기화
<input type="text" v-model.lazy="name" />
- number : 이 수식어를 지정하면 숫자가 입력될 경우 number 타입의 값으로 자동 형변환되어 데이터를 옵션 값으로 반영
<input type="text" v-model.number="num"/>
- trim : 이 수식어를 지정하면 문자열의 앞뒤 공백을 자동으로 제거한다.
<input type="text" v-model.trim="message"/>
- number 수식어를 사용한 예
- 숫자로 형변환이 가능한 값을 입력하면 정상적으로 형변환 되어 숫자로 값이 저장.
- 하지만, 100aaa 를 입력하게 되면 숫자로 형변환이 가능한 숫자부분만 값을 할당.
- 처음부터 문자열을 입력하게 되면 문자열로 형변환 되어 값을 할당.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03-07</title>
</head>
<body>
<div id="app">
<input type="text" v-model.number="num"><br>
입력된 수 : <span>{{ num }}</span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { num : 0 };
}
}).mount('#app')
</script>
</body>
</html>
- 한글에 대한 바인딩이 잘 되지 않는 부분에 대한, 해결법
- @input="changeName"과 같이 이벤트 핸들러 메서드를 등록하여 name 데이터로 부여
<div id="app">
<input id="a" type="text" :value="name" @input="changeName">
<br>
입력하신 이름 : <span>{{name}}</span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { name : "" };
},
methods : {
changeName(e) {
this.name = e.target.value;
}
}
}).mount("#app")
5. 조건 렌더링 디렉티브
- v-show : 화면에 보여줄지 말지를 결정하는 디렉티브
<div id="app">
예금액 : <input type="text" v-model="amount"/>
<img v-show="amount < 0 " src="https://contactsvc.bmaster.kro.kr/img/error.png"
title="마이너스는 허용하지 않습니다."
style="width:15px; height: 15px; vertical-align: middle;"/>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { amount : "" };
},
}).mount("#app")
</script>
- v-if : 조건에 부합하지 않을 경우 렌더링을 수행하지 않도록 함.
- 하지만, v-if는 HTML 요소를 만들어내지는 않는다.
<div id="app">
예금액 : <input type="text" v-model="amount"/>
<img
v-if="amout < 0"
src="https://contactsvc.bmaster.kro.kr/img/error.png"
title="마이너스는 허용하지 않습니다."
style="width: 15px; height: 15px; vertical-align: middle;" />
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { amount : "" };
},
}).mount("#app")
</script>
- v-else, v-else-if 디렉티브
- 계좌 잔고에 따라 고객의 등급을 평가하는 예제
<div id="app">
잔고 : <input type="text" v-model="balance" />
<br>
회원님의 등급 :
<span v-if="balance >= 1000000">Gold</span>
<span v-else-if="balance >= 500000">Silver</span>
<span v-else-if="balance >= 200000">Bronze</span>
<span v-else>Basic</span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { balance : 0 }
}
}).mount("#app")
6. 반복 렌더링 디렉티브
- v-for : 반복적인 데이터를 렌더링하기 위해서 v-for 디렉티브를 사용한다.
- contacts라는 배열의 갯수 만큼 for문을 돌아 반복되어 나타난다.
<div id="app">
<table id="list">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
</tr>
</thead>
<tbody id="contacts">
<tr v-for="contact in contacts" :key="contact.no">
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp ({
name : "App",
data() {
return {
"pageno" : 1,
"pagesize" : 4,
"totalcount" : 100,
"contacts" : [
{ "no" : 1011, "name" : "RM", "tel" : "010-3456-8299" },
{ "no" : 1012, "name" : "정국", "tel" : "010-3456-8298" },
{ "no" : 1013, "name" : "제이홉", "tel" : "010-3456-8297" },
{ "no" : 1014, "name" : "슈가", "tel" : "010-3456-8296" },
]
}
}
}).mount('#app')
</script>
- 원본 데이터가 객체인 경우 => 키를 이용해 값에 접근하는 해시맵 구조이기 때문에 Key, Value 값을 얻어낼 수 있는 구조 사용
<div id="app">
<select id="regions">
<option disabled="disabled" selected>지역을 선택하세요.</option>
<option v-for="(val, key) in regions" :value="key" :key="key">
{{ val }}
</option>
</select>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
regions : {
"A" : "Asia",
"B" : "America",
"C" : "Europe",
"D" : "Africa",
"E" : "Oceania"
}
}
}
}).mount("#app")
</script>
- 인덱스 번호를 함께 표현해야 한다면
- 배열 데이터인 경우
<tr v-for="(contact, index) in contacts" ...>
- 객체 데이터인 경우
<option v-for="(val, key, index) in regions" ...>
7. 여러 요소를 묶어서 반복 렌더링하기
- 여러 요소를 묶어서 반복 렌더링을 하고 싶다면, <template> 요소와 v-for 디렉티브를 함께 사용하면 됨.
- <template> 태그는 렌더링 내용에는 포함되지 않습니다. 단지, 요소들을 그룹으로 묶어주기 위한 용도로만 사용.
- 가급적, key 특성을 부여하도록 하고, 반복 렌더링되는 각각의 요소 노드를 추적하고 요소를 재사용할 수 있도록 key 특성에 반드시 고유 값을 바인딩하는 것이 좋다.
<div id="app">
<table id="list">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
</tr>
</thead>
<tbody id="contacts">
<template v-for="(contact, index) in contacts" :key="contact.no">
<tr>
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
</tr>
<tr class="divider" v-if="index % 4 === 3">
<td colspan="3"></td>
</tr>
</template>
</tbody>
</table>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
"contacts": [
{ "no" : 1011, "name" : "RM", "tel" : "010-3456-8299" },
{ "no" : 1012, "name" : "정국", "tel" : "010-3456-8298" },
{ "no" : 1013, "name" : "제이홉", "tel" : "010-3456-8297" },
{ "no" : 1014, "name" : "슈가", "tel" : "010-3456-8296" },
{ "no" : 1011, "name" : "진", "tel" : "010-3456-8295" },
{ "no" : 1012, "name" : "뷔", "tel" : "010-3456-8294" },
{ "no" : 1013, "name" : "지민", "tel" : "010-3456-8293" },
]
}
}
}).mount("#app")
</script>
8. 기타 디렉티브
- v-pre 디렉티브 : HTML 요소에 대한 컴파일을 수행하지 않는다.
- 즉, v-pre 디렉티브로 인해, Vue 인스턴스는 컴파일하지 않고 {{message}} 문자열을 그대로 출력한다.
<span v-pre>{{message}}</span>
- v-once 디렉티브 : HTML 요소를 단 한번만 렌더링하도록 설정한다.
- 즉, 초기 렌더링을 수행할 때 단 한번만 데이터를 바인딩하여 출력한다.
- 초기 렌더링이 완료된 후에는 데이터가 변경되더라도 다시 렌더링 되지 않는다.
<div id="app">
<span v-once>{{message}}</span>
</div>
- v-cloak 디렉티브 : 화면 초기에 컴파일되지 않은 템플릿은 나타나지 않도록 할 수 있다.
- 가끔 v-for 디렉티브를 이용해 많은 데이터를 출력하거나 할 때에 콧수염 표현식이 화면에 일시적으로 나타나는 경우가 있다. 복잡한, UI일수록 이런 경우가 빈번히 발생된다.
<style>
[v-clock] { display:none; }
</style>
<body>
<div id="app" v-cloak>
</body>
- 동적 아규먼트(Dynamic Argument)
- v-bind 디렉티브나 이벤트 처리를 위한 v-on 디렉티브에서 사용할 수 있다.
<!-- v-bind 예시-->
<element v-bind:[attrName] = "[attrValue]"></element>
<element :[attrName] = "[attrValue]"></element>
<!-- v-on 예시 -->
<element v-on:[eventName] = "[function code]"></element>
<element @[eventName] = "[function code]"></element>
- 예시
<div id="app">
<img v-bind:[image1.srcattr]="image1.src"
:[image1.titleattr]="image1.title"/>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
image1 : {
srcattr:"src", src:"https://contactsvc.bmaster.kro.kr/photos/18.jpg",
titleattr: "title", "title" : "Lily's photo"
}
};
}
}).mount("#app")
</script>
728x90
'Vue.js' 카테고리의 다른 글
Vue.js 3.0 STEP 3 - 이벤트 처리 (0) | 2024.01.18 |
---|---|
Vue.js 3.0 STEP 2 - Vue 인스턴스 (0) | 2024.01.18 |
ES6 STEP 2 - 기본 문법 2 (0) | 2024.01.17 |
ES6 STEP 1 - 기본 문법 (0) | 2024.01.16 |
Vue.js STEP 4 - 기본 문법 2 (1) | 2024.01.11 |