Here is a simple component for Vue/TS that demonstrates using the
transition-group
directive to collapse the width of elements when they are
removed from a list.
One catch is that an unlabelled 'div' is inserted as the parent of all list items. This can cause problems when styling things using flexbox, which treats only its direct children as layout items. Also, if you have styling applied to the children, applying styling to the transition classes won't override those styles, because the transition style may be less specific than the styles on the child elements.
<template>
<div class="home">
<div class="container">
<transition-group name="mytrans" tag="div">
<div v-for="(box, index) in boxes"
v-if="box.isVisible"
:key="box.id"
class="box">
{{box.id}}
<button v-on:click="hide(index)">Hide</button>
</div>
</transition-group>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import _ from 'lodash';
interface Box {
isVisible: boolean;
id: number;
}
export default Vue.extend({
name: 'home',
data() {
return {
boxes: [] as Box[]
};
},
components: {},
created() {
for (var i = 0; i < 5; i++) {
this.boxes.push({isVisible: true, id: i});
}
},
methods: {
hide(index: number): void {
this.boxes[index].isVisible = false;
}
}
});
</script>
<style>
.container {
height: 200px;
background-color: blue;
}
/* Because vue transition creates a wrapper div around the transition'ed elements,
we need to style that div to layout the elements correctly. */
.container > div {
display: flex;
flex-direction: row;
}
.box {
height: 150px;
width: 150px;
margin: 16px;
background-color: green;
}
.mytrans-leave-active {
transition: all 0.5s ease-in;
}
.mytrans-leave-to {
width: 0px;
}
</style>