66 lines
1.4 KiB
Vue
66 lines
1.4 KiB
Vue
<template>
|
|
<transition
|
|
name="expand"
|
|
:duration="500"
|
|
@enter="enter"
|
|
@after-enter="afterEnter"
|
|
@leave="leave">
|
|
<slot></slot>
|
|
</transition>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
export default {
|
|
methods: {
|
|
enter(element, done) {
|
|
const width = getComputedStyle(element).width;
|
|
|
|
element.style.width = width;
|
|
element.style.position = 'absolute';
|
|
element.style.visibility = 'hidden';
|
|
element.style.height = 'auto';
|
|
|
|
const height = getComputedStyle(element).height;
|
|
|
|
element.style.width = null;
|
|
element.style.position = null;
|
|
element.style.visibility = null;
|
|
element.style.height = 0;
|
|
|
|
// Trigger the animation.
|
|
// We use `setTimeout` because we need
|
|
// to make sure the browser has finished
|
|
// painting after setting the `height`
|
|
// to `0` in the line above.
|
|
setTimeout(() => {
|
|
element.style.height = height;
|
|
});
|
|
},
|
|
|
|
afterEnter(element) {
|
|
element.style.height = 'auto';
|
|
},
|
|
|
|
leave(element, done) {
|
|
const height = getComputedStyle(element).height;
|
|
|
|
element.style.height = height;
|
|
|
|
setTimeout(() => {
|
|
element.style.height = 0;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
* {
|
|
will-change: height;
|
|
transform: translateZ(0);
|
|
backface-visibility: hidden;
|
|
perspective: 1000px;
|
|
}
|
|
</style> |