[Vue] 조건부 렌더링

youngseo·2022년 5월 1일
post-thumbnail

한 번에 끝내는 프론트엔드 개발 초격차 패키지 Online를 들으며 정리한 내용입니다.

조건부렌더링

vue3 시작하기

Vue.js에서는 v-if , v-else-if, v-else 디렉티브를 이용하여, 특정한 데이터를 기준으로 화면에 렌더링이 되는 내용을 바꿔줄 수 있습니다.

1. V-if

v-if 디렉티브는 조건에 따라 블록을 렌더링할 때 사용합니다. 블록은 디렉티브의 표현식이 true 값을 반환할 때만 렌더링됩니다. v-else와 함께 “else 블록”을 추가하는 것도 가능합니다.

<h1 v-if="awesome">Vue is awesome!</h1>

<!-- v-if 와 v-else사용-->
<h1 v-if="awesome">Vue is awesome!</h1> 
<h1 v-else>Oh no 😢</h1>

아래는 버튼을 누르면 HEllo?!대신 Good~이 나타나고 다시 누르면 Hello?!가 나타나는 v-if 디렉티브를 사용한 예시입니다.

마치 자바스크립트의 if조건문과 같습니다. 자바스크립트의 if가 v-if디렉티브, else if가 v-esle-if디렉티브, else가 v-else디렉티브라고 생각하면 이해하기가 조금 더 쉽습니다.

v-if실습 (클릭 이벤트)

<template>
  <button @click="handler">
    Click me!
  </button>
  <h1 v-if="isShow">
    Hello?!
  </h1>
  <h1 v-else>
    Good~
  </h1>
</template>
<script>
export default {
  data() {
    return {
      isShow: true
    }
  },
  methods: {
    handler() {
      this.isShow = !this.isShow //true인 경우 false할당, false인 경우 true할당
    }
  }
}
</script>

스스로 실습(토글)

<template>
  <ul class="item__list">
    <li class="item">
      로그인
    </li>
    <li class="item<">
      회원가입
    </li>
    <li class="item">
      고객센터
    </li>
    <button 
      @click="handler">
      Global
    </button>
    <ul
      v-if="isShow"
      class="global__list">
      <li class="list">
        영어
      </li>
      <li class="list">
        한국어
      </li>
    </ul>
  </ul>
</template>
<script>
export default {
  data() {
    return {
      isShow: false
    }
  },
  methods: {
    handler() {
      this.isShow = !this.isShow
    }
  }
}
</script>
<style lang="scss" scoped>
  .item__list {
    display: flex;
    position: relative;
    width: 400px;
    height: 20px;
    justify-content: space-between;
    align-items: center;
    .item {
      padding-right: 10px;
    }
    .global__list {
       position: absolute;
       top: 20px;
       right: 0;
       border: 1px solid gray;
      .list {
        padding: 10px;
      }
    }
  }
</style>

2. 조건부 그룹

<template>에 v-if를 갖는 조건부 그룹 만들기

v-if는 디렉티브이기 때문에 하나의 엘리먼트에 추가되어야 합니다. 하지만 아래와 같이 h1태그와 두개의 p태그, 둘 이상의 엘리먼트를 전환하려면 어떻게 해야 할까요? 이런 경우, v-if를 <template> 엘리먼트에 사용할 수 있습니다.

<template>
  <button @click="handler">
    Click me!
  </button>
  <template v-if="isShow">
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
  </template>
</template>

그렇다면 template 태그에 v-if를 사용하는 것과 임의의 div태그를 만들어 h1태그와 두개의 p태그를 감싸는 것과 어떠한 차이가 있을까요?

<template v-if="isShow">  //template이 아니라 div태그를 쓰면 어떻게 될까?
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</template>

개발자 도구를 열어 확인을 해보면, div태그로 감싸는 경우 화면에 div가 출력되고 있지만 template로 감싼 경우 화면에 따로 template태그가 출력되지 않는 것을 확인할 수 있습니다. 즉 <template> 엘리먼트는 눈에 보이지 않게 내부 엘리먼트를 감싸는 역할(invisible wrapper)을 하며, 최종 렌더링 결과에 포함되지 않습니다.

단, 주의해야할 부분은 최상위 template에 v-if를 붙이는 경우 적용되지가 않으니, 최상위 template에는 v-if를 사용해서는 안됩니다.

3. v-show

엘리먼트를 조건에 따라 표시하기 위한 또 다른 방법으로 v-show 디렉티브가 있습니다. 사용 방법은 거의 동일합니다.

<h1 v-show="ok">Hello!</h1>

그렇다면 v-if와 v-show는 어떠한 차이가 있을까요? 아래는 화면에 출력된 button을 눌러 값이 false가 된 후의 v-if와 v-show의 차이를 개발도구로 확인한 예시입니다.


이처럼 v-show를 쓴 엘리먼트의 경우, 값이 false가 된 후에도 항상 렌더링 되어 DOM에 남아있다는 점에서 큰 차이가 있습니다. v-show는 단순히 엘리먼트의 CSS display 속성만을 전환합니다.

v-show는 <template> 엘리먼트를 지원하지 않으며, v-else와 함께 쓸 수 없습니다

4. v-if 대 v-show

v-if는 "실제(real)" 조건부 렌더링입니다. 초기 렌더링 시, 조건이 거짓(false)이면 아무 작업도 하지 않으며 조건부 블록은 조건이 처음으로 참(true)이 될 때까지 렌더링되지 않습니다.

이에 비해 v-show는 훨씬 간단합니다. 엘리먼트는 CSS 기반 전환으로 초기 조건과 관계 없이 항상 렌더링됩니다. (역자 주: v-show는 엘리먼트를 DOM에 우선 렌더링하고 조건에 따라 CSS display:block/display:none 속성을 전환합니다.)

일반적으로 v-if는 전환 비용이 높은 반면, v-show는 초기 렌더링 비용이 높습니다. 그러므로 무언가를 자주 전환해야 한다면 v-show를 사용하는 게 좋고, 런타임 시 조건이 변경되지 않는다면 v-if를 사용하는 게 더 낫습니다

추천 방법은 처음에는 v-if를 사용하고 실제로 서비스를 진행하면서 전환 비용이 많이 들어간다면, v-show로 바꾸어 사용하시면 됩니다.

0개의 댓글