티스토리 뷰
이번 포스트는 v-if
와 v-show
를 이용하여 조건부 렌더링을 이야기 합니다.
1. v-if
v-if
디렉티브를 사용하여 조건부 렌더링을 사용할 수 있습니다.
<div id="app">
<h1 v-if="ok">Yes</h1>
</div>
new Vue({
el: '#app',
data: {
ok: true,
},
});
v-else
v-if
디렉티브는 v-else
디렉티브와 함께 사용 할 수 있습니다.
<div id="app">
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
</div>
new Vue({
el: '#app',
data: {
ok: true,
},
});
위의 예제는 CodePen에서 결과를 확인 할 수 있습니다.
v-else-if
v-else-if
디렉티브는 2.1.0에 추가되었습니다. 이름에서 알 수 있듯이 else if 블록 역할을 합니다.
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
new Vue({
el: '#app',
data: {
type: 'C',
},
});
v-else-if
는 v-if
또는 v-else-if
뒤에 사용할 수 있습니다. 위의 예제는 CodePen에서 결과를 확인 할 수 있습니다.
<template>
와 v-if
로 조건부 그룹 만들기
v-if
는 디렉티브이기 때문에 하나의 엘리먼트에 추가되어야 합니다. 그렇다면 여러개의 엘리먼트에 조건부 렌더링을 추가하기 위해서는 각각의 엘리먼트에 v-if
를 사용해야 할 것입니다. 하지만 HTML에 실제로 렌더링 되지 않는 태그인 <template>
를 사용하면 각각의 엘리먼트에 v-if
를 사용하지 않고 조건부 그룹을 만들어 조건부 렌더링을 사용 할 수 있습니다.
<div id="app">
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
new Vue({
el: '#app',
data: {
ok: true,
},
});
<template>
에는 v-if
를 사용할 수 있습니다. 또한 최종 렌더링 결과에는 <template>
엘리먼트가 포함되지 않습니다. 위의 예제는 CodePen에서 결과를 확인 할 수 있습니다.
key
를 이용하여 재사용 가능한 엘리먼트 제어
Vue는 효율적인 렌더링을 위해 때때로는 처음부터 렌더링하지 않고 기존의 엘리먼트를 다시 사용합니다.
<div id="app">
<div>
<template v-if="loginType === 'username'">
<label>사용자 이름</label>
<input placeholder="사용자 이름을 입력하세요">
</template>
<template v-else>
<label>이메일</label>
<input placeholder="이메일 주소를 입력하세요">
</template>
<button @click="changeLoginType">로그인 유형 변경</button>
</div>
</div>
new Vue({
el: '#app',
data: {
loginType: 'username',
},
methods: {
changeLoginType() {
if (this.loginType === 'username') {
this.loginType = 'email';
} else {
this.loginType = 'username'
}
}
}
});
위 코드에서 loginType
이 바뀌어도 사용자가 입력한 내용은 지워지지 않습니다. Vue는 엘리먼트를 재사용하여 <input>
자체가 대체되지 않고 placeholder
만 변경됩니다. 위의 코드는 CodePen에서 확인 할 수 있습니다.
엘리먼트를 재사용하지 않길 원한다면, key
속성을 사용하면 됩니다. 즉 key
속성을 사용하여 완전 별개의 엘리먼트인 것을 명시하면 Vue는 엘리먼트를 재사용하지 않고 완전히 대체하여 렌더링 합니다.
<div id="app">
<div>
<template v-if="loginType === 'username'">
<label>사용자 이름</label>
<input placeholder="사용자 이름을 입력하세요" key="username-input">
</template>
<template v-else>
<label>이메일</label>
<input placeholder="이메일 주소를 입력하세요" key="email-input">
</template>
<button @click="changeLoginType">로그인 유형 변경</button>
</div>
</div>
new Vue({
el: '#app',
data: {
loginType: 'username',
},
methods: {
changeLoginType() {
if (this.loginType === 'username') {
this.loginType = 'email';
} else {
this.loginType = 'username'
}
}
}
});
<label>
엘리먼트는 key
속성이 없기 때문에 엘리먼트를 재사용합니다. <input>
엘리먼트는 속성을 사용하여 완전히 대체하여 렌더링합니다. 위의 예제는 CodePen에서 확인 할 수 있습니다.
2. v-show
v-show
디렉티브를 사용하여 조건부 렌더링을 사용할 수도 있습니다. 사용법은 v-if
와 유사합니다.
<div id="app">
<h1 v-show="ok">Yes</h1>
</div>
new Vue({
el: '#app',
data: {
ok: true,
},
});
v-show
는 DOM에 항상 그려집니다. v-show
에 false
가 넘겨지면 display:none
이 되어 DOM에는 있지만 화면에 나타나지 않는 상태가 됩니다. v-show
는 <template>
를 지원하지 않습니다.
v-if
VS v-show
v-if
디렉티브를 사용한 엘리먼트의 이벤트 리스너와 자식 컴포넌트들이 DOM에 제거되거나 삽입되는 진짜 조건부 렌더링입니다. 반면 v-show
는 DOM에 항상 삽입되고 display
style을 통해 화면에 그려지거나 그려지지 않는 조건부 렌더링입니다.
v-if
는 토글 비용(화면에 그려지거나 그려지지 않는데 사용되는 비용)이 높고, 초기 렌더링 비용이 낮습니다. 반면 v-show
는 토글 비용이 낮고 초기 렌더링 비용이 높습니다. 그렇기 때문에 자주 변하는 컴포넌트에 조건부 렌더링을 사용해야 한다면 v-show
를 사용하는 것이 좋습니다. 런타임 시 조건이 바뀌지 않다면 v-if
를 사용하는 것이 좋습니다.
v-if
와 v-for
v-for
디렉티브에 관련 내용은 이 후의 포스트에서 더 자세히 이야기 하도록 하겠습니다.
v-if
와 v-for
을 함께 사용한다면, v-for
가 더 높은 우선순위를 가집니다. 즉 v-for
로 리스트 렌더링을 하면서 각각의 리스트는 v-if
조건에 걸리게 됩니다.
참고
'Vue.JS' 카테고리의 다른 글
[Vue.JS] 이벤트 핸들링 (0) | 2018.12.06 |
---|---|
[Vue.JS] 리스트 렌더링 (0) | 2018.11.25 |
[Vue.JS] 클래스와 스타일 바인딩 (0) | 2018.11.13 |
[Vue.JS] computed와 watch (0) | 2018.10.31 |
[Vue.JS] 템플릿 문법 (0) | 2018.10.23 |