我正在为VueJS上的<transition-group>
元素使用纯JS钩子,而对于enter
钩子实际上是如何工作的,我感到很困惑。根据文档,我知道我将必须call done()
to avoid events being called synchronously:
使用仅JavaScript转换时,
done
和enter
钩子需要leave
回调。否则,挂钩将被同步调用,并且过渡将立即完成。
但是,即使我使用它,也似乎阻止了CSS过渡在输入过渡中发生。我发现的唯一解决方案是使用window.setTimeout
设置样式,我认为这是代码的味道。这是不带超时的代码与带超时的代码之间的快速直观比较(带超时的代码是理想的效果):
输入中断(左填充和不透明度没有转换)
所需的输入过渡:
在下面的示例中,我正在使用<transition-group>
显示一个列表,并希望使用JS挂钩,以便可以在单个列表项上创建交错的填充。在enter
过渡中,padding属性上的CSS过渡不起作用。
new Vue({
el: '#app',
data: {
items: [
'Lorem',
'Ipsum',
'Dolor',
'Sit',
'Amet'
],
toggle: false
},
computed: {
filteredItems: function() {
if (!this.toggle)
return [];
return this.items;
}
},
methods: {
toggleItems: function() {
this.toggle = !this.toggle;
},
beforeEnter: function(el) {
el.style.paddingLeft = '0px';
el.style.opacity = '0';
},
enter: function(el, done) {
el.style.paddingLeft = `${10 * +el.dataset.index}px`;
el.style.opacity = '1';
done();
},
beforeLeave: function(el) {
el.style.paddingLeft = '0px';
el.style.opacity = '0';
}
}
})
ul {
list-style: none;
margin: 0;
padding: 0;
}
ul li {
transition: all 500ms ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="toggleItems">
Toggle items
</button>
<transition-group
tag="ul"
@before-enter="beforeEnter"
@enter="enter"
@before-leave="beforeLeave">
<li
v-for="(item, i) in filteredItems"
v-bind:key="i"
v-bind:data-index="i">
{{ item }}
</li>
</transition-group>
</div>
如果您将enter
方法中的所有逻辑都包装在任意timout中,那么它将起作用:
enter: function(el, done) {
window.setTimeout(() => {
el.style.paddingLeft = `${10 * +el.dataset.index}px`;
el.style.opacity = '1';
done();
}, 100);
},
这是让我有些困惑的地方:enter
挂钩是否不等待beforeEnter
首先完成?工作片段如下
答案 0 :(得分:2)
将@enter
钩子更改为@after-enter
应该可以解决
我不知道为什么@enter
钩对此不起作用,因为它在应该的文档中进行了说明,但这至少应该摆脱超时而不会成为黑客。
new Vue({
el: '#app',
data: {
items: [
'Lorem',
'Ipsum',
'Dolor',
'Sit',
'Amet'
],
toggle: false
},
computed: {
filteredItems: function() {
if (!this.toggle)
return [];
return this.items;
}
},
methods: {
toggleItems: function() {
this.toggle = !this.toggle;
},
beforeEnter: function(el) {
el.style.paddingLeft = '0px';
el.style.opacity = '0';
},
afterEnter: function(el) {
el.style.paddingLeft = `${10 * +el.dataset.index}px`;
el.style.opacity = '1';
},
beforeLeave: function(el) {
el.style.paddingLeft = '0px';
el.style.opacity = '0';
}
}
})
ul {
list-style: none;
margin: 0;
padding: 0;
}
ul li {
transition: all 500ms ease-in-out;
}
li.v-enter-active {
transition: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="toggleItems">
Toggle items
</button>
<transition-group
tag="ul"
@before-enter="beforeEnter"
@after-enter="afterEnter"
@before-leave="beforeLeave">
<li v-for="(item, i) in filteredItems" v-bind:key="i" v-bind:data-index="i">
{{ item }}
</li>
</transition-group>
</div>
请注意,如果您使用的是SCSS或SASS,则可以使用JavaScript而不是JavaScript来实现此目的