Transition bug with transition hack

by nkovacs

HTML

<script src="http://dev.mito.hu/n/vue.js"></script>
<button type="button" @click="component = 'component-a'">
Component A
</button>
<button type="button" @click="component = 'component-b'">
Component B
</button>
<button type="button" @click="nextTickSwitch">
nextTick Switch
</button>
<button type="button" @click="instantSwitch">
Instant Switch
</button>
<component :is="component" transition="page" transition-mode="out-in"></component>

SCSS

.page-transition {
	//transition: all .5s ease;
	transition: opacity 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.page-enter {
	transform: translateY(20px);
	opacity: 0;
	box-shadow: none;
}

.page-leave {
	transform: translateY(20px);
	opacity: 0;
	box-shadow: none;
}

JavaScript

var pageTransition = {
	beforeEnter: function(el) {
		console.log('animation beforeenter');
	},
	enter: function(el, done) {
		console.log('animation enter');
		if (getComputedStyle(el).opacity === '1') {
			console.log('short circuit animation');
			done();
		} else {

			var onEnd = function(e) {
				console.log('onend');
				if (e.propertyName !== 'opacity') {
					console.log('but not opacity');
					return;
				}
				el.removeEventListener(Vue.util.transitionEndEvent, onEnd);
				console.log('actually done');
				done();
			};

			el.addEventListener(Vue.util.transitionEndEvent, onEnd);

			this.$onPageEndEnter = onEnd;
		}
	},
	afterEnter: function(el) {
		console.log('animation afterenter');
	},
	enterCancelled: function(el) {
		console.log('enter cancelled');
		if (this.$onPageEndEnter) {
			el.removeEventListener(Vue.util.transitionEndEvent, this.$onPageEndEnter);
			this.$onPageEndEnter = null;
		}
	},

	beforeLeave: function(el) {
		console.log('animation beforeleave');
	},
	leave: function(el, done) {
		console.log('leave');
		if (getComputedStyle(el).opacity === '0') {
			done();
		} else {
			var onEnd = function(e) {
				if (e.propertyName !== 'opacity') {
					return;
				}
				el.removeEventListener(Vue.util.transitionEndEvent, onEnd);
				done();
			};

			el.addEventListener(Vue.util.transitionEndEvent, onEnd);

			this.$onPageEndLeave = onEnd;
		}
	},
	afterLeave: function(el) {
		console.log('animation afterleave');
	},
	leaveCancelled: function(el) {
		console.log('leave cancelled');
		if (this.$onPageEndLeave) {
			el.removeEventListener(Vue.util.transitionEndEvent, this.$onPageEndLeave);
			this.$onPageEndLeave = null;
		}
	}
};

Vue.transition('page', pageTransition);

var componentA = {
    template: "<p>I'm Component A</p>",
    data: function() {
    	return {
            test: 'test'
		};
	}
};

var componentB = {
    template: "<p>I'm Component B</p>",
    data: function() {
    	return {
            test:...