Анимация изменения ширины элемента при условном рендеринге родственного элемента с помощью v-show

У меня есть приложение 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 для элемента с динамически изменяющейся шириной, но безрезультатно.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
1
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это жизнеспособное решение для создания анимации для данного элемента 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 раз.
  • Я не использовал никаких переводов, потому что имеет больше смысла иметь такое перераспределение ширины, поскольку мы используем flexbox, кстати вот очень хорошая письменная ссылка если вы ее еще не знаете
  • в этой ситуации нет реальной необходимости в компоненте <transition>, я старался сделать все простым и понятным, чтобы вы могли легко перенести его в Tailwind.
  • :class = "shown && 'open'" означает, что у нас должен быть .open на элементе, если shown равен truthy

Спасибо, это очень полезно! В своем объяснении вы советуете не использовать v-show в пользу display: Hidden. Является ли использование display: Hidden лучшим способом обработки динамического отображения/скрытия элементов? Есть ли конкретные ниши, в которых проявляет себя v-show?

loremus 07.05.2024 13:33

@loremus в этом случае использование v-show будет бороться с ним за путь CSS в будущем, так что давайте просто избежим такой боли. В общем, нет, это действительно зависит, но этого вполне может быть достаточно, если вам нужен быстрый способ спрятать вещи. Он довольно быстро достигает своего предела, когда вы хотите добавить немного микровзаимодействия и точно настроить игровой процесс. Честно говоря, я тоже редко использую его, потому что предпочитаю v-if удалить элемент из DOM. По сути, это то же самое и в документах.

kissu 07.05.2024 13:37

Другие вопросы по теме