Vue实现列表项交错动画:初始渲染与导航展开场景
我刚好做过类似的需求,用Vue的<transition-group>完全可以搞定这两种交错动画,给你一步步拆解具体实现方案:
一、列表初始渲染的交错动画
这个场景的核心是利用<transition-group>的appear属性触发初始渲染过渡,再给每个列表项动态设置不同的过渡延迟,实现依次出现的效果。
实现步骤:
- 在
<transition-group>上添加appear属性,启用初始渲染过渡 - 给每个列表项绑定基于索引的
transition-delay样式 - 编写CSS过渡类,定义具体的动画效果
代码示例:
<template> <transition-group name="list-item" appear> <div v-for="(item, index) in listData" :key="item.id" class="list-item" :style="{ transitionDelay: `${index * 150}ms` }" > {{ item.content }} </div> </transition-group> </template> <script setup> import { ref } from 'vue' const listData = ref([ { id: 1, content: '列表项1' }, { id: 2, content: '列表项2' }, { id: 3, content: '列表项3' }, { id: 4, content: '列表项4' } ]) </script> <style scoped> .list-item { margin: 8px 0; padding: 12px; background: #f5f5f5; border-radius: 4px; } /* 过渡类 */ .list-item-enter-active { transition: all 0.5s ease-out; } .list-item-enter-from { opacity: 0; transform: translateY(20px); } /* 初始渲染的appear类和enter类是共用的,上面的样式会自动生效 */ </style>
二、导航展开时的列表项依次出现动画
这个场景需要结合导航的显隐状态,在导航展开时触发<transition-group>的过渡。关键是确保导航容器显示后,列表项的过渡才会触发,同样通过索引设置延迟实现交错效果。
实现步骤:
- 用
v-show或v-if控制导航容器的显隐(推荐v-show,元素保留在DOM中过渡更稳定) - 在导航内部使用
<transition-group>,给每个导航项绑定索引对应的过渡延迟 - 可以给导航容器也加一个整体过渡,让展开更自然
代码示例:
<template> <div class="nav-wrapper"> <button @click="isNavOpen = !isNavOpen" class="hamburger-btn"> 汉堡图标 </button> <!-- 导航容器的过渡 --> <transition name="nav-container"> <div v-show="isNavOpen" class="fullscreen-nav"> <!-- 导航项的交错过渡 --> <transition-group name="nav-item"> <div v-for="(item, index) in navItems" :key="item.id" class="nav-item" :style="{ transitionDelay: `${index * 120}ms` }" > {{ item.label }} </div> </transition-group> </div> </transition> </div> </template> <script setup> import { ref } from 'vue' const isNavOpen = ref(false) const navItems = ref([ { id: 1, label: '首页' }, { id: 2, label: '产品' }, { id: 3, label: '关于我们' }, { id: 4, label: '联系我们' } ]) </script> <style scoped> .hamburger-btn { padding: 8px 16px; font-size: 16px; } .fullscreen-nav { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background: #fff; display: flex; flex-direction: column; justify-content: center; align-items: center; } .nav-item { margin: 16px 0; font-size: 24px; cursor: pointer; } /* 导航容器的过渡 */ .nav-container-enter-active, .nav-container-leave-active { transition: opacity 0.3s ease; } .nav-container-enter-from, .nav-container-leave-to { opacity: 0; } /* 导航项的交错过渡 */ .nav-item-enter-active { transition: all 0.4s ease-out; } .nav-item-enter-from { opacity: 0; transform: translateY(-15px); } /* 关闭时的过渡可以按需添加 */ .nav-item-leave-active { transition: all 0.3s ease-in; } .nav-item-leave-to { opacity: 0; transform: translateY(15px); } </style>
关键细节说明:
- 过渡延迟的时间(比如150ms、120ms)可以按需调整,数值越小动画越紧凑,越大则间隔越明显
- 如果是Vue2,把
<script setup>改成传统的export default写法即可,核心逻辑完全一致 - 要是需要更复杂的动画(比如缩放、旋转),只需要修改CSS里的
transform属性就行
内容的提问来源于stack exchange,提问作者Merc
相关产品推荐
相关产品推荐

