Lesson 03-Nuxt.js Transition Effects

Global Transition Effects

Global transition effects are applied to all page transitions. You can configure global transitions in the nuxt.config.js file.

Configuration Example:

// nuxt.config.js
export default {
  transition: {
    name: 'fade',
    mode: 'out-in',
  },
};

CSS File:

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to /* .fade-leave-active in Vue 2.x */ {
  opacity: 0;
}

Local Transition Effects

Local transition effects apply only to specific pages or components. You can define transitions directly in a page file using the <transition> tag.

Page File Example (pages/index.vue):

<template>
  <div>
    <transition name="slide">
      <router-view></router-view>
    </transition>
  </div>
</template>

<style scoped>
.slide-enter-active,
.slide-leave-active {
  transition: transform 0.5s;
}
.slide-enter,
.slide-leave-to {
  transform: translateX(20px);
}
</style>

Using Vue.js Transition-Group Component

To apply transition effects to list items, you can use the <transition-group> component.

Example:

<template>
  <transition-group name="list" tag="ul">
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </transition-group>
</template>

<style scoped>
.list-move {
  transition: transform 1s;
}
</style>

Dynamic Transition Names

You can dynamically change the transition name based on conditions.

Example:

<template>
  <transition :name="transitionName">
    <router-view></router-view>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      transitionName: 'fade',
    };
  },
};
</script>

Controlling Transitions with JavaScript

For more complex transition logic, you can control transitions using JavaScript.

<template>
  <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
    <router-view></router-view>
  </transition>
</template>

<script>
export default {
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0;
    },
    enter(el, done) {
      let frameId = requestAnimationFrame(() => {
        el.style.opacity = 1;
        frameId = requestAnimationFrame(() => {
          el.style.transform = 'scale(1)';
          done();
        });
      });
    },
    afterEnter(el) {
      cancelAnimationFrame(frameId);
    },
  },
};
</script>

Multiple Transition Effects

You may need to apply different transition effects to various elements on a single page, such as buttons and text inputs.

<template>
  <div>
    <transition name="button-fade">
      <button v-if="showButton">Click me</button>
    </transition>
    <transition name="input-slide">
      <input v-if="showInput" type="text" placeholder="Type something">
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showButton: false,
      showInput: false,
    };
  },
  mounted() {
    setTimeout(() => {
      this.showButton = true;
      this.showInput = true;
    }, 1000);
  },
};
</script>

<style scoped>
.button-fade-enter-active,
.button-fade-leave-active {
  transition: opacity 0.5s;
}
.button-fade-enter,
.button-fade-leave-to {
  opacity: 0;
}

.input-slide-enter-active,
.input-slide-leave-active {
  transition: transform 0.5s;
}
.input-slide-enter,
.input-slide-leave-to {
  transform: translateY(20px);
}
</style>

Using External Libraries

In addition to native Vue.js transitions, you can use third-party libraries like Animate.css for more complex animation effects.

Install Animate.css:

npm install animate.css --save
<template>
  <div>
    <transition name="animated fadeIn">
      <router-view></router-view>
    </transition>
  </div>
</template>

<style>
@import "node_modules/animate.css";

.animated {
  animation-duration: 1s;
}
</style>

Managing State with Vuex

For complex applications, you may need to use Vuex to manage transition-related state.

// store/index.js
export default new Vuex.Store({
  state: {
    transitionName: 'fade',
  },
  mutations: {
    setTransition(state, name) {
      state.transitionName = name;
    },
  },
});

Using in a Component:

<template>
  <transition :name="transitionName">
    <router-view></router-view>
  </transition>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['transitionName']),
  },
};
</script>

Custom Transition Hooks

Vue.js provides several transition hooks, such as before-enter, enter, and after-enter. These hooks allow you to perform custom operations at different stages of a transition.

<template>
  <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
    <router-view></router-view>
  </transition>
</template>

<script>
export default {
  methods: {
    beforeEnter(el) {
      // Operations before the element enters
      el.style.opacity = 0;
    },
    enter(el, done) {
      // Operations during the element's entry
      let frameId = requestAnimationFrame(() => {
        el.style.opacity = 1;
        frameId = requestAnimationFrame(() => {
          el.style.transform = 'scale(1)';
          done();
        });
      });
    },
    afterEnter(el) {
      // Operations after the element has entered
      cancelAnimationFrame(frameId);
    },
  },
};
</script>
Share your love