У меня есть приложение Vue.js, в котором я использую попутный ветер для стилизации. В моем шаблоне внутри гибкого родительского контейнера есть два дочерних элемента: один, который отображается всегда, а другой — условно, с использованием v-show.
Проблема в том, что при визуализации условного элемента ширина первого элемента автоматически регулируется, чтобы разместить пространство, занимаемое вторым элементом внутри гибкого контейнера. Такое поведение ожидаемо, но я бы хотел добавить плавную анимацию к изменению ширины первого элемента (например, анимацию скольжения).
Это упрощенная структура моего шаблона:
<div>
<div
v-for = "(group, groupName, index) in groups"
:key = "groupName"
class = "flex flex-row mb-2 relative"
>
<Transition
mode = "in-out"
enter-from-class = "-translate-x-[150%] opacity-0"
leave-to-class = "-translate-x-[150%] opacity-0"
enter-active-class = "transition duration-200"
leave-active-class = "transition duration-200"
>
<div class = "join join-vertical" v-show = "buttonsVisibility[groupName]">
<!-- Conditionally rendered element -->
</div>
</Transition>
<div class = "shadow-md rounded-lg collapse">
<!-- The element I would like to animate when the other element is shown/hidden -->
</div>
</div>
</div>
Текущее поведение:
Как я могу добиться эффекта анимированного перехода для рассматриваемого элемента? Любые идеи или предложения будут с благодарностью приняты!
Я пытался использовать встроенный компонент «Переход» Vue и различные свойства перехода Tailwind для элемента с динамически изменяющейся шириной, но безрезультатно.
Это жизнеспособное решение для создания анимации для данного элемента flexbox.
<script setup>
import { ref } from 'vue'
const shown = ref(true)
</script>
<template>
<nav class = "flex">
<div class = "first" :class = "shown && 'open'">first block</div>
<div class = "second" @click = "shown = !shown">second block that we do not really care about</div>
</nav>
</template>
<style>
.flex {
display: flex;
height: 50px;
}
.second {
background-color: #e9edc9;
flex: 12 0; /* set to 1 0 if you want to have an even width for the elements */
}
.first {
background-color: #caf0f8;
width: 0; /* this is important for the element to shrink */
display: hidden; /* this replaces the v-show in a better way */
transition: all 250ms ease-in-out;
}
.open {
background-color: #90e0ef;
flex: 1 0; /* where the transition happens */
}
</style>
Вот детская площадка, на которой можно возиться с вещами. Здесь нет ничего слишком сложного, и его можно легко воспроизвести в Tailwind.
Некоторое объяснение того, что происходит выше:
v-show
добавляет к элементу display: none;
, что очень раздражает при переходах из-за ограничений CSS и без хаков, лучше просто пропустить эту часть и использовать display: hidden;
, который даст тот же визуальный результат, но его легко применить переход на@click = "shown = !shown"
, но вы, конечно, можете пойти по пути @mouseenter
или @mouseleave
.flex: 12 0;
— это имитировать желаемую небольшую ширину сбоку, увеличив родительский элемент в 12 раз.<transition>
, я старался сделать все простым и понятным, чтобы вы могли легко перенести его в Tailwind.:class = "shown && 'open'"
означает, что у нас должен быть .open
на элементе, если shown
равен truthy
@loremus в этом случае использование v-show
будет бороться с ним за путь CSS в будущем, так что давайте просто избежим такой боли. В общем, нет, это действительно зависит, но этого вполне может быть достаточно, если вам нужен быстрый способ спрятать вещи. Он довольно быстро достигает своего предела, когда вы хотите добавить немного микровзаимодействия и точно настроить игровой процесс. Честно говоря, я тоже редко использую его, потому что предпочитаю v-if
удалить элемент из DOM. По сути, это то же самое и в документах.
Спасибо, это очень полезно! В своем объяснении вы советуете не использовать v-show в пользу display: Hidden. Является ли использование display: Hidden лучшим способом обработки динамического отображения/скрытия элементов? Есть ли конкретные ниши, в которых проявляет себя v-show?