Не работает вложенный transtion Vue v2
Transition "modal-content" не срабатывает, вместо неё применяется transition с именем "modal", подскажите пожалуйста как исправить, чтобы к содержимому внутри modal-container применилась своя анимация?
Vue компонент
<template>
<transition name="modal">
<div class="modal-mask" v-if="isModalVisible" @click.self="closeModal">
<div class="modal-wrapper">
<transition name="modal-content">
<div class="modal-container" v-if="isModalVisible">
<component :is="component"></component>
</div>
</transition>
</div>
</div>
</transition>
</template>
Стили
<style lang="scss" scoped>
.modal-enter {
&-active {
animation: modal .3s ease-out;
}
}
.modal-leave {
&-active {
animation: modal .3s ease-out reverse;
}
}
@keyframes modal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.modal-content-enter {
&-active {
animation: bounce .3s ease-out;
}
}
.modal-content-leave {
&-active {
animation: bounce .3s ease-out reverse;
}
}
@keyframes bounce {
from {
opacity: 0;
transform: translateY(-350px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Ответы (1 шт):
Если вы хотите выполнить анимацию последовательно (предполагаю, что вы пытаетесь этого достичь, используя вложенные <transition>), вам следует использовать Javascript хуки для <transition>:
а именно добавить родительскому <transition> атрибут:
@after-enter="bodyVisible = true"
, который запустит анимацию вложенного <transition> только после выполнения анимации родительского <transition> и для выхода соответственно:
@after-leave="$emit('close')"
, который запустит анимацию выхода для родительского <transition>, после выполнения анимации выхода дочернего <transition>
Привожу ваш пример(с внесенными правками):
new Vue({
el: '#app',
data: () => {
return {
modalVisible: false,
}
}
})
Vue.component('modal', {
data: () => {
return {
bodyVisible: false,
}
},
template: `
<transition
name="modal"
@after-enter="bodyVisible = true"
>
<div class="modal-mask" @click="bodyVisible = false">
<div class="modal-wrapper">
<transition
name="modal-content"
@after-leave="$emit('close')"
>
<div class="modal-container" v-if="bodyVisible"
@click.stop>
Здесь ваш компонент!
<button @click="bodyVisible = false">Закрыть модальное окно</button>
</div>
</transition>
</div>
</div>
</transition>
`
})
.modal-enter-active {
animation: modal .3s ease-out;
}
.modal-leave-active {
animation: modal .3s ease-out reverse;
}
@keyframes modal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.modal-content-enter-active {
animation: modal-content .3s ease-out;
}
.modal-content-leave-active {
animation: modal-content .3s ease-out reverse;
}
@keyframes modal-content {
from {
opacity: 0;
transform: translateY(350px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-mask {
position: fixed;
background: #00000080;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.modal-wrapper {
position: relative;
height: 100%;
width: 100%;
}
.modal-container {
max-width: 30%;
background: white;
padding: 20px;
margin: 0 auto;
margin-top: 5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<modal v-if="modalVisible" @close="modalVisible = false"></modal>
<button @click="modalVisible=!modalVisible">Открыть модальное окно</button>
</div>