Skip to content

Instantly share code, notes, and snippets.

@CyberAP
Last active February 12, 2023 01:06
Show Gist options
  • Select an option

  • Save CyberAP/b1f88c9ea33dbb5bdb3eff1e1a37cc33 to your computer and use it in GitHub Desktop.

Select an option

Save CyberAP/b1f88c9ea33dbb5bdb3eff1e1a37cc33 to your computer and use it in GitHub Desktop.
Transition height change in Vue
<template>
<div
class="transition-expand"
ref="container"
:style="style"
>
<transition
name="transition-fade"
@enter="enter"
@leave="leave"
@enterCancelled="clearHeight"
@leaveCancelled="clearHeight"
@afterEnter="clearHeight"
@afterLeave="clearHeight"
:duration="duration"
>
<slot />
</transition>
</div>
</template>
<script>
export default {
name: 'TransitionExpand',
props: {
duration: {
type: String,
default: '200'
},
},
data() {
return {
startHeight: 0,
height: null,
}
},
methods: {
enter(el) {
const { container } = this;
this.height = null;
const endHeight = container.clientHeight;
this.height = this.startHeight;
setTimeout(() => {
this.height = endHeight;
});
},
leave(el) {
const { container } = this;
this.height = null;
const [newEl] = Array.from(container.children).filter(child => child !== el);
if (newEl) {
newEl.classList.add('transition-expand__detached');
}
this.startHeight = container.clientHeight;
if (newEl) {
newEl.classList.remove('transition-expand__detached');
}
el.classList.add('transition-expand__detached');
const endHeight = container.clientHeight;
this.height = this.startHeight;
if (!newEl) {
setTimeout(() => {
this.height = endHeight;
});
}
},
clearHeight(el) {
this.startHeight = 0;
this.height = null;
},
},
computed: {
container() {
return this.$refs.container;
},
style() {
const { duration, height } = this;
return {
'--expand-duration': `${duration}ms`,
height: height !== null ? height + 'px' : null,
}
},
}
}
</script>
<style>
.transition-fade-enter-active,
.transition-fade-leave-active
{
transition: .2s;
transition-property: opacity;
}
.transition-fade-enter,
.transition-fade-leave-to
{
opacity: 0;
}
.transition-expand
{
overflow: hidden;
will-change: height;
position: relative;
transition: height var(--expand-duration);
}
.transition-expand__detached
{
position: absolute;
width: 100%;
left: 0;
top: 0;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment