Vue.js 기본 디렉티브



1) v-text, v-html 디렉티브

선언적 렌더링을 위해 html 요소 내부에 템플릿 표현식(콧수염 표현식:mustache Expression)만  사용할 수 있는건 아니다. 동일한 코드를 디렉티브라는 것을 이용해 표현해볼 수 있다.


<div id="simple">
<h2 v-text="message"></h2>
</div>



v-test, {{ }} : InnerText 속성에 연결된다. 태그 문자열을 HTML 인코딩하여 나타내기 때문에 화면에는 태그 문자열이 그대로 나타남

v-html : innerHtml 속성에 연결된. 태그 문자열을 파싱하여 화면에 나타냄


v-html 태그는 <Script> 태그 그대로 바인딩한다. 요즘 문제가되는 XSS(Cross Site Scripting)공격 등에 취약하기 때문에 꼭 필요한 경우가 아니라면 v-text를 사용하는것이 더 안전하다.




2) v-bind 디렉티브

이번에는 v-bind 디렉티브는 요소(Element)의 콘텐트 영역(시작 태그와 종료 태그 사이의 영역)을 설정하는 것이 아닌 요소 객체의 속성들을 바인딩하기 위해 사용한다. 


<body>
<div id="simple">
<input id="a" type="text" v-bind:value="message">
<br/>
<img v-bind:src="imagePath" />
</div>
<script tpye="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-bind 디렉티브를 통해서 html요소 객체의 속성이 변경되었음을 알 수 있다. v-bind 디렉티브를 매번 작성하는 것이 부담스럽다면 줄여 쓰는 방법이 있다. v-bind:src를 줄여 쓰면 :src로 작성해도 동작한다.




3) v-model 디렉티브


앞에 설명한 디렉티브는 모두 단방향 디렉티브이다. HTML 요소에서 값을 변경하더라도 모델 객체의 값이 바뀌지 않는데 v-model 디렉티브는 양방향 데이터 바인딩을 지원하는 디렉티브이다. 


<body>
<div id="simple">
<input id="a" type="text" v-model="name" placeholder="이름 입력하세요">
<br/> 입력된 이름 :
<h2 v-html="name"></h2>
</div>
<script tpye="text/javascript">
var simple = new Vue({
el: '#simple',
data: {
name: ''
},
})
</script>
</body>


실행 하여 텍스트박스에 이름을 입력하면 H2 태그 모델 객체의 속성이 변경되는걸 확인 할 수 있다.

v-model 디렉티브는 텍스트 박스뿐만 아니라 여러 가지 폼 필드에서도 사용할 수 있다. 여러개의 아이템을 선택할 수 있는 <input type="checkbox"/>나 <select multiple></select>의 경우 모델 객체의 배열 객체와 연결된다. 단일 아이템을 선택할 수 있는 <input type="radio">나 <select/>인 경우에는 모델 객체의 단일 값과 연결된다.




<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 tpye="text/javascript">
var model = {
fruits: []
}

var simple1 = new Vue({
el: '#simple1',
data: model
})

var simple2 = new Vue({
el: '#simple2',
data: model
})
</script>
</body>




위의 예제는 하나의 Model 객체를 두 개의 Vue 객체에서 참조하는 예제이다. simple1이 바인딩하는 Vue 객체는 v-model을 이용해 양방향 데이터 바인딩하여 사용자가 입력하는 값을 뮤모델 개체를 통해 model 객체의 fruits 배열 값을 즉시 바인딩한다. 


v-model 디렉티브는 몇가지 수식어(Modifier)를 지원한다. 수식어는 디렉티브에 특별한 기능을 추가하는 Vue.js 디렉티브의 문법 요소이다. v-model에서 사용할 수 있는 수식어는 아래와 같다.


lazy : 입력폼에 이벤트가 발생할 때 입력한 값을 데이터와 동기화한다. 텍스트 박스에서 입력 후 포커스가 이동하거나 할 때 데이터 옵션값이 변경된다.  <input type="text" v-model.lazy="name"


number : 숫자가 입력될 경우 number 타입의 값으로 자동 현변환된다.


trim : 이 수식어를 지정하면 문자열의 앞뒤 공백을 자동으로 제거한다.




4) v-show, v-if, v-else, v-else-if 디렉티브

v-if 디렉티브는 Vue객체의 data 속성 값에 따라 렌더링 여부를 결정할 수 있는 기능이다. 다른 랭귀지에서도 쓰이는 if문과 동일한 개념으로 생각해도 된다.


v-if와 비슷한 기능을 가진것이 v-show 디렉티브이다. 사실 v-if와 v-show 차이는 실제 렌더링 여부에 있다. v-if 디렉티브는 조건에 부함되지 않으면 렌더링을 하지 않는 반면 v-show는 일단 html 요소를 렌더링 후에 display 스타일 속성으로 화면에 보여줄지 여부를 결정한다.


sample.bmaster.kro.kr/img/error.png에서 이미지를 다운로드 후 작업하는 폴더에 images 하위 폴더를 생성 후 저장한다.



<body>
<div id="account">
예금액 : <input type="text" v-model="amount" />
<img v-if="amount < 0 " src="images/error.png"
title="마이너스는 허용하지 않음"
style="width:15px; height:15px; vertical-align:middle">
</div>
<hr/>
<script tpye="text/javascript">
var simple1 = new Vue({
el: '#account',
data: {
amount: 0
}
})
</script>
</body>


v-if는 조건에 부합되지 않으면 렌더링을 하지 않는다. 그렇기 때문에 자주 화면이 변경되는 부분에 대해서는 v-if 디렉티브보다는 v-show 디렉티브를 사용하는 것이 더 바람직한다. v-show 디렉티브는 조건을 만족하지 않을때 display 스타일 속성을 none으로 설정해 화면에 보이지 않도록 처리한다. 실제로는 렌더링을 하는 것.


v-if, v-else, v-else-if 는 다른 언어에서의 if ~ else if ~ else 구문과 동일한 기능이라고 생각하면 된다.

<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>
<hr/>
<script tpye="text/javascript">
var simple1 = new Vue({
el: '#account',
data: {
balance: 0
}
})
</script>
</body>





5) v-for 디렉티브


JavaScript의 for문과 유사하다.


<html>
<head>
<meta charset="utf-8">
<title>hello vue.js</title>
<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>
<script src="http://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>

<body>
<div id="exmaple">
<table id="list">
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
<th>주소</tr>
</tr>
<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 tpye="text/javascript">
var model = {
"pageno": 1,
"pagesize": 10,
"totalcount": 100,
"contacts": [{
"no": 100,
"name": "설현",
"tel": "010-1234-1234",
"address": "서울"
}, {
"no": 100,
"name": "혜리",
"tel": "010-1234-1234",
"address": "서울"
}, {
"no": 100,
"name": "하니",
"tel": "010-1234-1234",
"address": "경기"
}, {
"no": 100,
"name": "성소",
"tel": "010-1234-1234",
"address": "제주"
}, {
"no": 100,
"name": "설현",
"tel": "010-1234-1234",
"address": "서울"
}, {
"no": 100,
"name": "혜리",
"tel": "010-1234-1234",
"address": "서울"
}, {
"no": 100,
"name": "하니",
"tel": "010-1234-1234",
"address": "경기"
}, {
"no": 100,
"name": "성소",
"tel": "010-1234-1234",
"address": "제주"
}, {
"no": 100,
"name": "설현",
"tel": "010-1234-1234",
"address": "서울"
}, {
"no": 100,
"name": "혜리",
"tel": "010-1234-1234",
"address": "서울"
}]
}
var simple1 = new Vue({
el: '#exmaple',
data: model
})
</script>
</body>
</html>


model 객체 내부에는 contacts라는 이름의 배열 데이터를 가지고 있는데 이 데티러르 여러번 반복적으로 화면에 나타낸것이다. v-for 의 구문은 원본 데이터가 어떤 형식인가에 따라 사용방법이 조금씩 달라진다ㅣ 배열 또는 유사 배열인 경우에는 contact.name 처럼 작성한다. 


원본 데이터가 객체 인경우에는 조금 달라진다. 객체인 경우는 키를 이용해 값을 접근하는 HashMap 구조 이기 때문에 Key, Value를 얻어낼 수 있는 구조를 사용한다.


<body>
<div id="exmaple">
<select id="regions">
<option disabled="disabled" selected> 지역을 선택하세요 </option>
<option v-for="(val, key) in regions" v-bind:value="key">{{val}}</option>
</select>
</div>
<script tpye="text/javascript">
var regions = {
"A": "Asia",
"B": "America",
"C": "Europe",
"D": "Africa",
"E": "Oceania",
}
var simple1 = new Vue({
el: '#exmaple',
data: {
regions: regions
}
})
</script>
</body>


이번 예제의 v-for 형태는 조금 다른 것을 확인 할 수 있다. (val, key)로 작성되어 있는데 var에는 텍스트가 전달되고, key에는 지역코드가 전달되면서 반복적으로 <option>요소들을 만들어 낸다.


만일 인덱스를 표현해야 한다면 다음과 같이 표현할 수 있다.


<tr v-for="(contact, index) in contacts"> ... </tr>

<option v-for="(val, key, index) in regions" ...> </option>





6) 기타 디렉티브


v-pre -> v-pre는 HTML요소에 대한 컴파일을 수행하지 않는다.


<body>
<div id="exmaple">
<span v-pre>{{ message }}</span>
</div>
<script tpye="text/javascript">
var simple1 = new Vue({
el: '#exmaple',
data: {
message: "Hello World"
}
})
</script>
</body>


위의 예제는 v-pre 디렉티브를 사용한 예제이다. 실제 실행을 해보면 Hello World 문자열이 찍히지 않고 콧수염 표현식 그대로 {{ message }}가 화면에 출력된 모습을 볼 수 있다. 앞서 설명한것 처럼 v-pre는 HTML 요소에 대한 컴파일을 수행하지 않는다.



v-once-> v-once는 HTML요소를 단 한 번만 렌더링하도록 설정한다.


<body>
<div id="exmaple">
<span v-once>{{ message }}</span>
</div>
<script tpye="text/javascript">
var simple1 = new Vue({
el: '#exmaple',
data: {
message: "Hello World"
}
})
</script>
</body>


실제로 실행을 하면 v-pre와는 다르게 Hello World가 찍힌 모습을 확인 할 수있다. v-once 디렉티브는 처음 한번만 렌더링을 수행한다. 그렇기 때문에 Vue 인스턴스의 데이터를 변경하더라도 렌더링을 수행하지 않는다. 초깃값이 주어지면 변경되지 안는 UI를 만들때 사용할 수 있다.

'Vue.js' 카테고리의 다른 글

[Vue.js] Event 처리  (0) 2018.12.17
[Vue.js] Vue instance (뷰 인스턴스)  (0) 2018.12.16
[Vue.js] computed Property (계산형 속성)  (0) 2018.12.15
[Vue.js] 기본 디렉티브  (0) 2018.12.15
vue.js 구조  (0) 2018.12.15
[Vue.js] 개발환경 구축  (0) 2018.12.15
Posted by 루우지