Ex No: 13 ANIMATION IN VUE.JS
Aim: To create a Vue.js application to implement element animation.
Procedure
Step1: Install Node Package Manager (npm) in the system.
Step2: Create New Vue.js project using "npm create vue@latest". Choose Router Option for Creating Single Page Application.
Step3: Open the created project folder and install the dependencies using "npm install".
Step4: Create two components "AppTitle.vue" and "ListComp.vue" place the components in projects src > components folder.
Step6: Create two Views "HomeView.vue" and "GrocView.vue" place the views in projects src > views folder.
Step7: Update the contents of "index.js" file in src > router folder.
Step8: Use <TransitionGroup> to add animation to the element in "ListComp.vue". Use <Transition> to add Router animation in "App.vue"
Step9: Include "AppTitle.vue" component and add <nav> tag and <RouterLink> in "App.vue" file to implement Single Page Application.
Step10: Include the "ListComp.vue" in "GrocView.vue" view.
Step11: Run the code using "npm run dev".
Source Code

App.vue


<script setup>
import { RouterLink, RouterView } from 'vue-router'
import AppTitle  from './components/AppTitle.vue';
</script>

<template>
  <AppTitle title="Grocery Shopping List App" class="css-title" />
  <nav>
    <RouterLink to="/">Home</RouterLink>
    <RouterLink to="/grocery">Grocery</RouterLink>
  </nav>
  <router-view v-slot="{ Component, route }">
    <transition :name="route.meta.transition" mode="out-in">
      <component :is="Component" />
    </transition>
  </router-view>
  <AppTitle title="Developed by Dr.D. Natarajasivan" class="css-footer" />
</template>

<style scoped>
nav {
  width: 100%;
  font-size: 14px;
  text-align: center;
  margin-top: 2rem;
}

nav a.router-link-exact-active {
  color: black;
}

nav a.router-link-exact-active:hover {
  background-color: transparent;
}

nav a {
  display: inline-block;
  padding: 0 1rem;
  border-left: 1px solid var(--color-border);
}

nav a:first-of-type {
  border: 0;
}

@media (min-width: 1024px) {

  nav {
    text-align: left;
    font-size: 1rem;
    padding: 1rem 0;
    margin-top: 1rem;
  }
}
.slide-enter-active,
.slide-leave-active {
  transition: opacity 1s ease, transform 1s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  transform: translateX(-100%);
}
</style>

AppTitle.vue


<script setup>
defineProps({
  title: {
    type: String,
    required: true
  }
});
</script>

  <template>
    <div>
      <h1>{{ title }}</h1>
    </div>
  </template>
  
  
  <style>
  .css-title {
    text-align: center;
    display: block;
    height: 100px;
    width: auto;
    background-color:rgb(175, 244, 101);
    color: red;
    text-decoration: underline;
    border-radius: 10px;
  }
  
  .css-footer {
    text-align: center;
    display: block;
    height: 100px;
    width: auto;
    font-size: 10px;
    background-color:rgb(206, 227, 228);
    color: red;
    text-decoration: underline;
    border-radius: 10px;
  }
  </style>

ListComp.vue


<script>
import { TransitionGroup } from 'vue';
export default {
  data() {
    return {
      items: [],
      newItem: ''
    }
  },
  methods: {
    addItem() {
      this.items.push(this.newItem)
      this.newItem = ''
    }
  }
}
</script>

<template>
    <TransitionGroup name="list" tag="ol">
        <li v-for="(item, index) in items" :key="index">{{ item }}</li>
    </TransitionGroup>
    <input class="list-inp" v-model="newItem" placeholder="Grocery Item" @keypress.enter="addItem()" />
</template>

<style>
.list-inp{
    width: 150px;
    height: 35px;
    border-radius: 5px;
    font-size: 14px;
    margin-left: 2.5%;
    padding-left: 10px;
}

li{
  font-size: 16px;
  font-weight: bold;
}

.list-enter-from {
    opacity: 0;
    transform: scale(0.5);
  }
  .list-enter-to {
    opacity: 1;
    transform: scale(1);
  }
  .list-enter-active {
    transition: all 4s;
  }
</style>

index.js


import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import GrocView from '../views/GrocView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView,
      meta: { transition: 'slide' },
    },
    {
      path: '/grocery',
      name: 'grocery',
      component: GrocView,
      meta: { transition: 'slide' },
    }
  ]
})

export default router

HomeView.vue


<template>
  <div class="home">
    <p>
      This VUE application is used to create a Grocery Shopping list
    </p>
  </div>
</template>

<style>
.home {
  min-height: 50vh;
  background-color: rgba(138, 255, 255, 0.497);
  border-radius: 10px;
  margin: 10px;
}
p{
  margin-left: 20px;
  padding-top: 20px;
}
</style>

index.js


<script setup>
import ListComp  from '../components/ListComp.vue';
</script>

<template>
  <div class="about">
    <h1>Create Grocery List</h1>
    <ListComp />
  </div>
</template>

<style>
.about {
    min-height: 50vh;
    background-color: rgba(248, 170, 200, 0.497);
    border-radius: 10px;
    margin: 10px;
  }
</style>

Result: Thus vue.js application is created to perform element animation.