Computed Property (계산형 속성)


앞서 v-bind 디렉티브를 이용한 간단한 데이터 바인딩 방법을 설명했는데 만약 연산 로직이 필요한 경우에는 이 방법만으로는 문제를 해결하기가 쉽지 않다.


Vue.js의 Computed Property(계산형 속성)은 이러한 문제를 해결해주는 방법 중의 하나이다.  Vue 객체를 만들때 computed 속성과 함께 함수를 등록해두면 마치 속성처럼 이용할 수 있다.


<body>
<div id="exmaple">
<input type="text" v-model="num" /><br/>
1부터 입력된 수까지의 합 : <span>{{ sum }}</span>
</div>
<script tpye="text/javascript">
var vmSum = new Vue({
el: '#exmaple',
data: {
num: 0
},
computed: {
sum: function() {
var n = Number(this.num)
if (Number.isNaN(n) || n < 1)
return 0;
return ((1 + n) * n) / 2;
}
}
})
</script>
</body>


위의 소스에서 주의할점이 있는데 바로 this.값이다. 함수 안에서의 this는 vue 객체 자신을 참조한다. 그런데 함수 내부에서 다른 콜백함수를 실행하거나 했을 때는 this가 다른 값으로 연결 될 수 있으므로 주의 해야한다. num 값이 number 타입이라 생각하기 슂미나 html 요소 내부에서는 모두 문자열로 다뤄진다. 그렇기 때문에 Number() 함수나 parseInt() 함수를 이용해 명시적으로 숫자값으로 변환해야한다.



<body>
<div id="exmaple">
<p>
국가명 : <input type="text" v-model="countryname"
placeholder="국가명" />
</p>
<table id="list">
<thead>
<tr>
<th>번호</th>
<th>국가명</th>
<th>수도</th>
<th>지역</th>
</tr>
</thead>
<tbody id="contacts">
<tr v-for="c in filtered">
<td>{{ c.no }}</td>
<td>{{ c.name }}</td>
<td>{{ c.capital }}</td>
<td>{{ c.region }}</td>
</tr>
</tbody>
</table>
</div>
<script tpye="text/javascript">
var model = {
countryname: "",
countries: [{
no: 1,
name: "미국",
capital: "워싱턴 DC",
region: "america"
}, {
no: 2,
name: "프랑스",
capital: "워싱턴 DC",
region: "europe"
}, {
no: 3,
name: "영국",
capital: "워싱턴 DC",
region: "europe"
}, {
no: 4,
name: "중국",
capital: "워싱턴 DC",
region: "asia"
}, {
no: 5,
name: "태국",
capital: "워싱턴 DC",
region: "asia"
}, {
no: 6,
name: "모로코",
capital: "워싱턴 DC",
region: "africa"
}, {
no: 7,
name: "라오스",
capital: "워싱턴 DC",
region: "asia"
}, {
no: 8,
name: "베트남",
capital: "워싱턴 DC",
region: "asia"
}, {
no: 9,
name: "피지",
capital: "워싱턴 DC",
region: "oceania"
}, {
no: 10,
name: "자메이카",
capital: "워싱턴 DC",
region: "oceania"
}, {
no: 11,
name: "솔로몬제도",
capital: "워싱턴 DC",
region: "america"
}, {
no: 12,
name: "나미비아",
capital: "워싱턴 DC",
region: "africa"
}, {
no: 13,
name: "동티모르",
capital: "워싱턴 DC",
region: "asia"
}, {
no: 14,
name: "멕시코",
capital: "워싱턴 DC",
region: "america"
}, {
no: 15,
name: "베네수엘라",
capital: "워싱턴 DC",
region: "america"
}, {
no: 16,
name: "서사모아",
capital: "워싱턴 DC",
region: "oceania"
}, ]
}
var vmSum = new Vue({
el: '#exmaple',
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;
}
})
}
}
})
</script>
</body>







배열의 filter 메서드는 배열의 아이템 중 조건을 만족하는 아이템을 모아서 새로운 배열을 만들어 리턴하는 기능을 수행한다. filter 메서드는 함수를 인자로 전달하고 이 함수는 다시 두 개의 인자를 전달 받는데, 첫 번째 인자가 배열의 아이템(item) 두번째가 인덱스 번호이다.


계산형 속성인 filtered 함수는 this.countryname 속성값을 cname 변수에 할당하고 있다. 그 이유는 배열 객체의 filter 함수에 의해 호출되는 콜백함수 안에서는 this는 바깥쪽의 this와 다르기 때문이다. 콜백 함수 안쪽의 this는 Vue객체가 아니고 전역 객체를 참조한다. 


텍스트 필드에 국가명의 일부를 입력하면 필터링된 결과가 나타난다. 새롭게 렌더링되는 것이기 때문에 display 스타일 속성을 none으로 지정해서 보이지 않도록 하는 것과는 전혀 다르다. 

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

[Vue.js] Event 처리  (0) 2018.12.17
[Vue.js] Vue instance (뷰 인스턴스)  (0) 2018.12.16
[Vue.js] 기본 디렉티브  (0) 2018.12.15
vue.js 구조  (0) 2018.12.15
[Vue.js] 개발환경 구축  (1) 2018.12.15

+ Recent posts