我正在为 <transition-group>
使用纯 JS 钩子(Hook)VueJS 上的元素,我很困惑 enter
钩子(Hook)确实有效。根据文档,我知道我必须 call done()
to avoid events being called synchronously :
When using JavaScript-only transitions, the
done
callbacks are required for theenter
andleave
hooks. Otherwise, the hooks will be called synchronously and the transition will finish immediately.
但是,即使我使用它,它似乎也阻止了 CSS 转换在进入转换 时发生。我找到的唯一解决方案是使用 window.setTimeout
设置样式,我认为这是一种代码味道。这是没有超时的代码和有超时的代码之间的快速视觉比较(有超时的是预期的效果):
损坏的输入过渡(左填充和不透明度没有过渡):
所需的输入转换:
在下面的示例中,我使用 <transition-group>
显示一个列表并想使用 JS-hooks 以便我可以在单个列表项上创建交错填充。它似乎可以正常工作,但在 enter
中除外。过渡,填充属性上的 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
中任意超时内的方法,然后它工作:
enter: function(el, done) {
window.setTimeout(() => {
el.style.paddingLeft = `${10 * +el.dataset.index}px`;
el.style.opacity = '1';
done();
}, 100);
},
这就是我有点困惑的地方:enter
Hook 不等待beforeEnter
先完成?工作片段如下
最佳答案
将 @enter
Hook 更改为 @after-enter
应该可以修复它
我不知道为什么 @enter
Hook 对此不起作用,因为查看它应该的文档,但这至少应该摆脱超时没有黑客
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 - VueJS 仅 JS 转换 Hook 需要 setTimeout 才能使 CSS 转换正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55256613/