VueJS transition css только скользит вниз
Я долго искал решение этой проблемы, но, похоже, не могу найти лучшего решения для этой проблемы. В принципе, у меня есть аккордеон, который, когда пользователь открывает его, должен мягко скользить вниз с приятным переходом.
Я почти уверен, что это возможно только с помощью css. Пожалуйста, поправьте меня, если я ошибаюсь, но css-переходы с точки зрения производительности лучше, чем JS-переходы.
Итак, теперь HTML для Проблемы, с которой я столкнулся:
<transition name="slide-down">
<ul v-if="isDisplayingOpeningHours" class="mt-2 text-sm flex flex-col space-y-2">
<li v-for="i in 10" :key="i"> <!-- just for testing purposes -->
element
</li>
</ul>
</transition>
А css-это:
.slide-down-enter-active, .slide-down-leave-active {
transition: all .5s;
}
.slide-down-enter-to, .slide-down-leave {
overflow: hidden;
max-height: 100%;
}
.slide-down-enter, .slide-down-leave-to {
overflow: hidden;
max-height: 0;
}
Это приводит к не плавному переходу. Скольжение вниз не кажется проблемой,но когда он скользит вверх, он действительно дергается и совсем не бегает!. Если я установлю max-height: 10rem
, это не сделает его лучше. Я надеюсь, что кто-то может отладить помочь мне с этой проблемой и, возможно, рассказать мне больше о переходах vue и переходах js vs css.
Редактировать:
Просто для уточнения самого перехода следует использовать только css. Открытие аккордеона происходит с помощью js, и это прекрасно. Кроме того, было бы неплохо, возможно, увидеть пример использования перехода с собственным компонентом vue-transition.
Правка 2:
Вот codesandbox, который имеет ту же проблему, что и я.
https://codesandbox.io/s/frosty-bash-lmc2f?file=/src/components/HelloWorld.vue
Ответы - VueJS transition css только скользит вниз / Vuejs transition css only slide down

05.10.2020 08:47:51
Еще Одно Обновление!!! Для того чтобы добиться перехода на JS, вы можете ознакомиться с официальным документом. В любом случае, я не собираюсь реализовывать причудливый механизм синхронизации, но в простейшей форме переход JS collapse в react будет выглядеть примерно так, я включил его в существующий codesandbox:
<template>
...
<div>
<button @click="jsOpen = !jsOpen">Open JS list</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:level-cancelled="leaveCancelled"
v-bind:css="false"
>
<ul v-if="jsOpen" class="mt-2 text-sm flex flex-col space-y-2">
<li v-for="i in 10" :key="i">item-{{ i }}</li>
</ul>
</transition>
</div>
</template>
<script>
export default {
...
methods: {
beforeEnter(el) {
el.style.height = 0;
el.style.overflow = "hidden";
},
enter(el, done) {
const increaseHeight = () => {
if (el.clientHeight < el.scrollHeight) {
const height = `${parseInt(el.style.height) + 5}px`;
el.style.height = height;
} else {
clearInterval(this.enterInterval);
done();
}
};
this.enterInterval = setInterval(increaseHeight, 10);
},
afterEnter(el) {},
enterCancelled(el) {
clearInterval(this.enterInterval);
},
beforeLeave(el) {},
leave(el, done) {
const decreaseHeight = () => {
if (el.clientHeight > 0) {
const height = `${parseInt(el.style.height) - 5}px`;
el.style.height = height;
} else {
clearInterval(this.leaveInterval);
done();
}
};
this.leaveInterval = setInterval(decreaseHeight, 10);
},
afterLeave(el) {},
leaveCancelled(el) {
clearInterval(this.leaveInterval);
},
},
};
</script>
Обновление: После понимания требований от OP, я пытался играть с разными вещами, и я наткнулся на эту статью о css-трюках, которая объясняет гораздо более подробно о переходе, из этой статьи другое не-js решение, предложенное будет выглядеть следующим образом, я включил его в существующий stackblitz:
.scale-enter-active,
.scale-leave-active {
transform-origin: top;
transition: transform 0.3s ease-in-out;
}
.scale-enter-to,
.scale-leave-from {
transform: scaleY(1);
}
.scale-enter-from,
.scale-leave-to {
transform: scaleY(0);
}
здесь вместо высоты он масштабируется по оси Y. Он также имеет побочный эффект, заключающийся в том, что сначала он расширяет контейнер до полного размера, а затем обновляет (масштабирует) содержимое.
Вью В3.х
Классы -leave
и -enter
в V3 переименованы в -leave-from
и -enter-from
. Взгляните на этого штакблица.
.slidedown-enter-active,
.slidedown-leave-active {
transition: max-height 0.5s ease-in-out;
}
.slidedown-enter-to,
.slidedown-leave-from {
overflow: hidden;
max-height: 1000px;
}
.slidedown-enter-from,
.slidedown-leave-to {
overflow: hidden;
max-height: 0;
}
Вью версии v2.х
Проблема в том, что вы указываете max-height
на 100%, используйте некоторое значение, которое будет больше вашей ожидаемой максимальной высоты. Обновите свой стиль до:
.slide-down-enter-active,
.slide-down-leave-active {
transition: max-height 0.5s ease-in-out;
}
.slide-down-enter-to,
.slide-down-leave {
overflow: hidden;
max-height: 1000px;
}
.slide-down-enter,
.slide-down-leave-to {
overflow: hidden;
max-height: 0;
}
и это должно сработать. Взгляните на эту демо-версию codesandbox.