Я работаю с чистыми JS-хуками для элемента <transition-group>
в VueJS, и я весьма озадачен тем, как на самом деле работает хук enter
. Исходя из документации, я понимаю, что мне придется позвонить done()
, чтобы избежать синхронного вызова событий :
При использовании переходов только для JavaScript обратные вызовы done
требуются для ловушек enter
и leave
. В противном случае крючки будут вызываться синхронно, и переход завершится немедленно.
Однако, даже когда я его использую, кажется, что переходы CSS не происходят при входящем переходе . Единственное решение, которое я нашел, - это использование window.setTimeout
для установки стиля, который, я думаю, является запахом кода. Вот быстрое визуальное сравнение между кодом без тайм-аута и кодом с (тот, у которого тайм-аут является желаемым эффектом):
Неработающий вводный переход (без перехода на левый отступ и непрозрачность):
Желаемый ввод перехода:
В приведенном ниже примере я отображаю список, используя <transition-group>
, и хотел использовать JS-хуки, чтобы я мог создавать разнесенные отступы для отдельных элементов списка. Кажется, работает с тем исключением, что при переходе enter
переходы CSS в свойстве padding не работают.
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
не ждет, пока beforeEnter
не завершится первым? Рабочий фрагмент выглядит следующим образом