当同级元素使用 v-show 有条件渲染时,动画元素的宽度变化

问题描述 投票:0回答:1

我有一个 Vue.js 应用程序,我使用 tailwind 进行样式设置。在我的模板中,在 Flex 父容器中,我有两个子元素:一个始终渲染,另一个使用 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>

当前行为:

Current behavior

如何为相关元素实现动画过渡效果?任何见解或建议将不胜感激!

我尝试使用Vue内置的“Transition”组件和Tailwind的不同过渡属性来动态改变宽度的元素,但没有结果。

css vue.js vuejs3
1个回答
0
投票

这是在给定的 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 限制,在没有 hack 的情况下进行转换非常烦人,最好直接跳过该部分并使用
    display: hidden;
    ,这将产生相同的视觉效果结果,但很容易应用过渡
  • 在我的示例中,我使用了
    @click="shown = !shown"
    ,但当然你也完全可以使用
    @mouseenter
    @mouseleave
    方式
  • flex: 12 0;
    是通过将父级放大 12 倍来模拟您想要的侧面小宽度
  • 我没有使用任何翻译,因为自从我们使用 Flexbox 以来,这种宽度重新分区更有意义,顺便说一句这里有一个非常好的书面参考如果你还不知道的话
  • 在这种情况下,并不真正需要
    <transition>
    组件,我试图让事情简单明了,以便您可以轻松地将其转移到Tailwind
© www.soinside.com 2019 - 2024. All rights reserved.