본문 바로가기

Front-end/Vue

Vue.js) 조건부 렌더링

1. 조건부 렌더링

Vue.js에서는 디렉티브 v-if, v-else-if, v-else, v-show를 사용하여 조건에 맞게 렌더링을 할 수 있습니다. 이 기능들은 보다 동적이고 유연한 웹 애플리케이션을 구현할 수 있게 해 줍니다.

 

2. 사용 예제

  • v-if
<template>
	<h3>현재 값: {{ val }} / 기준 값: {{ avgVal }}</h3>
	<h3 v-if="isBig">{{ val }}은 {{ avgVal }}보다 큽니다.</h3>           <!-- val > avgVal -->
	<h3 v-else-if="isSmall">{{ val }}은 {{ avgVal }}보다 작습니다.</h3>  <!-- val < avgVal -->
	<h3 v-else>{{ val }}은 {{ avgVal }}와 같습니다.</h3>                 <!-- val = avgVal -->
	<button v-on:click="increaseVal">+</button>
	<button v-on:click="decreaseVal">-</button>
</template>

<script>
export default {
	data() {
		return {
			val: 0,
			avgVal: 4,			
		};
	},
	computed: {
		isBig() {
			return this.val > this.avgVal;
		},
		isSmall() {
			return this.val < this.avgVal;
		},
	},
	methods: {
		increaseVal() {
			this.val += 1;			
		},
		decreaseVal() {
			this.val = this.val == 0 ? 0 : this.val - 1;	
		},
	},
};
</script>

위 코드는 + 버튼을 누르면 val 증가하고 - 버튼을 누르면 val이 감소합니다. val이 증가, 감소됨에 따라 avgVal과 비교를 통해 값이 큰지, 같은지, 작은지 비교 후에 조건에 맞는 문구를 보여줍니다. 

 

  • v-show
<template>
	<h3>현재 값: {{ val }} / 기준 값: {{ avgVal }}</h3>
	<h3 v-if="isBig">{{ val }}은 {{ avgVal }}보다 큽니다.</h3>
	<h3 v-else-if="isSmall">{{ val }}은 {{ avgVal }}보다 작습니다.</h3>
	<h3 v-else>{{ val }}은 {{ avgVal }}와 같습니다.</h3>
	<div v-show="isShow">
		<div>v-show</div>
		<p>토글입니다.</p>
	</div>
	<button v-on:click="increaseVal">+</button>
	<button v-on:click="decreaseVal">-</button>
</template>

<script>
export default {
	data() {
		return {
			val: 0,
			avgVal: 4,
			isShow: false,
		};
	},
	computed: {
		isBig() {
			return this.val > this.avgVal;
		},
		isSmall() {
			return this.val < this.avgVal;
		},
	},
	methods: {
		increaseVal() {
			this.val += 1;
			this.isShow = this.isBig;
		},
		decreaseVal() {
			this.val = this.val == 0 ? 0 : this.val - 1;
			this.isShow = this.isBig;
		},
	},
};
</script>

val이 avgVal보다 클 때 "v-show 토글입니다." 문구가 노출되는 코드입니다.

 

3. v-if와 v-show

v-if와 v-show는 사용법은 거의 동일하나 v-show는 v-if와 다르게 해당 엘리먼트가 항상 렌더링 되고 DOM에 남아있습니다. 아래 예제 코드로 확인해 보겠습니다.

 

<template>
	...
	<div v-if="isShow">
		<div>v-if</div>
		<p>토글입니다.</p>
	</div>
	<template v-if="isShow">
		<div>v-if</div>
		<p>토글입니다.</p>
	</template>
	<div v-show="isShow">
		<div>v-show</div>
		<p>토글입니다.</p>
	</div>
	...
</template>

<script>
export default {
	...
};
</script>

 

해당 엘리먼트가 노출되기 전 개발자 모드로 HTML 구성을 보면 v-if를 사용한 것은 모두 주석 처리로 표시되어 있는 반면에 v-show를 사용한 엘리먼트는 이미 렌더링 되어있고 css 속성이 display: none으로 되어있는 것을 알 수 있습니다. 

모든 엘리먼트가 노출되고 HTML 구성을 확인해 보면 주석처리 되어있던 v-if가 엘리먼트가 생성되었고 이미 렌더링 되었던 v-show를 사용한 엘리먼트는 css display 속성이 사라졌음을 확인할 수 있습니다.

 

v-if 같은 경우 어떤 조건에 따라서 실제로 구조적인 렌더링이 되거나 혹은 진짜로 사라지거나 하기 때문에 전환 비용이 높고 v-show 같은 경우에는 단순하게 css 디스플레이 속성의 값만 제어를 하는 것이기 때문에 초기 렌더링 비용이 높습니다. 

따라서 무언가를 자주 전환해야 한다면 v-show를 사용하는 게 좋고, 화면이 동작하고 있을 때 적용해 놓은 데이터의 조건이 자주 변경이 되지 않는다면 v-if를 사용하는 것이 좋습니다. 

 

* template와 v-if

위 사진처럼 template으로 감싼 엘리먼트들은 template태그 안에 요소들만 보입니다. 따라서 하나 이상의 엘리먼트를 전환하기 위해선 template 태그를 쓰는 게 좋습니다. 

* v-show 디렉티브는 template 태그 안에서 사용할 수 없습니다.

 

관련 문서:

https://v2.ko.vuejs.org/v2/guide/conditional.html

'Front-end > Vue' 카테고리의 다른 글

Vue.js) 이벤트 핸들링  (0) 2024.07.26
Vue.js) 리스트 렌더링  (0) 2024.07.25
Vue.js) 클래스와 스타일 바인딩  (0) 2024.07.25
Vue.js) Watch  (0) 2024.07.24
Vue.js) Getter, Setter  (1) 2024.07.24