跳转到内容

Vue.js列表过渡

来自代码酷

Vue.js列表过渡是Vue.js中通过内置组件`<transition-group>`实现的动态效果,用于在列表项被插入、移除或顺序改变时添加平滑的动画或过渡效果。与单个元素的`<transition>`不同,它专为渲染列表设计,能自动处理多个元素的过渡状态,同时保留DOM元素的正确位置。

核心概念[编辑 | 编辑源代码]

与单个元素过渡的区别[编辑 | 编辑源代码]

  • `<transition-group>`特性

* 默认渲染为真实DOM元素(可通过`tag`属性指定标签类型,如`

    `)。 * 每个列表项需有唯一的`key`属性。 * 自动应用CSS过渡类名(如`v-enter`、`v-leave-to`),支持JavaScript钩子。

    工作原理[编辑 | 编辑源代码]

    当列表变化时,Vue会通过以下步骤处理过渡: 1. 识别新增、删除或重新排序的项。 2. 应用进入/离开的过渡类名或钩子函数。 3. 使用FLIP动画技术(First, Last, Invert, Play)优化性能,避免昂贵的DOM操作。

    flowchart LR A[列表变更] --> B[Diff算法比较新旧列表] B --> C{操作类型} C -->|新增| D[应用v-enter类] C -->|删除| E[应用v-leave类] C -->|移动| F[FLIP动画]

    基础用法[编辑 | 编辑源代码]

    CSS过渡示例[编辑 | 编辑源代码]

    以下代码展示了一个动态列表的添加和删除动画:

      
    <template>  
      <div>  
        <button @click="addItem">添加</button>  
        <button @click="removeItem">删除</button>  
        <transition-group name="list" tag="ul">  
          <li v-for="item in items" :key="item.id">  
            {{ item.text }}  
          </li>  
        </transition-group>  
      </div>  
    </template>  
    
    <script>  
    export default {  
      data() {  
        return {  
          items: [  
            { id: 1, text: '项目A' },  
            { id: 2, text: '项目B' }  
          ],  
          nextId: 3  
        }  
      },  
      methods: {  
        addItem() {  
          this.items.push({ id: this.nextId++, text: `项目${String.fromCharCode(64 + this.nextId)}` })  
        },  
        removeItem() {  
          this.items.pop()  
        }  
      }  
    }  
    </script>  
    
    <style>  
    .list-enter-active, .list-leave-active {  
      transition: all 0.5s ease;  
    }  
    .list-enter, .list-leave-to {  
      opacity: 0;  
      transform: translateY(30px);  
    }  
    </style>
    

    效果说明

    • 添加项时:元素从下方淡入(`translateY(30px)`到原始位置)。
    • 删除项时:元素淡出并向下移动。

    JavaScript钩子示例[编辑 | 编辑源代码]

    通过钩子函数实现更复杂的动画逻辑(如使用GSAP库):

      
    <transition-group  
      @enter="onEnter"  
      @leave="onLeave"  
      tag="div"  
    >  
      <!-- 列表项 -->  
    </transition-group>  
    
    <script>  
    import gsap from 'gsap'  
    
    export default {  
      methods: {  
        onEnter(el, done) {  
          gsap.from(el, {  
            opacity: 0,  
            height: 0,  
            onComplete: done  
          })  
        },  
        onLeave(el, done) {  
          gsap.to(el, {  
            opacity: 0,  
            scale: 0,  
            onComplete: done  
          })  
        }  
      }  
    }  
    </script>
    

    高级技巧[编辑 | 编辑源代码]

    列表排序动画[编辑 | 编辑源代码]

    通过`v-move`类实现元素位置变化的动画:

      
    .list-move {  
      transition: transform 0.8s ease;  
    }
    

    关键点

    • 确保CSS中定义`transition`属性。
    • 使用`shuffle`方法随机排序列表触发动画。

    与第三方库集成[编辑 | 编辑源代码]

    结合`animate.css`快速添加预设动画:

      
    <transition-group  
      enter-active-class="animate__animated animate__fadeInUp"  
      leave-active-class="animate__animated animate__fadeOutDown"  
    >  
      <!-- 列表项 -->  
    </transition-group>
    

    实际案例[编辑 | 编辑源代码]

    场景:任务管理应用的待办列表

    • 添加任务:条目从左侧滑入。
    • 完成任务:条目向右淡出。
    • 重新排序:拖拽后其他条目平滑移动。
      
    // 拖拽排序示例(需配合vuedraggable等库)  
    import draggable from 'vuedraggable'  
    
    export default {  
      components: { draggable },  
      data() {  
        return { tasks: ['任务1', '任务2'] }  
      }  
    }
    

    常见问题[编辑 | 编辑源代码]

    • Q:动画不生效?
     * 检查CSS类名是否匹配`name`属性。  
     * 确保`key`唯一且稳定。  
    
    • Q:位置计算错误?
     * 避免在过渡期间修改父元素的布局(如`flex-direction`)。  
    

    数学原理(可选)[编辑 | 编辑源代码]

    FLIP技术的位移计算可表示为: Δ=finalRect.topfirstRect.top 通过反转(Invert)此差值并应用变换,实现高效动画。

    总结[编辑 | 编辑源代码]

    `<transition-group>`是处理列表动画的强大工具,结合CSS或JavaScript可实现从简单到复杂的交互效果。理解其工作原理(如FLIP)和正确使用`key`是掌握该技术的关键。