Dikarenakan banyaknya fitur yang harus dikerjakan, kadang kita lupa untuk memberikan efek animasi pada komponen yang kita buat. Meskipun tidak memberikan dampak yang besar pada pengalaman pengguna, namun efek animasi bisa membuat aplikasi kita terlihat lebih menarik dan interaktif. Selain itu, efek animasi juga bisa membantu pengguna dalam memahami perubahan yang terjadi pada aplikasi. Vue.js menyediakan fitur transition menggunakan komponen Transition yang memudahkan kita dalam memberikan efek animasi pada komponen.

Pada artikel ini saya menggunakan tailwindcss sebagai utility class untuk membuat animasi.

Animasi Komponen Muncul / Hilang

Komponen Transition pada Vue.js sebenarnya sudah cukup untuk memberikan efek animasi pada komponen, namun karena ada banyak props yang harus dituliskan maka kita akan membuat komponen sendiri yang lebih sederhana. Komponen ini saya beri nama ToggleTransition.vue yang akan memiliki tiga props, yaitu duration, type dan timingFunction. Anda bisa meletakkannya di dalam folder src/components pada proyek Vue.js Anda.

html
        
<script setup lang="ts">
import { computed } from 'vue';

const props = withDefaults(defineProps<{
  duration: 'fast' | 'normal' | 'slow';
  type: 'fade' | 'slideX' | 'slideY' | 'zoomIn' | 'zoomOut';
  timingFunction: 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
}>(), {
  duration: 'normal',
  type: 'fade',
  timingFunction: 'ease-in'
});

const transitionClassesMap = {
  slideY: {
    enterFromClass: 'opacity-0 translate-y-20',
    enterToClass: 'opacity-100 translate-y-0',
    leaveFromClass: 'opacity-100 translate-y-0',
    leaveToClass: 'opacity-0 translate-y-20',
  },
  slideX: {
    enterFromClass: 'opacity-0 translate-x-20',
    enterToClass: 'opacity-100 translate-x-0',
    leaveFromClass: 'opacity-100 translate-x-0',
    leaveToClass: 'opacity-0 translate-x-20'
  },
  zoomIn: {
    enterFromClass: 'opacity-0 scale-50',
    enterToClass: 'opacity-100 scale-100',
    leaveFromClass: 'opacity-100 scale-100',
    leaveToClass: 'opacity-0 scale-50'
  },
  zoomOut: {
    enterFromClass: 'opacity-0 scale-150',
    enterToClass: 'opacity-100 scale-100',
    leaveFromClass: 'opacity-100 scale-100',
    leaveToClass: 'opacity-0 scale-150'
  },
  fade: {
    enterFromClass: 'opacity-0',
    enterToClass: 'opacity-100',
    leaveFromClass: 'opacity-100',
    leaveToClass: 'opacity-0'
  },
};

const transitionClasses = computed(() => transitionClassesMap[props.type]);
const durationMap = {
  fast: 'duration-300',
  normal: 'duration-700',
  slow: 'duration-1000'
};

</script>

<template>
  <Transition appear
    :enter-active-class="`transition ${props.timingFunction} ${durationMap[props.duration]}`"
    :enter-from-class="transitionClasses.enterFromClass"
    :enter-to-class="transitionClasses.enterToClass"
    :leave-active-class="`transition ${props.timingFunction} ${durationMap[props.duration]}`"
    :leave-from-class="transitionClasses.leaveFromClass"
    :leave-to-class="transitionClasses.leaveToClass">
    <slot></slot>
  </Transition>
</template>
      

Komponen ToggleTransition di atas menerima tiga props, yaitu duration, type dan timing-function. duration digunakan untuk menentukan durasi animasi, sedangkan type digunakan untuk menentukan jenis animasi yang akan digunakan (fade, slideY, slideX, zoomIn, zoomOut). timingFunction digunakan untuk menentukan jenis fungsi waktu yang digunakan dalam animasi.

Contoh penggunaan komponen ToggleTransition:

html
        
<script setup lang="ts">
import { ref } from 'vue';
import ToggleTransition from './components/ToggleTransition.vue';

const state = ref(true);
</script>

<template>
  <button @click="state = !state" class="bg-yellow-700 rounded m-5 text-white p-4">Toggle State</button>

  <ToggleTransition type="slideY" duration="slow">
    <div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Slide Y</div>
  </ToggleTransition>

  <ToggleTransition type="fade" timing-function="ease-in">
    <div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Fade</div>
  </ToggleTransition>
</template>
      

Tombol Toggle State digunakan untuk mengubah nilai variabel state yang akan menampilkan atau menyembunyikan elemen yang berada di dalam komponen ToggleTransition. Pada contoh di atas, kita menggunakan dua jenis animasi, yaitu slideY dan fade.

Animasi Antara Komponen

Selain animasi muncul dan hilang, kita juga bisa memberikan efek animasi ketika komponen berubah. Misalnya, ketika kita mengganti sebuah blok pada aplikasi, kita bisa memberikan efek animasi ketika komponen lama digantikan dengan komponen baru. Kita juga akan membuat komponen sendiri yang bernama SwitchTransition.vue yang juga akan memiliki tiga props, yaitu duration, type dan timingFunction.

html
        
<script setup lang="ts">
import { computed } from 'vue';

const props = withDefaults(defineProps<{
  duration: 'fast' | 'normal' | 'slow';
  type: 'fade' | 'slideX' | 'slideY' | 'zoom';
  timingFunction: 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
}>(), {
  duration: 'normal',
  type: 'fade',
  timingFunction: 'ease-in'
});

const transitionClassesMap = {
  slideY: {
    enterFromClass: 'opacity-0 translate-y-20',
    enterToClass: 'opacity-100 translate-y-0',
    leaveFromClass: 'opacity-100 translate-y-0',
    leaveToClass: 'opacity-0 translate-y-20',
  },
  slideX: {
    enterFromClass: 'opacity-0 translate-x-20',
    enterToClass: 'opacity-100 translate-x-0',
    leaveFromClass: 'opacity-100 translate-x-0',
    leaveToClass: 'opacity-0 translate-x-20'
  },
  zoom: {
    enterFromClass: 'opacity-0 scale-50',
    enterToClass: 'opacity-100 scale-100',
    leaveFromClass: 'opacity-100 scale-100',
    leaveToClass: 'opacity-0 scale-50'
  },
  fade: {
    enterFromClass: 'opacity-0',
    enterToClass: 'opacity-100',
    leaveFromClass: 'opacity-100',
    leaveToClass: 'opacity-0'
  }
};

const transitionClasses = computed(() => transitionClassesMap[props.type]);
const durationMap = {
  fast: 'duration-300',
  normal: 'duration-700',
  slow: 'duration-1000'
};
const enterLeaveActiveClass = computed(() => `transition ${props.timingFunction} ${durationMap[props.duration]}`);
</script>

<template>
  <Transition 
    :enter-active-class="enterLeaveActiveClass" 
    :enter-from-class="transitionClasses.enterFromClass"
    :enter-to-class="transitionClasses.enterToClass"
    :leave-active-class="enterLeaveActiveClass"
    :leave-from-class="transitionClasses.leaveFromClass"
    :leave-to-class="transitionClasses.leaveToClass"
    mode="out-in">

    <slot></slot>
  
  </Transition>
</template>
      

Komponen SwitchTransition di atas hampir sama dengan komponen ToggleTransition, namun kita menggunakan properti mode="out-in" pada komponen Transition. Properti ini digunakan untuk memberikan efek animasi pada komponen lama sebelum digantikan dengan komponen baru. Untuk menggunakan komponen ini harus dipastikan bahwa hanya ada 1 komponen yang ditampilkan pada satu waktu.

Contoh penggunaan komponen SwitchTransition:

html
        
<script setup lang="ts">
import { ref } from 'vue';
import SwitchTransition from './components/SwitchTransition.vue';

const state = ref(true);
</script>

<template>
  <button @click="state = !state" class="bg-yellow-700 rounded m-5 text-white p-4">Toggle State</button>

  <SwitchTransition type="slideY" duration="slow">
    <div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Slide Y</div>
    <div v-else class="bg-red-500 text-white p-4 mb-2">Slide Y</div>
  </SwitchTransition>

  <SwitchTransition type="fade" timing-function="ease-in">
    <div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Fade</div>
    <div v-else class="bg-red-500 text-white p-4 mb-2">Fade</div>
  </SwitchTransition>
</template>
      

Pada contoh di atas, kita menggunakan dua jenis animasi, yaitu slideY dan fade. Ketika tombol Toggle State ditekan, maka komponen yang ditampilkan akan berubah dengan efek animasi yang kita tentukan.

Kesimpulan

Semoga artikel ini bisa membantu Anda dalam memberikan efek animasi pada komponen Vue.js yang Anda buat. Dengan menggunakan komponen Transition pada Vue.js, kita bisa memberikan efek animasi pada komponen dengan mudah. Dengan memberikan efek animasi pada komponen, kita bisa membuat aplikasi kita terlihat lebih menarik dan interaktif.