VUE :Transition elements on view change - javascript

I have what seems to be the simplest of problems but cannot get around it.
My goal is very simple :
On view change I would like to transition some elements of the new view. Not the whole view, because I want to keep the background in place, so a <router-view> global transition doesn't do the trick here (it works btw).
Here is an simplified version of the code I have right now :
<template>
<div class="fixedBackground">
<transition name="slideIn">
<div>
<h1>Title</h1>
<p>Subtitle</p>
</div>
</transition>
</div>
</template>
<script>
export default {
name: 'whatever'
}
</script>
<style scoped>
.slideIn-enter-active, .slideIn-leave-active {
transition: transform .3s ease, opacity .3s ease;
}
.slideIn-enter, .slideIn-leave-to {
transform: translateX(-10vw);
opacity: 0;
}
.slideIn-enter-to, .slideIn-leave {
transform: translateX(0);
opacity: 1;
}
</style>
The transition as it is doesn't have any effect.
I tried watching routes in App.vue to pass the active page as a prop and activate the transition when landing on the page, it didn't work.
And now that I'm experimenting with even more complicated solutions it just feels like I'm missing the really easy way to do that :( by what I've read the code I have should work fine.
TLDR : I need to transition some elements on view change, but not the whole router-view.

You need a v-if or v-show inside your transition, a data variable, "show" in this example, to toggle visibility, and then toggle the "show" variable on created, or any other action like data returned from an API, etc.
<template>
<div class="fixedBackground">
<transition name="slideIn">
<div v-show="show">
<h1>Title</h1>
<p>Subtitle</p>
</div>
</transition>
</div>
</template>
<script>
export default {
name: 'whatever',
data () {
return {
show: false
}
},
mounted () {
this.show = true;
}
}
</script>
<style scoped>
.slideIn-enter-active, .slideIn-leave-active {
transition: transform .3s ease, opacity .3s ease;
}
.slideIn-enter, .slideIn-leave-to {
transform: translateX(-10vw);
opacity: 0;
}
.slideIn-enter-to, .slideIn-leave {
transform: translateX(0);
opacity: 1;
}
</style>

Related

vue transition component doesn't work correctly

hello this is a simple code but i don't know what is problem.
when i click on open modal on parent component modal get open but without transition
i just write it from a tutorial and in tutorial it work correctlry
<template>
<div class="backdrop" #click="$emit('close')" v-if="open"></div>
<transition name="modal" mode="out-in">
<dialog open v-if="open">
<slot></slot>
</dialog>
</transition>
</template>
<script>
export default {
emits: ['close'],
props:['open']
};
</script>
<style scoped>
.modal-enter-active{
animation: modal 2s linear;
}
.modal-leave-active{
animation: modal 2s linear;
}
#keyframes modal {
from{
opacity: 0;
transform:translateY(-150px) scale(0)
}
to{
opacity: 1;
transform:translateY(0) scale(1)
}
}
</style>
i am using vue 3
Do you actually need to use CSS animations?
How about using simple transitions?
.modal-enter-active, .modal-leave-active {
transition: 2s;
transition-timing-function: linear;
}
.modal-enter, .modal-leave-to {
opacity: 0;
transform:translateY(-150px) scale(0);
}

Vue Js - Transition only when component is visible

I'm doing some transitions using the transition tag and they're working perfectly. The problem is that transitions happen even if the component is not visible, I wanted it to happen only when the user arrived on that part of the page. Is there any way to do this with Vue?
HTML:
<transition name="products" appear>
<h2 class="container">Products</h2>
</transition>
CSS:
#keyframes slide-in {
from { transform: translateX(-60px); }
to { transform: translateX(0); }
}
.products-enter-active {
animation: slide-in 2s ease;
}

Vue - apply transition to menu element

I have this scss code in my vue app. I'm trying to make a smooth transition from left for a menu when the isVisible property is set to true but I'm not able to apply the transition I've defined and the menu will instantly appear.
I've done a reserach here on SO and I've found some interesting questions but all of them are using jQuery and css animation so they are not really useful.
I'm not a CSS master, any suggestion about?
HTML
<div class="col-12 settings p-3 position-fixed" :class="{ 'show': isVisible }" ref="settings" v-if="isVisible">
<h4>Settings</h4>
</div>
CSS
.settings {
top: 0;
width: 50%;
height: 100vh;
background-color: white;
transform: translateX(-100%);
transition: transform 0.5s ease;
&.show {
transform: translateX(0);
transition: transform 0.5s ease;
}
}
This is done with <transition>
Here an example:
<transition name="slide">
<div class="col-12 settings p-3 position-fixed" class="settings" v-if="isVisible">
<h4>Settings</h4>
</div>
</transition>
CSS class
.slide-enter-active, .slide-leave-active {
transition: transform .5s;
}
.slide-enter, .slide-leave-to {
transform: translateX(-200px);
}
.settings {
top: 0;
width: 50%;
height: 100vh;
background-color: white;
}
Its really not that hard
Take a look: https://v2.vuejs.org/v2/guide/transitions.html
I believe the issue is that, because you are using v-if, the element is only being rendered when the condition isVisible === True. This means that it is being rendered with the conditional 'show' class already applied, therefore no transition.
You could use the v-show directive instead of v-if, this makes the element hidden but rendered until the condition is true. (more info here).
<div
class="col-12 settings p-3 position-fixed"
:class="{ 'show': isVisible }"
ref="settings"
v-show="isVisible">
<h4>Settings</h4>
</div>
If you want to do more with transitions, I suggest looking up vue-transitions - documentation here - this allows you to assign css to the element during its rendering states, i.e. what styles apply as it enters and when it leaves.
See the other answer here for an example of how to do this with vue transition.

Vue.js transition doesn't apply on page first load

I have a navbar with links that switch between two components.
I've got a fade-in animation for the switching, but it wouldn't run when you first open the page (it runs only when you use the navbar links to switch the components).
Is there any way to overcome this?
P.S. The components are just <h1>Home</h1> and <h1>About</h1>.
HTML:
<div id="app">
<transition name="view">
<router-view/>
</transition>
</div>
JS (Router):
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
redirect: { name: 'home-route' }
},
{
path: '/home',
name: 'home-route',
component: HomeComponent
},
{
path: '/about',
name: 'about-route',
component: AboutComponent
}
]
})
CSS (Animation):
.view-leave-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
}
.view-enter-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
transition-delay: 0.5s;
}
.view-enter, .view-leave-to {
opacity: 0;
}
.view-enter-to, .view-leave {
opacity: 1;
}
Just add "appear" attribute in the transition wrapper.
And you will need your css classes for the animtaion or transition to.
Example:
<transition name="fade" appear></transition>
View transitions don't automatically work on page load as when the content is loaded they haven't been initialised yet.
You have to find another way to trigger the transition. I can think of a few options.
Hide the component by default with a data prop and then in the mounted life cycle switch it to true. This should trigger the transition.
<div v-if="show"></div>
data() {
return {
show: false
}
},
mounted() {
this.show = true; // might need this.$nextTick
}
Use a regular css transition.
Similar to the above approach, give the parent element a class with a style
opacity: 0;
transition: opacity 0.5s ease-in-out;
Then on mount add a class to change the opacity to 1.

Vue.js animations not working correctly

I am using Vue 2 and attempting to include CSS animations on elements that are created and destroyed frequently. Below is an example of my code:
export default {
name: 'MyElement',
methods: {
enterStart: function (el) {
console.log('about to enter');
el.classList.add('testing-enter');
},
enter: function (el) {
console.log('entered');
},
leaveStart: function (el) {
console.log('starting to leave!');
},
leave: function (el) {
console.log('leaving!');
},
}
};
.testing-enter {
animation: enter .2s;
}
.testing-leave {
animation: leave .2s;
}
#keyframes enter {
0% {
opacity: 0;
transform: scale(0);
}
100% {
opacity: 1;
transform: scale(1);
}
}
#keyframes leave {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0);
}
}
<template>
<div>
<transition
#before-enter="enterStart"
#enter="enter"
#leave="leaveStart"
#leave-active="leave"
appear
>
<div>My element is here!</div>
</transition>
</div>
</template>
First off, none of this works unless I include appear in my <transition ...> element. I know that this makes the transition happen on initial rendering, but I want them to happen any time the element is created or destroyed.
Next, in my console. I can see enterStart and enter both run, but leaveStart and leave never run, even when the elements are destroyed. What am I doing wrong?
The element inside the transition needs a state (show or hide). Also your transition needs a name that must much the transition in the CSS and it should be named with
name="transitionName"
e.g:
new Vue({
el: "#app",
data: function() {
return {
showThisElement: false
}
},
methods: {
toggleShow: function() {
this.showThisElement = !this.showThisElement
}
}
});
.testing-enter-active {
animation: enter .2s;
}
.testing-leave-active {
animation: leave .2s;
}
#keyframes enter {
0% {
opacity: 0;
transform: scale(0);
}
100% {
opacity: 1;
transform: scale(1);
}
}
#keyframes leave {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0);
}
}
<div id="app">
<div #click="toggleShow">Show/Hide</div>
<transition
name="testing">
<div v-if="showThisElement">My element is here!</div>
</transition>
</div>
In the codepen, click on 'show/hide' to toggle the transition.
http://codepen.io/anon/pen/WpZPJp
Problem solved!
So I took out the transition from the individual component and created a transition-group instead around the container component that rendered them.
Then, after a bit more reading I realized I wanted to add the mode="out-in" field to my transition-group so that the leaving components fully animate before the new ones are rendered.
I also looked at the HTML when the animations were supposed to be happening to see what classes Vue added. It looks like Vue added v-enter-active, v-enter-to, and v-leave-to. Instead of customizing any names I just stuck with those classes and added my animations to them in the styling.
Hopefully if anybody else wants a similar effect this helps them decrease their stress levels a bit...

Categories