You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Vue实现Svelte中Deferred transitions同款过渡效果?

用Vue的Transition/TransitionGroup实现Svelte Deferred同款过渡效果

先看目标效果:
过渡效果演示

这个效果的核心是点击元素展开时,其他元素按顺序延迟位移/收缩,形成连贯的层级过渡。Vue没有原生的deferred transitions,但可以通过「自定义过渡延迟+TransitionGroup的钩子」来实现,以下是完整实现方案:

核心思路

  1. 用CSS变量给每个列表项绑定基于索引的过渡延迟,实现依次触发的效果
  2. 通过动态修改元素高度(或内部内容的显隐)触发过渡
  3. 配合TransitionGroup处理列表项的进入/离开过渡,调整延迟顺序让动画更自然

完整代码实现

组件模板

<template>
  <div class="container">
    <TransitionGroup name="deferred" tag="div" class="list">
      <div
        v-for="(item, index) in items"
        :key="item.id"
        class="list-item"
        :style="{ '--delay': index * 50 + 'ms', '--height': activeId === item.id ? '120px' : '40px' }"
        @click="activeId = activeId === item.id ? null : item.id"
      >
        {{ item.text }}
        <!-- 可添加展开后的自定义内容 -->
        <div v-if="activeId === item.id" class="expanded-content">
          展开的详细内容 {{ item.id }}
        </div>
      </div>
    </TransitionGroup>
  </div>
</template>

脚本逻辑

<script setup>
import { ref } from 'vue'

// 模拟列表数据
const items = ref([
  { id: 1, text: 'Item 1' },
  { id: 2, text: 'Item 2' },
  { id: 3, text: 'Item 3' },
  { id: 4, text: 'Item 4' },
  { id: 5, text: 'Item 5' }
])

// 记录当前展开的项ID
const activeId = ref(null)
</script>

样式部分(关键)

<style scoped>
.container {
  width: 300px;
  margin: 2rem auto;
}

.list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.list-item {
  background: #42b883;
  color: #fff;
  border-radius: 4px;
  padding: 0 1rem;
  height: 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  cursor: pointer;
  /* 核心过渡属性:高度、间距的平滑变化 */
  transition: height 0.3s ease, margin 0.3s ease;
  /* 绑定自定义延迟变量 */
  transition-delay: var(--delay);
  overflow: hidden;
}

.expanded-content {
  padding: 0.5rem 0;
  font-size: 0.875rem;
}

/* TransitionGroup 处理列表项的进入/离开动画 */
.deferred-enter-from,
.deferred-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

.deferred-enter-active,
.deferred-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
  transition-delay: var(--delay);
}

/* 离开时反向延迟,让后面的元素先收缩,和Svelte deferred行为一致 */
.deferred-leave-active {
  transition-delay: calc(250ms - var(--delay));
}
</style>

关键细节说明

  • 延迟计算:用index * 50ms给每个元素设置递增延迟,数值可根据需求调整,越大过渡间隔越明显
  • 反向延迟:离开动画使用calc(250ms - var(--delay)),让索引大的元素先开始收缩,避免动画重叠混乱
  • 内容扩展:如果需要更复杂的展开内容,只需在列表项内部添加动态显隐的元素,配合overflow: hidden即可,过渡逻辑不变

内容的提问来源于stack exchange,提问作者Pavan Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:47:18