#vue.js #vue-transitions
Вопрос:
В моем приложении нажатие кнопки закрытия модала заставляет его исчезать с анимацией затухания, в то время как прокрутка вниз заставляет его исчезать с анимацией свайпа. Это делается путем изменения модальности <transition name>
в зависимости от события.
То же самое, похоже, не работает с переходной группой. Я делаю что-то не так, или это на самом деле невозможно?
Шаблон:
<transition-group :name="itemTransition">
<div
v-for="item in items"
:key="item.id"
v-hammer:swipe.up="() => onSwipeUp(notification.id)"
>
</div>
</transition-group>
Скрипт:
export default {
data () {
return {
applySwipeTransition: false
}
},
computed: {
itemTransition () {
return this.applySwipeTransition ? 'swipe' : 'fade'
}
},
methods: {
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.applySwipeTransition = false
})
}
}
}
CSS:
.fade-leave-active {
animation: fade-out .75s;
}
.swipe-leave-active {
animation: slide-up .25s;
}
Ответ №1:
Проблема заключается в сроках обновления компонентов. Вы переключаете режим перехода обратно fade
в тот же цикл обновления, что и при закрытии элемента. Таким образом, когда запускается следующее обновление компонента (путем удаления элемента), переход уже переключается обратно fade
. На данный момент вы, возможно, догадались, что все, что нужно сделать, — это переключить переход обратно в следующем обновлении, вызванном удалением элемента:
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.$nextTick(()=>{
this.applySwipeTransition = false
})
})
}
Поскольку нет причин ждать обновления компонента, чтобы закрыть элемент, вы можете немного упростить код:
onSwipeUp (id) {
this.applySwipeTransition = true
this.closeItem(id)
this.$nextTick(() => {
this.applySwipeTransition = false
})
}
Вот ваша рабочая песочница: https://codesandbox.io/s/vue-template-forked-60lkk?file=/src/App.vue
Комментарии:
1. Работает, спасибо! ТАК что не позволяйте мне назначать награду сейчас, придется ждать 4 часа. Один вопрос, однако, в моей песочнице я на самом деле (1) установил переход на свайп, (2) удалил элемент в следующем цикле обновления, (3) вернул переход на затухание в следующем цикле обновления. Почему это не работает? Я понимаю, что нет необходимости делать что-то в таком количестве последовательных циклов обновления, но это все равно должно работать, так как каждый шаг выполняется в хронологическом порядке циклов обновления, не так ли?
2. в вашем коде оба вызова nextTick () (для удаления элемента и переключения перехода) выполняются синхронно, поэтому при регистрации они оба ожидают одного и того же цикла обновления. чтобы быть последовательным, следующая функция nextTick() должна быть вызвана из предыдущего цикла обновления. вот почему вы должны их гнездить. думайте о них как о вызовах асинхронных функций. не уверен, что я хорошо объяснил, должен признать, что их сложно понять
3. Нет, я вроде как понимаю тебя, спасибо за разъяснение
![]()
Ответ №2:
Итак, я поработал с вашим CSS, вручную изменив name
<transition-group
его на » или fade
«или swipe
«, чтобы посмотреть, есть ли проблемы с анимацией CSS.
Вердикт: fade
Работает. swipe
только переходы list-item
со страницы с помощью щелчка и перетаскивания, а не истинного свайпа, если это вас касается (кстати, мой свайп-это свайп macOS двумя пальцами, без щелчка).
До сих пор, не изменяя при этом сайт CodePen, проблема, кажется, с вашей computed
отель, где нет ничего рассказывать name
, чтобы изменить динамически, даже если вы связали ее в computed
собственность — логика itemTransition()
, кажется, всегда по умолчанию fade
, потому что applySwipeTransition
никогда не равно «проведите пальцем», учитывая, что CSS не работает, когда вы вручную изменить name
на swipe
(см. «приговор)».
Чтобы понять, в чем заключалась основная проблема, я поработал с вашим itemTransition()
:
computed: {
itemTransition() {
return this.applySwipeTransition ? "fade" : "swipe";
},
Переключение порядка fade
и swipe
теперь делает swipe
работу. Я надеюсь, что это даст вам некоторое представление об этой проблеме. Возможно, вам потребуется создать пользовательскую директиву или событие Vue для обработки логики свайпа / затухания, если это необходимо.