Vue 2 | 조건 분기 및 산출 속성
조건에 따라 요소나 특성 등의 내용을 표시/숨기기로 전환하려면 v-show
v-if
지시자 속성을 사용한다.
- Vue 2.5.4
v-show와 v-if의 차이
둘 사이의 차이는 v-show
는 CSS에서 display : none
으로 단순히 화면에서만 숨길 수 있는 반면 v-if
는 DOM 레벨로 존재를 삭제한다.
표시와 숨기기를 여러번 전환하는 경우는 v-show
를 사용하는 것이 성능으로 좋다. 그러나 v-show
보이지 않아도 내부는 계속 상황을 모니터링하고 있다.
내부 데이터가 많거나 특정 객체를 가지고 있지 않으면 오류가 발생하는 등 단순히 숨겨져 있는 상태에서 처리를 시키고 싶지 않은 경우는 v-if
를 사용하면 좋다.
목록에 특정 조건을 만족하는 데이터만 표시
다음 데이터를 사용하여 입력한 수치 이하의 제품만 표시하도록 싶다.
new Vue({
el: '#app',
data: {
price: 300,
inputprice: 200,
list: [{
name: '토마토',
price: 100
}, {
name: '상추',
price: 200
}, {
name: '오이',
price: 300
}]
}
})
작성법은 v-show
도 v-if
도 동일하게 다음과 같다.
<li v-for="val in list" v-show="조건식">조건을 만족하는 조건을 만족하면 표시된다.</li>
조건식 부분에는 JavaScript의 if문 괄호 안에 쓰는 것과 같은 식을 넣는다. 메소드명이라면 부울 값을 나타내는 데이터를 전달하면 된다.
<ul>
<!-- val.price가 입력된 price 보다도 작다면 표시 -->
<li v-for="val in list" v-show="val.price <= price">
{{ val.name }} {{ val.price }} 원
</li>
</ul>
<input v-model.number="inputprice" size="5"> 원 이하의 상품 표시보기
<!-- 버튼을 누르면 price가 갱신되고 동시에 결과도 갱신된다. -->
<button @click="price = inputprice">click!</button>
v-model에 연결되어 있는 inputprice 값을 사용하면 실시간으로 검색되지만, 이번에는 버튼을 누른 타이밍에서 검색하려고 했기에 price라는 데이터 입력 값을 대입하여 그것을 조건으로 사용하도록 했다.
숫자를 입력하고 클릭하면 그 이하의 가격의 상품만 표시가 되었다. 실제로는 숫자 외에 값이 입력된 경우의 처리가 필요하지만 실시간 필터링이 되는 간단히 가능한 기능만 확인하도록 하자.
덧붙여서 v-model에는 입력 값을 숫자로 변환시키는 수식어(.number)도 포함되어 있다.
스타일과 클래스에 조건을 붙인다.
<ul>
<li v-for="val in list" v-show="!price || val.price <= price">
{{ val.name }} <span v-bind:style="{color: val.price <= 200 ? 'red' : 'blue'}">{{ val.price }}원</span>
</li>
</ul>
위의 예에서는 가격이 200원 이하면 빨간색하도록 했다. style과 class는 값이 여러 개가 있을 수 있기 때문에 v-bind에는 객체 형식으로 각각에 조건을 붙일 수 있다. v-bind를 사용하지 않고 일반적으로 작성하는 style과 class가 있을 경우 병합(merge)된 결과가 표시된다.
<span :style="{ color: colorValue }">텍스트</span>
<span :class="{ active: price < 200 }">텍스트</span>
colorValue
에는 수식 및 부울 값에 데이터를 쓴다. 객체 또는 가공된 문자열 데이터를 넘겨도 된다.
<span :style="styleObject">텍스트</span>
계산 속성 사용하기
그런데, 여기에 동시에 “X건을 찾았습니다"나 “아무것도 찾을 수 없습니다"와 같은 표시도 하고 싶은데, 최종적으로 검색한 데이터 개수를 어떻게 얻는 것이 좋을까? 공식 가이드를 보면 “계산된 속성"이라는 것이 있다. 데이터를 검색할 때에 처리할 수 있는 기능으로써 이를 사용한다면 가능할 것이다!
계산된 속성은 무엇인가 처리를 한 결과를 데이터 값으로 반환할 수 있다. 위의 예와 다른 점은 v-for
에 전달된 시점에 이미 조건을 만족한 것만이 배열로 되어 있다는 것이다. 문자를 덧붙이거나, 불필요한 것을 제거하거나, 지금 가지고 있는 데이터로 부터 새로운 데이터를 만들거나 여러가지가 가능하다. methods
와 같이 computed
라는 옵션에 함수를 정의한다. 함수로 정의하고 있지만, 사용 방법은 그 이름과 같이 속성으로 사용한다.
new Vue({
el: '#app',
data: {
price: 300,
inputprice: 200,
list: [{
name: '토마토',
price: 100
}, {
name: '상추',
price: 200
}, {
name: '오이',
price: 300
}]
},
computed: {
matchList: function() {
console.log('matchList') // 테스트이므로 실행했을 때 로그를 남긴다.
// 필터를 사용하여 price보다 작은 것만 배열을 만들어 반환한다.
return this.list.filter(function(val) {
return val.price <= this.price
}, this)
}
}
})
matchList라는 이름으로 간단한 계산된 속성을 만들어 보았다.
<ul>
<li v-for="val in matchList">
{{ val.name }} {{ val.price }} 원
</li>
<li v-if="!matchList.length">
해당하는 상품이 없습니다.
</li>
</ul>
<input v-model.number="inputprice" size="5"> 원 이하의 상품 표시보기
<button @click="price = inputprice">click!</button>
{{ matchList.length }} 개를 찾았습니다.
계산된 속성에서 먼저 처리하고 결과의 length를 보면 검색된 수를 알 수 있다!
matchList을 3곳에서 사용하고 있기 때문에, 그 때마다 함수가 실행되는 있을까 하고 불안하여 console.log을 넣어 보니 한 번만 실행되었다. 계산된 속성은 그 속에서 사용하는 데이터에 변화가 있을 때까지 캐시되는 것 같다. 멋지지 않은가? 그럼 method를 사용에 이득이 있다는 것이다.
계산된 속성은 종속 관계에 의거 캐시된다는 차이가 있다.
즉, 종속 데이터에 변화가 있으면 계산된 속성도 동기화 해 버리므로, 변화되어도 즉시 표시를 갱신하고 싶지 않거나, 어떤 조건에 새로운 데이터를 만들고 싶을 때에는 다른 글에서작성 있는 watch를 사용하는 것이 좋다.
v-if / v-else-if / v-else으로 여러 조건을 설정
v-if
와 함께 v-else-if, v-else 지시어를 사용할 수 있다. 반드시 조건 요소 바로 뒤에 두도록 하여 사용한다.
<div v-if="조건A">조건A</div>
<div v-else-if="조건B">조건B</div>
<div v-else>일치되지 않는다.</div>
결론
응용 프로그램을 만들려면 조건 분기는 필수이다. 계산된 속성은 굉장히 편리하다! 상황에 따라 method로 사용을 알게 되면 좋을 것이다. 다음은 드디어 구성 요소에 대해 설명하겠다.