hello vue.js 예제 분석
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>hello vue.js</title>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="simple">
<h2>{{ message }}</h2>
</div>
<script type="text/javascript">
var model = {
message: "첫 번째 Vue.js 앱입니다."
};
var simple = new Vue({
el: "#simple",
data: model
});
</script>
</body>
</html>
기본 디렉티브
v-text, v-html
<!-- innerText 속성에 연결됨 -->
<div id="simple">
<h2 v-text="message"></h2>
</div>
<!-- innerHTML 속성에 연결 -->
<div id="simple">
<h2 v-html="message"></h2>
</div>
v-bind
- 요소의 콘텐츠 영역을 설정하는 것이 아닌 요소 객체의 속성들을 바인딩하기 위해 사용
<body>
<div id="simple">
<input id="a" type="text" v-bind:value="message">
<br />
<img v-bind:src="imagePath" />
<br /><br />
<!-- 축약형 -->
<input id="a" type="text" :value="message">
<br />
<img :src="imagePath" />
</div>
<script type="text/javascript">
var model = {
message: "v-bind 디렉티브",
imagePath: "http://sample.bmaster.kro.kr/photos/61.jpg"
};
var simple = new Vue({
el: "#simple",
data: model
});
</script>
</body>
v-model
- 양방향 바인딩
- 몇가지 수식어를 지원
- lazy : 입력폼에서 이벤트가 발생할 때 입력한 값을 데이터와 동기화. 텍스트 박스에서라면 입력 후 포커스가 이동하거나 할때 데이터 옵션 값 변경
- <input type="text" v-model.lazy="name" />
- number : 이 수식어를 지정하면 숫자가 입력될 경우 number 타입의 값으로 자동 형병환되어 데이터 옵션값으로 반영
- trim : 이 수식어를 지정하면 문자열의 앞뒤 공백을 자동으로 제거
- lazy : 입력폼에서 이벤트가 발생할 때 입력한 값을 데이터와 동기화. 텍스트 박스에서라면 입력 후 포커스가 이동하거나 할때 데이터 옵션 값 변경
<body>
<div id="simple">
<input id="a" type="text" v-model="name" placeholder="이름을 입력하세요">
<br /> 입력된 이름 :
<h2 v-html="name"></h2>
</div>
<script type="text/javascript">
var model = {
name: ""
};
var simple = new Vue({
el: "#simple",
data: model
});
</script>
</body>
<body>
<div id="simple1">
<div>좋아하는 과일을 모두 골라주세요</div>
<input type="checkbox" value="1" v-model="fruits">사과,
<input type="checkbox" value="2" v-model="fruits">키위,
<input type="checkbox" value="3" v-model="fruits">포도,
<input type="checkbox" value="4" v-model="fruits">수박,
<input type="checkbox" value="5" v-model="fruits">참외
</div>
<hr/>
<div id="simple2">
선택된 과일들 : <span v-html="fruits"></span>
</div>
<script type="text/javascript">
var model = {
fruits: []
};
var simple1 = new Vue({
el: "#simple1",
data: model
});
var simple2 = new Vue({
el: "#simple2",
data: model
});
</script>
</body>
v-show, v-if, v-else, v-else-if 디렉티브
- v-if는 조건에 부합되지 않으면 랜더링을 하지 않음
- v-show 는 조건을 만족하지 않을 때 display 속성을 none 으로 하여 보이지 않게 함. 즉 랜더링을 함
<body>
<div id="account">
예금액: <input type="text" v-model="amount">
<img v-if="amount < 0" src=""
alt="이미지에러"
title="마이너스는 허용하지 않습니다."
style="width:15px; height:15px; vertical-align:middle;">
</div>
<script type="text/javascript">
var model = {
amount: 0
};
var simple1 = new Vue({
el: "#account",
data: model
});
</script>
</body>
<body>
<div id="account">
잔고 : <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">
var model = {
balance: 0
};
var simple1 = new Vue({
el: "#account",
data: model
});
</script>
</body>
v-for
배열에 적용
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>hello vue.js</title>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<style>
#list {
width: 400px;
border: 1px solid black;
border-collapse: collapse;
}
#list td,
#list th {
border: 1px solid black;
text-align: center;
}
#list>thead>tr {
color: yellow;
background-color: purple;
}
</style>
</head>
<body>
<div id="example">
<table id="list">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
<th>주소</th>
</tr>
</thead>
<tbody id="contacts">
<tr v-for="contact in contacts">
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
<td>{{contact.address}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
var model = {
pageno: 1,
pagesize: 10,
totalcount: 100,
contacts: [
{no : 100, name: "설현", tel : "010-000-0000", address: "서울"},
{no : 99, name: "혜리", tel : "010-000-0001", address: "서울"},
{no : 98, name: "하니", tel : "010-000-0002", address: "경기"},
{no : 97, name: "성소", tel : "010-000-0003", address: "제주"},
{no : 96, name: "지아", tel : "010-000-0004", address: "전주"},
{no : 95, name: "정연", tel : "010-000-0005", address: "포천"},
{no : 94, name: "쯔위", tel : "010-000-0006", address: "안양"},
{no : 93, name: "사나", tel : "010-000-0007", address: "영주"},
{no : 92, name: "모모", tel : "010-000-0008", address: "광주"},
{no : 91, name: "소진", tel : "010-000-0009", address: "부산"}
]
};
var simple1 = new Vue({
el: "#example",
data: model
});
</script>
</body>
</html>
<tbody id="contacts">
<tr v-for="(contact, index) in contacts">
<td>{{index+1}}</td>
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
<td>{{contact.address}}</td>
</tr>
</tbody>
<tbody id="contacts">
<tr v-for="(contact, index) in contacts" v-if="contact.address.indexOf('서울') > -1">
<td>{{index+1}}</td>
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
<td>{{contact.address}}</td>
</tr>
</tbody>
<tbody id="contacts">
<template v-for="(contact, index) in contacts">
<tr>
<td>{{index+1}}</td>
<td>{{contact.no}}</td>
<td>{{contact.name}}</td>
<td>{{contact.tel}}</td>
<td>{{contact.address}}</td>
</tr>
<tr class="divider" v-if="index % 5 === 4">
<td colspan="5"></td>
</tr>
</template>
</tbody>
객체에 적용
<body>
<div id="example">
<select id="regions">
<option disabled="disabled" selected >지역을 선택하세요</option>
<option v-for="(val, key) in regions" v-bind:value="key">{{ val }}</option>
</select>
</div>
<script type="text/javascript">
var model = {
regions: {
"A": "Asia",
"B": "America",
"C": "Europe",
"D": "Africa",
"E": "Oceania"
}
};
var simple1 = new Vue({
el: "#example",
data: model
});
</script>
</body>
<select id="regions">
<option disabled="disabled" selected >지역을 선택하세요</option>
<option v-for="(val, key, index) in regions" v-bind:value="key">
{{ index + 1 }} : {{ val }}
</option>
</select>
v-pre
- 컴파일 하지 않고 문자열을 그대로 출력
<body>
<div id="example">
<span v-pre>{{message}}</span>
</div>
<script type="text/javascript">
var model = {
message: 'Hello World'
};
var simple1 = new Vue({
el: "#example",
data: model
});
</script>
</body>
v-once
- HTML 요소를 단 한번만 렌더링하도록 설정
<div id="example">
<span v-once>{{message}}</span>
</div>
v-cloak
- 콧수염 표현식이 일시적으로 나타나는 경우가 있는데 v-cloak 디렉티브는 초기에 컴파일 하지 않은 디렉티브는 나타나지 않도록 할 수 있음
계산형 속성
<body>
<div id="example">
<input type="text" v-model="num">
<br /> 1부터 입력된 수까지의 합 : <span>{{sum}}</span>
</div>
<script type="text/javascript">
var model = {
num: 0
};
var simple1 = new Vue({
el: "#example",
data: model,
computed: {
sum: function() {
var n = Number(this.num)
if (Number.isNaN(n) || n < 1) return 0;
return ((1 + n) * n) / 2;
}
}
});
</script>
</body>
- v-model 디렉티브로 양방향 바인딩을 사용할 경우 한글 입력시에는 엔터키를 눌러야 바인딩이 일어나는 문제
- v-bind:value 디렉티브와 v-on:input 이벤트 디렉티브를 이용 이를 해결
<!--
국가명 : <input type="text" v-model="countryname" placdholder="국가명" />
-->
국가명 : <input type="text" :value="countryname" placdholder="국가명"
@input="nameChanged" />
....
<tbody id="contacts">
<tr v-for="(c, index) in filtered">
<td>{{c.no}}</td>
<td>{{c.name}}</td>
<td>{{c.capital}}</td>
<td>{{c.region}}</td>
</tr>
</tbody>
....
<script>
var model = {
countryname : "",
countries : [
{ no : 1, name: "미국", capital : "워싱턴DC", region : "america"},
....
{ no : 16 name: "서사모아", capital : "아피아", region : "oceania"}
]
};
var clist = new Vue({
el : "#example",
data : model,
computed : {
filtered : function() {
var cname = this.countryname.trim();
return this.countries.filter(function(item, index) {
if(item.name.indexOf(cname) > -1 ) {
return true;
}
});
}
}
methods : {
nameChanged : function(e) {
this.countryname = e.target.value;
}
}
});
</script>