Posted at

Vue.jsのリストレンダリングにslideUp/slideDownアニメーション効果


内容

Vue.jsのリストレンダリングのトランジションにjQueryのslideUp/slideDownのようなアニメーション効果をつける。


コード


HTML

<div id="app">

<input v-on:keypress.enter="addItem" v-model="input" type="text">
<button v-on:click="addItem">追加</button>
<transition-group tag="ul" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:leave="leave" v-on:after-leave="afterLeave">
<li v-for="(item, index) in list" v-bind:key="item.id">{{ item.text }}<button v-on:click="removeItem(index)">削除</button></li>
</transition-group>
</div>


CSS

ul {

padding-left: 0;
list-style-type: none;
}
li button {
margin-left: 1em;
}
.v-enter-active,
.v-leave-active {
overflow-y: hidden;
transition: height 0.5s ease;
}


JavaScript

var counter = 0; // v-forのkey属性用

var app = new Vue({
el: '#app',
data: {
input: '',
list: []
},
methods: {
addItem: function() {
if (this.input.length !== 0) {
this.list.push({
id: counter,
text: this.input
});
counter += 1;
this.input = '';
}
},
removeItem: function(index) {
this.list.splice(index, 1);
},
enter: function(element) {
var elementHeight = element.getBoundingClientRect().height;
element.style.height = 0;
element.offsetHeight; // reflow
element.style.height = elementHeight + 'px';
},
afterEnter: function(element) {
element.style.height = null;
},
leave: function(element) {
var elementHeight = element.getBoundingClientRect().height;
element.style.height = elementHeight + 'px';
element.offsetHeight; // reflow
element.style.height = 0;
},
afterLeave: function(element) {
element.style.height = null;
}
}
});