Vuejs: Complete Dynamic Component Transition Before Rendering New Component

VueJS: Complete dynamic component transition before rendering new component

mode="out-in" should be what you want.

Transition between the same component?

Had the same problem yesterday! ^^"
It worked fine when I added a :key="" attribute to my component (even if there is no prop called key in the child component).
Try with this :

<transition name="slide">
<my-component :key="currentIndex" :my-prop="data[currentIndex]" />
</transition>

I don't know yet why but I guess if a prop is an object, it dont detect the changes? Or maybe you must pass a key attribute (but I saw some examples not using key attribute...)
Tell me if it works ;)

Edit: I saw that you change the name of the transition and the style don't include this name. Try the solution above with the default name and style ("fade") https://v2.vuejs.org/v2/guide/transitions.html

Vue.js change a leave transition dynamically after enter has been played

Looks like your slide transition starts before slideDirection is updated.
Try using nextTick function so that slide transition wait for direction to get updated.

Updated Example.

new Vue({  el: "#app",  data: {    slideDirection: "right",    counter: 0  },  methods: {    moveRight: function() {      this.slideDirection = "right";      this.$nextTick(() => {        this.counter++;      })
}, moveLeft: function() { this.slideDirection = "left"; this.$nextTick(() => { this.counter--; }) }, }})
body {  background: #20262E;  padding: 20px;  font-family: Helvetica;}
#app { background: #fff; border-radius: 4px; padding: 20px; transition: all 0.2s; display: flex; flex-direction: column; width: 300px; height: 150px;}
div#slider { position: relative;}
div#slider div:nth-child(even) { background: green;}
div#slider div:nth-child(odd) { background: red;}
div { padding: 30px; width: 100%; height: 100%; position: absolute;}
div:odd { background: blue;}
.slider-right-enter { opacity: 0; transform: translatex(100%);}
.slider-right-enter-to { opacity: 1; transition: all 0.5s ease-out;}
.slider-right-leave-to { opacity: 0; transform: translatex(-100%); transition: all 0.5s ease-out;}
.slider-left-enter { opacity: 0; transform: translatex(-100%);}
.slider-left-enter-to { opacity: 1; transition: all 0.5s ease-out;}
.slider-left-leave-to { opacity: 0; transform: translatex(100%); transition: all 0.5s ease-out;}
<div id="app">
<div id="slider"> <transition v-bind:name="'slider-' + slideDirection"> <div v-if='counter == 0'> 0 </div> </transition>
<transition v-bind:name="'slider-' + slideDirection"> <div v-if='counter == 1'> 1 </div> </transition>
<transition v-bind:name="'slider-' + slideDirection"> <div v-if='counter == 2'> 2 </div> </transition>
<transition v-bind:name="'slider-' + slideDirection"> <div v-if='counter == 3'> 3 </div> </transition>
</div>
<div>
<button @click="moveLeft"> << </button> <button @click="moveRight"> >> </button> </div></div>

Dynamic style for Vue transition

First, your way to set style just not work

el.style = {
transition: 'all 0.6s',
marginLeft: '-20em',
};

I just move transition: 'all 0.6s' to css and set style like this

el.style.marginLeft = '-20em';

Second, enter event is called very soon after beforeEnter event so the browser cannot detect change between two states. So I wrap enter event into setTimeout to make a trick to trigger the transition.

Third, done callback is not necessary in this case. It's only required in pure js transition. We are using mixed CSS and JS

Vue.component('app', {  template: `<div class="app">    <sidebar>sidebar content</sidebar>    <div class="main">Hello, VueJS!</div>  </div>`});
Vue.component('sidebar', { template: ` <div class="sidebarContainer"> <transition name="slide" @before-enter="beforeEnter" @enter="enter" @leave="leave" > <div v-if="isOpen" class="sidebar" :style="{ width }"> <slot/> </div> </transition> <div class="toggle" @click="isOpen = !isOpen"><></div> </div>`, props: { 'width': { default: '20em', } }, data() { return { isOpen: true, }; }, methods: { beforeEnter(el) { el.style.marginLeft = '-20em'; }, enter(el, done) { // Wait a tick here, so browser can detect style change and tigger transition setTimeout(() => { el.style.marginLeft = '0'; }, 0) }, leave(el, done) { el.style.marginLeft = '-20em'; }, },});
new Vue({ el: '#app', template: '<app/>'});
html,body,.app {  height: 100%;}
.app { display: flex;}
.main { flex-grow: 1; background: red;}
.sidebarContainer { display: flex;}
.sidebar { flex-grow: 1; padding: 0.5em; background: blue; transition: all 0.6s;}
.toggle { margin: 0.5em;}
<div id="app"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

How do you realize the in-out mode transition effect when using dynamic route matching in Vue.js?

You can definitely use in-out with router-view, Here is the modified fiddle from the question you have added : https://jsfiddle.net/dLnz4rbL/3/

I have change the transition to slide-fade with below CSS:

/* Enter and leave animations can use different */
/* durations and timing functions. */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for <2.1.8 */ {
transform: translateX(500px);
opacity: 0;
}


Related Topics



Leave a reply



Submit