问题
Is there a way to get Vue to wait for elements to leave a list before new ones enter? At the moment, the animation for new elements entering the list plays at the same time as the animation for elements leaving the list:
var SPEED = 3;
var app = new Vue({
el: '.container',
data: {
nodes: [
{id: 0, value: 5, name: "Alan"},
{id: 1, value: 15, name: "Bob"},
{id: 2, value: 25, name: "Charles"}
]
},
methods: {
enter(el, done) {
var bar = $(el).children(".bar");
TweenMax.fromTo(bar, SPEED, {width: 0}, {width: $(el).attr("width") * 10, onComplete: done});
},
leave(el, done) {
var bar = $(el).children(".bar");
TweenMax.fromTo(bar, SPEED, {width: $(el).attr("width") * 10}, {width: 0, onComplete: done});
},
swapBobDave() {
this.nodes = [
{id: 0, value: 5, name: "Alan"},
{id: 2, value: 25, name: "Charles"},
{id: 3, value: 35, name: "Dave"}
];
},
reset() {
this.nodes = [
{id: 0, value: 5, name: "Alan"},
{id: 1, value: 15, name: "Bob"},
{id: 2, value: 25, name: "Charles"}
];
}
}
});
body {
margin: 30px;
font-family: sans-serif;
}
.bar {
background-color: pink;
padding: 10px;
margin: 10px;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<h1>Vue JS Hooks</h1>
<transition-group name="list" tag="div" v-on:enter="enter" v-on:leave="leave" v-bind:css="false" appear>
<div v-for="(node, index) in nodes" v-bind:key="node.id" v-bind:width="node.value">
<div class="bar" v-bind:style="{width: node.value + '%'}">{{node.name}}</div>
</div>
</transition-group>
<button type="button" class="btn btn-default" @click="swapBobDave">Add Dave and remove Bob</button>
<button type="button" class="btn btn-default" @click="reset">Reset</button>
</div>
Extra points for explaining why the leaving bar doesn't get to width: 0
before disappearing!
回答1:
It's a transition-group
, so every change to the array is a different animation. If you always add an element and then remove another one, you can achieve it using a setTimeout on enter
hook, having the same duration of SPEED
.
enter(el, done) {
window.setTimeout( () => {
var bar = $(el).children(".bar");
TweenMax.fromTo(bar, SPEED, {width: 0}, {width: $(el).attr("width") * 10, onComplete: done});
}, SPEED * 1000 )
},
I also suggest you to alter your array in the following way
swapBobDave() {
this.nodes.splice(1,1);
this.nodes.push({id: 3, value: 35, name: "Dave"});
},
Concerning the bar, it reachs width: 0
but there is padding: 10px
in the css. To fix it you can add margin directly to the text within, and remove padding on bar.
Hope it helps you.
来源:https://stackoverflow.com/questions/56004995/vue-list-animation-with-greensock-js-hooks-wait-for-leave-to-finish-before-ente