• Vue.js: 트랜지션(transition) 어떻게 사용하는가? :: 마이구미
    Vue.js 2018. 8. 3. 00:41

    이 글은 Vue.js 의 트랜지션(transition) 을 통해 애니메이션을 조작하는 법을 다룬다.

    Vue.js 는 공식 문서가 정말 이해하기 쉽게 설명하고 있다.

    그렇기에, 기본적인 내용은 자세히 다루지 않는다.

    기본적인 지식을 문서를 통해 확인한 후, 이 글을 실제 응용하는 방법을 목적으로 참고하길 바란다.

    글은 예제를 통해 진행된다.

    관련 예제 - https://kxk7j2vwr.codesandbox.io/

    공식 문서 - https://kr.vuejs.org/v2/guide/transitions.html


    트랜지션의 일반적인 정의는 DOM 의 삽입, 삭제, 갱신 등에 관련된 효과라고 볼 수 있다.

    이러한 효과는 페이지 단위에서는 싱글페이지(SPA) 활성화로 인해 페이지 전환에 따른 애니메이션을 많이 경험하거나 구현했을 것이다.

    요소 단위에서도 클릭, 존재여부 등과 같은 각 요소가 이벤트에 따른 애니메이션이 존재할 수 있다.

    Vue.js 의 트랜지션 시스템은 위와 같은 목적을 위해 편의를 제공한다.


    Vue.js 의 트랜지션을 정의하는 방법(tag)은 크게 2가지로 나타낸다.


    • <transition>
    • <transition-group>


    트랜지션 태그는 감싼 내부의 요소에 대해 동작한다.

    <transition> 경우는 일반적으로 하나의 요소이고, <transition-group> 은 여러 요소를 위함이다.


    <transition>

      <button>버튼</button>

    </transition>


    <transition-group>

      <div v-for="item in items">

         .............

      </div>

    </transition-group>


    위와 같은 태그를 사용해서 다양한 방법으로 애니메이션을 처리할 수 있게 도와준다.

    그 구현 방법에는 크게 2가지로 분류할 수 있다.


    • CSS 클래스(Class)
    • Javascript 훅(Hook)


    서론은 여기까지다.

    이제는 관련 예제를 통해 언급한 각 2가지 방법들을 확인해본다.



    우선 구현하는 트랜지션 효과는 다음과 같다.


    • 하단에 카드 리스트가 존재한다. 
    • 카드 리스트의 display 여부에 해당하는 ON/OFF 기능이 존재한다. (y축, 투명도 조절)
    • 카드 리스트에는 페이지마다 5개의 카드들이 존재하고, 카드 교체를 위한 왼쪽, 오른쪽 방향키가 존재한다.


    카드 리스트가 ON 일 경우 서서히 올라오면서 보여지게 된다.

    반대로 OFF 일 경우에는 서서히 내려가면서 사라지게 된다.

    오른쪽 방향키를 클릭하면 기존 카드들은 왼쪽 방향으로 서서히 나가고, 오른쪽에서 새로운 카드들이 서서히 들어온다.

    반대로 왼쪽 방향키를 클릭하면 기존 카드들은 오른쪽 방향으로 서서히 나가고, 왼쪽에서 새로운 카드들이 서서히 들어온다.


    위와 같은 시나리오는 아래 GIF 이미지를 통해 확인할 수 있다.


    Vue.js Transition


    예제의 템플릿 코드는 다음과 같은 형태로 작성되었다.


    App.vue

    <template> <div id="app"> <button>On/Off</button> <p>{{computedText}}</p> <transition name="slide-up"> <list-view v-show="isList"/> </transition> </div> </template>


    ListView.vue

    <template> <div class="list-container"> <direction/> <transition-group v-on:leave="leave" v-on:enter="enter"> <card v-for="item in computedItems"> ....... </card> </transition-group> <direction/> </div> </template>


    이미지와 코드를 본다면, 서론에서 언급했던 태그 및 이에 따른 구현 방법의 각 2가지 방식을 모두 사용하고 있다.

    자세히 설명하자면, 다음과 같다.


    트랜지션 태그가 사용된 곳은 두군데로써, 카드 리스트와 카드이다.

    코드를 보다시피 카드 리스트와 카드의 트랜지션에 대한 태그가 구분되었다.

    • 카드 리스트를 위해 <transition> 태그로 감싸졌다.
    • 카드는 v-for 를 통해 렌더링되기에 <transition-group> 태그로 감싼 모습을 볼 수 있다.

    <transition> 에는 name  속성, <transition-group> 에는 Hook 메소드를 정의함으로써, 구현 방법을 구분했다.


    • 카드 리스트는 "name 을 통해 CSS 클래스로 구분해서 트랜지션 효과를 제어하겠다"
    • 카드는 "훅(Hook) 을 통해 트랜지션 효과를 제어하겠다" 




    우선 카드 리스트에 대한 트랜지션에 대해 알아본다.

    카드 리스트 요소는 <transition> 태그에 감싸져있고, 속성 name 에는 slide-up 이라고 정의했다.

    이 name 속성으로 인해, 트랜지션이 발생하면 slide-up-* 형태의 CSS 클래스들이 적용된다.

    (기본적인 내용은 공식 문서에서 더 이해하기 쉬울 것이다. https://kr.vuejs.org/v2/guide/transitions.html)


    트랜지션 클래스


    버튼(Off) 클릭을 통해 진행되는 경우의 상황

    Vue.js 트랜지션


    버튼(On) 클릭을 통해 진행되는 경우의 상황

    Vue.js 트랜지션

    이러한 클래스명을 통해 원래 CSS 그대로 사용하면 되는 것처럼 사용하면 된다.

    원래 CSS 를 작성하는 것과 다를게 없다.

    CSS 그대로 사용하면 되는 것을 알아차릴 수 있다.

    이러한 클래스를 통해 CSS 만으로 트랜지션을 조작할 수 있게 되었다.


    .slide-up { transition: all 0.25s; } .slide-up-enter-active { transition: all 0.25s ease; } .slide-up-leave-active { transition: all 0.25s cubic-bezier(1, 0.5, 0.8, 1); } .slide-up-enter, .slide-up-leave-active { opacity: 0; transform: translateY(100%); }




    이번에는 <transition-group> 을 통해 감싸졌고, 훅을 통해 구현되는 트랜지션을 확인해본다.

    (본인은 카드에 대한 슬라이드 애니메이션을 고정적인 좌표를 가지는 방식으로 구현했다.)

    우선 각 카드는 트랜지션이 일어나면, 방향에 따라 현재 좌표에서 "카드 리스트의 너비" 만큼 +- 이동하게 된다.

    트랜지션 발생을 느리게 지켜보는 아래 그림을 보면 쉽게 이해할 수 있을 것이다. (overflow: hidden 해제)




    위처럼 트랜지션이 일어나면, 진출하는 카드들, 진입하는 카드들이 존재하게 될 것이고, 위처럼 애니메이션이 동작할 것이다.

    트랜지션이 일어날 때, 고려해야하는 사항들이 존재한다.


    • 진입/진출에 따라 시작하는 좌표가 다르다.
    • 진입/진출에 따라 이동하는 거리(+-) 가 다르다.
    • 클릭 방향에 따라 진입/진출의 좌표 및 거리가 다르다.


    이렇게 분기와 같은 상황이 존재한다면, CSS 만으로는 다소 구현이 복잡하다.

    이러한 경우 자바스크립트의 힘을 얻고 싶을 것이다.

    Vue.js 에서는 자바스크립트를 사용한 훅을 통해 쉽게 구현할 수 있다.


    트랜지션에 대한 훅은 다음과 같이 제공하고 있다.


    <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled" > ....... </transition>


    진입하는 요소들에 대한 훅들은 *enter*, 진출하는 요소들에 대한 훅은 *leave* 이다.

    용어 그대로 before-enter => enter => after-enter 순으로 호출된다.

    목적에 따라 원하는 훅을 고려하여 사용하면 된다.

    이 글의 예제에서는 단순히 leave, enter 훅만을 사용한다.


    methods: { leave(el, done) { let dist; // set, dist if (this.direction === "right") {} else {} el.style.transform = `translateX(${dist}px)`; done(); }, enter(el, done) { let dist; // set, dist if (this.direction === "right") {} else {} el.style.transform = `translateX(${dist}px)`; done(); }, }


    위와 같이 고려해야할 사항을 훅을 통해 진입/진출을 구분하고, 그 안에서 조건문을 사용할 수 있다.

    그로인해, 진입/진출에 대한 요소들을 자바스크립트를 통해 원하는 애니메이션을 쉽게 구현할 수 있다.


    이것뿐만 아니라, Vue.js 에서 제공하는 트랜지션 방법은 다양하다.

    글에서 다룬 2가지 방법을 혼용해서 사용해도 되고, 또 다른 방식들도 많이 존재한다.

    공식 문서를 참고하자.

    계속 반복해서 자세한건 공식 문서를 참고하는데... 그만큼 문서가 잘 되어있다.


    완성된 예제 코드를 통해 직접 확인해보길 바란다.

    관련 예제 코드(codesandbox.io) - https://kxk7j2vwr.codesandbox.io/

    댓글 0

Designed by Tistory.