transition toggle between divs in vue js - vue.js

I am trying to apply toggle between divs. But I couldn't make it happen. I know I can't put two elements inside the transition. I need to a transition-group for that. But when I use group, then it says bind the elements inside group. But I am not looping the elements... So I am a bit stuck about solving this...
template
<div>
<transition name="view">
<map-view
v-show="this.screenView == 'map'"
:changeView="changeView" />
<list-view
v-show="this.screenView === 'list'"
:changeView="changeView" />
</transition>
</div>
script
methods: {
changeView(screen){
this.screenView = screen;
}
}
styles
.view-enter-active, .view-leave-active {
transition: opacity .5s
}
.view-enter, .view-leave-to {
opacity: 0
}
By the way changeView() is working. No problem about that part. Just trying to toggle between divs.

Thanks to advice in the comments.
I tried to give different keys to elements.
<transition-group name="view">
<map-view
key="maps"
v-show="this.screenView == 'map'"
:changeView="changeView" />
<list-view
key="list"
v-show="this.screenView === 'list'"
:changeView="changeView" />
</transition-group>
and changed the styles like below.
.view-enter-active, .view-leave-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
}
.view-enter-active {
transition-delay: 0.5s;
}
.view-enter, .view-leave-to {
opacity: 0;
}
.view-enter-to, .view-leave {
opacity: 1;
}
It's working now.

Related

how to delay elements entering the DOM using TransitionGroup?

The problem I am running into is that all the elements are rendered first before the animation starts. The effect that I want to achieve is that the element is animated while entering the DOM and it happens one after another. What's wrong with my code?
<template>
<TransitionGroup appear name="stagger" tag="ul">
<li v-for="(num, index) in list" :style="{ '--order': index }" :key="num">
{{ num }}
</li>
</TransitionGroup>
</template>
<script setup>
const list = Array.from({ length: 5 }, (_, index) => index + 1);
</script>
<style scoped>
.stagger-enter-active {
animation-name: stagger;
animation-duration: 0.5s;
animation-delay: calc(var(--order) * 0.15s);
}
#keyframes stagger {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
After reading the official doc one more time, I realized that the same animation effect can be made with just transition and it works, which got me wondering what's the main difference between these two approaches?
.stagger-enter-from {
opacity: 0;
transform: translateX(-1em);
}
.stagger-enter-active {
transition: opacity 0.5s linear, transform 0.5s ease;
transition-delay: calc(var(--order) * 0.15s);
}

How to animate a transition from one Vue component to the same component (with a different parameter) using router?

I have a Vue 2 application. It uses router to manage pages. On one page, you can click to go to the next page, and the next page is the same component. You can think of it like a folder page going to a new sub folder page. The URL is the mostly same, except for the folder ID.
I want this animated, so the new component slides in from the right, over-top the old page.
But I think the router likes to reuse the same component, so how can I make multiple pages of the same component?
You can use the key attribute on your component, keyed to the route's folder ID param so that every new page load causes Vue to re-render the component which should also trigger your animation.
codesandbox
<template>
<div class="container">
<Transition name="slide">
<h1 class="text" :key="$route.params.id">Page {{ $route.params.id }}</h1>
</Transition>
</div>
</template>
.container {
position: relative;
}
.text {
position: absolute;
}
.slide-enter-active {
animation: slide 1s;
}
.slide-leave-active {
transition: all 1s;
opacity: 0;
}
#-webkit-keyframes slide {
0% {
-webkit-transform: translateX(200px);
transform: translateX(200px);
}
100% {
-webkit-transform: translateX(0px);
transform: translateX(0px);
}
}
#keyframes slide {
0% {
-webkit-transform: translateX(200px);
transform: translateX(200px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}

Slide transition on tab (one pushing the other)

I'm trying to achieve a slide transition between two tabs. One tab is supposed to come from the left pushing the other one to the right and the opposite for the other one.
The leave transition goes well but the tab just pop in straight away without starting where it is supposed to...
I have made a CodePen to reproduce what I've tried : Slide transition test on CodePen
Here is the HTML, it is just a div containting 2 buttons that change the visibility of two div that represents my tabs content.
<div id="transition-test" class="demo">
<div class="tabs">
<button v-for="tab in tabs" class="tab" :key="tab.id" #click="selectedTab = tab.id"> {{tab.text}}</button>
<transition name="slide-right">
<div v-show="1 === selectedTab" class="tab1" key="tab1"></div>
</transition>
<transition name="slide-left">
<div v-show="2 === selectedTab" class="tab2" key="tab2"></div>
</transition>
</div>
</div>
In order to do the transition I do have the following css :
.slide-left,
.slide-right{
position: absolute;
}
.slide-right-enter-to,
.slide-right-leave {
opacity: 1;
transform: translateX(0);
}
.slide-right-enter,
.slide-right-leave-to {
opacity: 0;
transform: translateX(100%);
}
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 500ms ease-in-out;
}
.slide-left-enter-to,
.slide-left-leave {
opacity: 1;
transform: translateX(0);
}
.slide-left-enter,
.slide-left-leave-to {
opacity: 0;
transform: translateX(-100%);
}
Does anyone have an idea about what I'm missing here ?
I found the issue. I don't know why in the Vue transition documentation the css class added at enter is v-enter but the class applied in reality is v-enter-from...
this css class :
.slide-left-enter
becomes :
.slide-left-enter-from
Instead of coding it by yourself, you can use npm version of the transition. It will also help you with its API, Guides and Examples, so that you don't have to worry about those.

VueRouter: Is it possible to have a smooth scroll down animation from one route to another?

I have a simple VueJS application where I have multiple routes. For a pair of routes, I want to have a scroll down and scroll up animation while routes change.
For example, I have a search/dropdown page, where after the search result from the dropdown is selected, I want to take him to the details page but with a scroll down animation. So that the user feels he is still on the same page.
I have tried using the VuePageTransition library. That is indeed a great library but does not have this specific animation that I need.
Update:
I tried the following code. It gives a scroll-like animation but the leaving page is shown going down but the coming page is not shown during the animation.
In the template in App.vue
<template>
<div id="app">
<transition name="slide" mode="out-in">
<router-view></router-view>
</transition>
</div>
</template>
In the style tag,
.slide-enter {
}
.slide-enter-active {
animation: slide-in-coming 2s ease-out forwards;
}
.slide-leave {
}
.slide-leave-active {
animation: slide-in 2s ease-out forwards;
}
#keyframes slide-in {
from {
transform: translateY(0);
}
to {
transform: translateY(800px);
}
}
#keyframes slide-in-coming {
from {
transform: translateY(-800px);
}
to {
transform: translateY(0);
}
}

Vuejs transition classes are not applying on Vue Component

I'm using VueJs transition to make a component appVacancies slide.
<transition name="slide-down" mode="out-in" appear>
<appVacancies v-if="showVacancies"></appVacancies>
</transition>
It's Vue specific CSS for transition is
// Slide Down animation
.slide-down-active, .slide-down-leave-active {
transition: all .5s ease-out;
}
.slide-down-enter, .slide-down-leave-to {
opacity: 0;
transform: translateY(20%);
}
On created() life-cycle hook I'm just using setTimeout() to make showVacancies boolean to true.
I also have a fade animation with similar configuration but that is working.
<transition name="fade">
<h1 v-if="!showMotion" class="display-2 grad-text mt-4">Welcome!</h1>
</transition>
// CSS
.fade-enter-active, .fade-leave-active {
transition: opacity .5s ease-out;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
I don't know what I'm doing wrong here. Please help.